00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 package com.generalrobotix.ui.view;
00021
00022 import java.awt.BorderLayout;
00023 import java.awt.Component;
00024 import java.awt.Container;
00025 import java.awt.Dimension;
00026 import java.awt.Frame;
00027 import java.text.SimpleDateFormat;
00028 import java.util.ArrayList;
00029 import java.util.Date;
00030 import java.util.HashMap;
00031 import java.util.List;
00032
00033 import javax.swing.BoxLayout;
00034 import javax.swing.JButton;
00035 import javax.swing.JCheckBox;
00036 import javax.swing.JComponent;
00037 import javax.swing.JDialog;
00038 import javax.swing.JLabel;
00039 import javax.swing.JPanel;
00040 import javax.swing.JScrollPane;
00041 import javax.swing.JTabbedPane;
00042 import javax.swing.JTextArea;
00043 import javax.swing.JTextField;
00044 import javax.swing.SwingConstants;
00045 import javax.swing.event.ChangeEvent;
00046 import javax.swing.event.ChangeListener;
00047 import javax.swing.text.JTextComponent;
00048
00049 import org.python.core.PyObject;
00050 import org.python.util.PythonInterpreter;
00051
00052 import com.generalrobotix.ui.util.GrxDebugUtil;
00053 import com.generalrobotix.ui.util.GrxGuiUtil;
00054 import com.generalrobotix.ui.view.GrxJythonPromptView.StyledTextWriter;
00061 @SuppressWarnings("serial")
00062 public class MenuDialog extends JPanel {
00063 private static MenuDialog currentMenuPanel_ = null;
00064 private JDialog dialog_ = null;
00065 private JPanel jPanel_localMenu = null;
00066 private JButton jButton_previous = null;
00067 private JButton jButton_next = null;
00068 private JLabel jLabel = null;
00069 private JCheckBox jCheckBoxSequential = null;
00070 private JTextArea jTextArea = null;
00071
00072 private JCheckBox jCheckBoxContinuous = null;
00073
00074 private List<JTextField> currentFields_ = new ArrayList<JTextField>();
00075
00076
00077 private String[][] menu_;
00078 private int showingStage_ = 0;
00079 private int currentStage_ = 0;
00080 private String command_ = null;
00081 private boolean isWaiting_ = false;
00082 private static final SimpleDateFormat dateFormat_ = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
00083 private static final String QUITBUTTON_TITLE = "Quit";
00084 private HashMap<String, String> exceptMap = new HashMap<String, String>();
00085 private String message_;
00086 private PythonInterpreter interpreter_;
00087 private StyledTextWriter writer_;
00088
00089 public MenuDialog(String[][] src, PythonInterpreter interpreter, String message, StyledTextWriter writer){
00090 menu_ = src;
00091 interpreter_ = interpreter;
00092 message_ = message;
00093 writer_ = writer;
00094 initialize();
00095 }
00096 private void initialize() {
00097 exceptMap.put(QUITBUTTON_TITLE,QUITBUTTON_TITLE);
00098
00099
00100 JPanel localPanel = new JPanel(new BorderLayout());
00101 localPanel.add(new JScrollPane(getLocalMenuPanel()),BorderLayout.CENTER);
00102
00103 JPanel localPanelLower = new JPanel();
00104 localPanelLower.add(getPreviousButton(), null);
00105 jLabel = new JLabel(" 1 / 1 ");
00106 localPanelLower.add(jLabel, null);
00107 localPanelLower.add(getNextButton(), null);
00108 localPanelLower.add(getJCheckBoxSequential(), null);
00109 localPanel.add(localPanelLower,BorderLayout.SOUTH);
00110
00111
00112 JTabbedPane tabbedPane = new JTabbedPane();
00113 tabbedPane.addTab("Local", null, localPanel, null);
00114 tabbedPane.addTab("Global", null, new JScrollPane(getGlobalMenuPanel()), null);
00115 tabbedPane.addTab("History",null, new JScrollPane(getJTextArea()), null);
00116 tabbedPane.addChangeListener(new ChangeListener(){
00117 public void stateChanged(ChangeEvent e){
00118 JTabbedPane jtp = (JTabbedPane)e.getSource();
00119 if (jtp.getSelectedIndex() != 2)
00120 _clearTextComponentRecursive((Container)jtp.getSelectedComponent());
00121 }
00122 });
00123
00124
00125 setLayout(new BorderLayout());
00126 add(tabbedPane,BorderLayout.CENTER);
00127
00128 isWaiting_ = false;
00129 }
00130
00131 void setReadyToNext(){
00132 command_ = null;
00133 if (getJCheckBoxSequential().isSelected()){
00134 if (currentStage_ < menu_.length){
00135 showingStage_ = currentStage_;
00136
00137
00138 showLocalMenu();
00139 } else {
00140 showingStage_ = currentStage_ = menu_.length-1;
00141 showLocalMenu();
00142
00143
00144 }
00145 } else {
00146 showLocalMenu();
00147 }
00148 }
00149
00150
00151 JPanel jpanel_globalMenu = null;
00152 private void showGlobalMenu(){
00153 getGlobalMenuPanel().removeAll();
00154
00155 JPanel jpanel = new JPanel();
00156 JButton buttonQuit = new JButton(QUITBUTTON_TITLE);
00157 buttonQuit.addActionListener(new java.awt.event.ActionListener() {
00158 public void actionPerformed(java.awt.event.ActionEvent e) {
00159 exit();
00160 }
00161 });
00162 jpanel.add(buttonQuit);
00163 jpanel.setAlignmentX( JComponent.CENTER_ALIGNMENT );
00164 getGlobalMenuPanel().add(jpanel);
00165
00166 jpanel = new JPanel();
00167 JButton buttonRetry = new JButton("RETRY(from first)");
00168 buttonRetry.addActionListener(new java.awt.event.ActionListener() {
00169 public void actionPerformed(java.awt.event.ActionEvent e) {
00170 refresh();
00171 _setTabSelected(getLocalMenuPanel());
00172 getLocalMenuPanel().setVisible(true);
00173 }
00174 });
00175 jpanel.add(buttonRetry);
00176 jpanel.setAlignmentX( JComponent.CENTER_ALIGNMENT );
00177 getGlobalMenuPanel().add(jpanel);
00178
00179 for(int i=1; i<menu_[0].length; i=i+2){
00180 String m1 = menu_[0][i-1].trim();
00181 String m2 = menu_[0][i].trim();
00182 if (m2.equals("#label")){
00183 JLabel label = new JLabel(m1, SwingConstants.LEFT);
00184 label.setAlignmentX( JComponent.CENTER_ALIGNMENT );
00185 getGlobalMenuPanel().add(label);
00186 }else if(m2.equals("#monitor")) {
00187 PyObject res = interpreter_.eval(m1);
00188 JLabel label = new JLabel(res.toString(), SwingConstants.LEFT);
00189 label.setAlignmentX( JComponent.CENTER_ALIGNMENT );
00190 getGlobalMenuPanel().add(label);
00191 }else {
00192 addButton(getGlobalMenuPanel(),m1,m2,false);
00193 }
00194 }
00195 }
00196
00197 private JPanel getGlobalMenuPanel() {
00198 if (jpanel_globalMenu == null){
00199 jpanel_globalMenu = new JPanel();
00200 jpanel_globalMenu.setLayout(new BoxLayout(jpanel_globalMenu, BoxLayout.Y_AXIS));
00201 }
00202 return jpanel_globalMenu;
00203 }
00204
00205
00206 private void showLocalMenu(){
00207 getLocalMenuPanel().setVisible(false);
00208 getLocalMenuPanel().removeAll();
00209 getLocalMenuPanel().setVisible(true);
00210 if (showingStage_ >= menu_.length-1){
00211 showingStage_ = menu_.length-1;
00212 getNextButton().setEnabled(false);
00213 } else {
00214 getNextButton().setEnabled(true);
00215 }
00216 if (showingStage_ < 2){
00217 showingStage_ = 1;
00218 getPreviousButton().setEnabled(false);
00219 } else {
00220 getPreviousButton().setEnabled(true);
00221 }
00222
00223 currentFields_.clear();
00224 for(int i=1; i<menu_[showingStage_].length; i=i+2){
00225 String m1 = menu_[showingStage_][i-1].trim();
00226 String m2 = menu_[showingStage_][i].trim();
00227 if (m2.equals("#label")){
00228 JLabel label = new JLabel(m1, SwingConstants.LEFT);
00229 label.setAlignmentX( JComponent.CENTER_ALIGNMENT );
00230 getLocalMenuPanel().add(label);
00231 }else if(m2.equals("#monitor")) {
00232 PyObject res = interpreter_.eval(m1);
00233 JLabel label = new JLabel(res.toString(), SwingConstants.LEFT);
00234 label.setAlignmentX( JComponent.CENTER_ALIGNMENT );
00235 getLocalMenuPanel().add(label);
00236 }else {
00237 addButton(getLocalMenuPanel(),m1,m2,(i<=1));
00238 }
00239 }
00240
00241 jLabel.setText(showingStage_+" / "+(menu_.length-1));
00242
00243 if (command_ != null){
00244 GrxGuiUtil.setEnableRecursive(false,getLocalMenuPanel(),null);
00245 GrxGuiUtil.setEnableRecursive(false,getGlobalMenuPanel(),exceptMap);
00246 } else {
00247 if (getJCheckBoxSequential().isSelected() && showingStage_ != currentStage_)
00248 GrxGuiUtil.setEnableRecursive(false,getLocalMenuPanel(),null);
00249 GrxGuiUtil.setEnableRecursive(true,getGlobalMenuPanel(),null);
00250 }
00251
00252
00253
00254 }
00255
00256 private JPanel getLocalMenuPanel() {
00257 if (jPanel_localMenu == null) {
00258 jPanel_localMenu = new JPanel();
00259 jPanel_localMenu.setLayout(new BoxLayout(jPanel_localMenu, BoxLayout.Y_AXIS));
00260 }
00261 return jPanel_localMenu;
00262 }
00263 private JButton getPreviousButton() {
00264 if (jButton_previous == null) {
00265 jButton_previous = new JButton("Previous");
00266 jButton_previous.setToolTipText("show previous menu");
00267 jButton_previous.addActionListener(new java.awt.event.ActionListener() {
00268 public void actionPerformed(java.awt.event.ActionEvent e) {
00269 showingStage_--;
00270 showLocalMenu();
00271 }
00272 });
00273 }
00274 return jButton_previous;
00275 }
00276 private JButton getNextButton() {
00277 if (jButton_next == null) {
00278 jButton_next = new JButton(" Next ");
00279 jButton_next.setToolTipText("show next menu");
00280 jButton_next.addActionListener(new java.awt.event.ActionListener() {
00281 public void actionPerformed(java.awt.event.ActionEvent e) {
00282 showingStage_++;
00283 showLocalMenu();
00284 }
00285 });
00286 }
00287 return jButton_next;
00288 }
00289 private JCheckBox getJCheckBoxSequential() {
00290 if (jCheckBoxSequential == null) {
00291 jCheckBoxSequential = new JCheckBox("Sequential",true);
00292 jCheckBoxSequential.setToolTipText("enable only current button");
00293 jCheckBoxSequential.addActionListener(new java.awt.event.ActionListener() {
00294 public void actionPerformed(java.awt.event.ActionEvent e) {
00295 if (jCheckBoxSequential.isSelected()){
00296 showingStage_ = currentStage_;
00297 showLocalMenu();
00298 getJCheckBoxContinuous().setEnabled(true);
00299 } else {
00300 if (isIdle()){
00301 GrxGuiUtil.setEnableRecursive(true,getLocalMenuPanel(),null);
00302 }
00303 getJCheckBoxContinuous().setEnabled(false);
00304 }
00305 }
00306 });
00307 }
00308 return jCheckBoxSequential;
00309 }
00310 private JCheckBox getJCheckBoxContinuous() {
00311 if (jCheckBoxContinuous == null) {
00312 jCheckBoxContinuous = new JCheckBox("continuous",false);
00313 jCheckBoxContinuous.setToolTipText("excecute continuously");
00314 }
00315 return jCheckBoxContinuous;
00316 }
00317 private JButton addButton(JPanel pnl,final String name,final String com,final boolean goNext){
00318 JPanel jpanel = new JPanel();
00319 JButton button = new JButton(name);
00320 jpanel.add(button);
00321
00322 final String[] str = parseCommand(com);
00323 int len = 1;
00324 if (str!=null) len = str.length;
00325 final JTextField[] fields = new JTextField[len];
00326 if (str!= null && len > 0){
00327 for (int i=0;i<len;i++){
00328 fields[i] = new JTextField();
00329 fields[i].setPreferredSize(new Dimension(60,20));
00330 jpanel.add(fields[i]);
00331
00332 }
00333 }
00334
00335 if (goNext){
00336
00337 if (com.indexOf("#continuous")!=-1){
00338 getJCheckBoxContinuous().setSelected(true);
00339 jpanel.add(getJCheckBoxContinuous());
00340 } else {
00341 getJCheckBoxContinuous().setSelected(false);
00342 }
00343 }
00344
00345 button.addActionListener(new java.awt.event.ActionListener() {
00346 public void actionPerformed(java.awt.event.ActionEvent e) {
00347 if (command_ == null){
00348 String rcom = com;
00349
00350 try{
00351 if (com.indexOf("#appendlog") < 0){
00352
00353 }
00354 if (str!=null && str.length > 0){
00355 for (int i=0;i<str.length;i++){
00356 char c = str[i].charAt(1);
00357 String s = fields[i].getText();
00358 if (c == 'd' || c == 'D'){
00359 Double.parseDouble(s);
00360 } else if (c == 'i' || c == 'I'){
00361 Integer.parseInt(s);
00362 } else if (c == 't' || c == 'T'){
00363 s = "\'"+s+"\'";
00364 }
00365 rcom = rcom.replaceFirst(str[i],s);
00366 }
00367
00368 }
00369 command_ = rcom;
00370 String comLog = dateFormat_.format(new Date())+" : "+name+" : "+command_+"\n";
00371 getJTextArea().append(comLog);
00372
00373 if (getJCheckBoxSequential().isSelected() && goNext ){
00374
00375 currentStage_++;
00376 } else {
00377
00378 }
00379 GrxGuiUtil.setEnableRecursive(false,getLocalMenuPanel(),null);
00380 GrxGuiUtil.setEnableRecursive(false,getGlobalMenuPanel(),exceptMap);
00381
00382 interpreter_.exec(command_);
00383 setReadyToNext();
00384
00385 } catch (NumberFormatException e1){
00386 GrxDebugUtil.printErr("MenuDialog: parse error");
00387 writer_.write("MenuDialog: parse error "+e1+System.getProperty("line.separator"));
00388 }
00389 }
00390 }
00391 });
00392 jpanel.setAlignmentX( JComponent.CENTER_ALIGNMENT );
00393 pnl.add(jpanel);
00394 return button;
00395 }
00396
00397 private String[] parseCommand(String com){
00398 StringBuffer sb = new StringBuffer();
00399 int idx = -1;
00400 while((idx = com.indexOf("#",idx+1)) != -1){
00401 char c = com.charAt(idx+1);
00402 if (c =='d' || c =='D'||
00403 c =='i' || c =='I' ||
00404 c =='t' || c =='T' ) {
00405 sb.append("#"+c+" ");
00406 }
00407 }
00408 if (sb.toString().trim().equals(""))
00409 return null;
00410 return sb.toString().split(" ");
00411 }
00412
00413
00414 private JTextArea getJTextArea() {
00415 if (jTextArea == null) {
00416 jTextArea = new JTextArea();
00417 jTextArea.setEditable(false);
00418 }
00419 return jTextArea;
00420 }
00421
00422 private static void _clearTextComponentRecursive(Container container){
00423 Component[] components = container.getComponents();
00424 for (int i=0;i<components.length;i++){
00425 Component c = components[i];
00426 if (c instanceof JTextComponent){
00427 ((JTextComponent)c).setText("");
00428 } else if (c instanceof Container) {
00429 _clearTextComponentRecursive((Container)c);
00430 }
00431 }
00432 }
00433 private static void _setTabSelected(Component c){
00434 Component parent = c.getParent();
00435 if (parent == null)
00436 return;
00437 if (parent instanceof JTabbedPane){
00438 JTabbedPane tabpane = (JTabbedPane)parent;
00439 tabpane.setSelectedComponent(c);
00440 return;
00441 }
00442 _setTabSelected(parent);
00443 }
00444
00445
00446 public void showDialog(Frame owner, String title, boolean modal){
00447 if (dialog_ == null ){
00448 dialog_ = new JDialog(owner,title,modal);
00449
00450 dialog_.setSize(new Dimension(400, 400));
00451 dialog_.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
00452 dialog_.setContentPane(this);
00453 }
00454
00455 refresh();
00456
00457 }
00458 private void refresh(){
00459 dialog_.setVisible(true);
00460 currentStage_ = showingStage_ = 1;
00461 isWaiting_ = true;
00462 currentMenuPanel_ = this;
00463 showGlobalMenu();
00464 showLocalMenu();
00465 }
00466 public boolean isWaiting(){
00467 return isWaiting_;
00468 }
00469 public boolean isIdle(){
00470 return (command_ == null);
00471 }
00472 public String getCommand(){
00473 return command_;
00474 }
00475 public static MenuDialog getCurrentMenuDialog(){
00476 return currentMenuPanel_;
00477 }
00478 public String getCurrentMenuItem(){
00479 if (getJCheckBoxSequential().isSelected()){
00480 if (command_ != null)
00481 return command_;
00482 return menu_[Math.min(currentStage_,menu_.length-1)][0];
00483 }
00484 return menu_[Math.min(showingStage_,menu_.length-1)][0];
00485 }
00486 public boolean isAllDone(){
00487 if (currentStage_ >= menu_.length-1)
00488 return true;
00489 return false;
00490 }
00491 public void showMessage(String msg){
00492 int idx = -1;
00493 if (currentFields_ != null && msg != null){
00494
00495 while((idx = msg.indexOf("$",idx+1)) != -1){
00496 int idx2 = msg.indexOf("=",idx+1);
00497 String s = msg.substring(idx+1,idx2);
00498 int idx3 = msg.indexOf(" ",idx2+1);
00499 if (idx3 < 0)
00500 idx3 = msg.length();
00501 String val = msg.substring(idx2+1,idx3);
00502 try {
00503 int i = Integer.parseInt(s.trim());
00504 ((JTextField)(currentFields_.get(i))).setText(val);
00505
00506 } catch (Exception e){
00507 GrxDebugUtil.printErr("MenuDialog.setMessage():",e);
00508 }
00509 idx = idx2;
00510 }
00511 }
00512 }
00513 public void setMessage(String message){
00514 message_ = message;
00515 }
00516
00517 public void setContinuous(boolean b){
00518 getJCheckBoxContinuous().setSelected(b);
00519 }
00520 public void exit(){
00521 dialog_.setVisible(false);
00522 isWaiting_ = false;
00523 currentMenuPanel_ = null;
00524 }
00525 }