source: src/main/java/weka/gui/scripting/FileScriptingPanel.java @ 20

Last change on this file since 20 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 30.7 KB
RevLine 
[4]1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 * FileScriptingPanel.java
19 * Copyright (C) 2009 University of Waikato, Hamilton, New Zealand
20 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc. 
21 */
22
23package weka.gui.scripting;
24
25import weka.core.Utils;
26import weka.gui.ComponentHelper;
27import weka.gui.DocumentPrinting;
28import weka.gui.ExtensionFileFilter;
29import weka.gui.PropertyDialog;
30import weka.gui.scripting.event.ScriptExecutionEvent;
31import weka.gui.scripting.event.ScriptExecutionListener;
32import weka.gui.scripting.event.TitleUpdatedEvent;
33import weka.gui.scripting.event.ScriptExecutionEvent.Type;
34
35import java.awt.BorderLayout;
36import java.awt.Dialog;
37import java.awt.Dimension;
38import java.awt.Font;
39import java.awt.Frame;
40import java.awt.event.ActionEvent;
41import java.awt.event.WindowEvent;
42import java.awt.event.WindowListener;
43import java.io.File;
44import java.util.HashMap;
45
46import javax.swing.AbstractAction;
47import javax.swing.Action;
48import javax.swing.BorderFactory;
49import javax.swing.JDialog;
50import javax.swing.JFileChooser;
51import javax.swing.JFrame;
52import javax.swing.JInternalFrame;
53import javax.swing.JLabel;
54import javax.swing.JMenu;
55import javax.swing.JMenuBar;
56import javax.swing.JMenuItem;
57import javax.swing.JOptionPane;
58import javax.swing.JPanel;
59import javax.swing.JScrollPane;
60import javax.swing.JTextArea;
61import javax.swing.JTextPane;
62import javax.swing.KeyStroke;
63import javax.swing.event.DocumentEvent;
64import javax.swing.event.DocumentListener;
65import javax.swing.event.UndoableEditEvent;
66import javax.swing.event.UndoableEditListener;
67import javax.swing.text.DefaultEditorKit;
68import javax.swing.text.Document;
69import javax.swing.text.JTextComponent;
70import javax.swing.undo.CannotRedoException;
71import javax.swing.undo.CannotUndoException;
72import javax.swing.undo.UndoManager;
73
74/**
75 * Supports loading/saving of files.
76 *
77 * @author  fracpete (fracpete at waikato dot ac dot nz)
78 * @author  Sun Microsystems Inc (see <a href="http://java.sun.com/docs/books/tutorial/uiswing/examples/components/TextComponentDemoProject/src/components/TextComponentDemo.java">TextComponentDemo.java</a>)
79 * @version $Revision: 5144 $
80 */
81public abstract class FileScriptingPanel
82  extends ScriptingPanel
83  implements ScriptExecutionListener {
84
85  /** for serialization. */
86  private static final long serialVersionUID = 1583670545010241816L;
87
88  /**
89   * A slightly extended action class.
90   *
91   * @author  fracpete (fracpete at waikato dot ac dot nz)
92   * @version $Revision: 5144 $
93   */
94  public abstract class BasicAction
95    extends AbstractAction {
96   
97    /** for serialization. */
98    private static final long serialVersionUID = 2821117985661550385L;
99
100    /**
101     * Constructor for setting up an action.
102     *
103     * @param name      the name of the action (to be displayed in menu/button)
104     * @param icon      the icon name (no path required if in weka/gui/images), can be null
105     * @param accel     the accelerator command, e.g., "ctrl N", can be null
106     * @param mnemonic  the mnemonic character
107     */
108    public BasicAction(String name, String icon, String accel, Character mnemonic) {
109      super(name);
110     
111      if ((icon != null) && (icon.length() > 0))
112        putValue(Action.SMALL_ICON, ComponentHelper.getImageIcon(icon));
113      if ((accel != null) && (accel.length() > 0))
114        putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(accel));
115      if (mnemonic != null)
116        putValue(Action.MNEMONIC_KEY, new Integer(mnemonic.charValue()));
117    }
118  }
119 
120  /**
121   * The New action.
122   *
123   * @author  fracpete (fracpete at waikato dot ac dot nz)
124   * @version $Revision: 5144 $
125   */
126  protected class NewAction
127    extends BasicAction {
128   
129    /** for serialization. */
130    private static final long serialVersionUID = -8665722554539726090L;
131
132    /**
133     * Initializes the action.
134     */
135    public NewAction() {
136      super("New", "new.gif", "ctrl N", 'N');
137      setEnabled(true);
138    }
139
140    /**
141     * Fired when action got executed.
142     *
143     * @param e         the event
144     */
145    public void actionPerformed(ActionEvent e) {
146      m_Script.empty();
147      notifyTitleUpdatedListeners(new TitleUpdatedEvent(FileScriptingPanel.this));
148    }
149  }
150
151  /**
152   * The Open action.
153   *
154   * @author  fracpete (fracpete at waikato dot ac dot nz)
155   * @version $Revision: 5144 $
156   */
157  protected class OpenAction
158    extends BasicAction {
159   
160    /** for serialization. */
161    private static final long serialVersionUID = -4496148485267789162L;
162
163    /**
164     * Initializes the action.
165     */
166    public OpenAction() {
167      super("Open...", "open.gif", "ctrl O", 'O');
168      setEnabled(true);
169    }
170
171    /**
172     * Fired when action got executed.
173     *
174     * @param e         the event
175     */
176    public void actionPerformed(ActionEvent e) {
177      boolean   ok;
178      int       retVal;
179     
180      if (!checkModified())
181        return;
182     
183      retVal = m_FileChooser.showOpenDialog(FileScriptingPanel.this);
184      if (retVal != JFileChooser.APPROVE_OPTION)
185        return;
186     
187      ok = m_Script.open(m_FileChooser.getSelectedFile());
188      m_TextCode.setCaretPosition(0);
189      if (!ok)
190        JOptionPane.showMessageDialog(
191            FileScriptingPanel.this, 
192            "Couldn't open file '" + m_FileChooser.getSelectedFile() + "'!");
193     
194      notifyTitleUpdatedListeners(new TitleUpdatedEvent(FileScriptingPanel.this));
195    }
196  }
197
198  /**
199   * The Save action.
200   *
201   * @author  fracpete (fracpete at waikato dot ac dot nz)
202   * @version $Revision: 5144 $
203   */
204  protected class SaveAction
205    extends BasicAction {
206   
207    /** for serialization. */
208    private static final long serialVersionUID = -74651145892063975L;
209   
210    /** whether to bring up the save dialog all the time. */
211    protected boolean m_ShowDialog;
212   
213    /**
214     * Initializes the action.
215     *
216     * @param name              the name of the action
217     * @param showDialog        whether to always show the dialog
218     */
219    public SaveAction(String name, boolean showDialog) {
220      super(name, (showDialog ? "" : "save.gif"), (showDialog ? "ctrl shift S" : "ctrl S"), (showDialog ? 'a' : 'S'));
221      m_ShowDialog = showDialog;
222      setEnabled(true);
223    }
224
225    /**
226     * Fired when action got executed.
227     *
228     * @param e         the event
229     */
230    public void actionPerformed(ActionEvent e) {
231      boolean   ok;
232      int       retVal;
233     
234      if (m_ShowDialog || (m_Script.getFilename() == null)) {
235        retVal = m_FileChooser.showSaveDialog(FileScriptingPanel.this);
236        if (retVal != JFileChooser.APPROVE_OPTION)
237          return;
238        ok = m_Script.saveAs(m_FileChooser.getSelectedFile());
239      }
240      else {
241        ok = m_Script.save();
242      }
243     
244      if (!ok) {
245        if (m_Script.getFilename() != null)
246          JOptionPane.showMessageDialog(
247              FileScriptingPanel.this, 
248              "Failed to save file '" + m_FileChooser.getSelectedFile() + "'!");
249        else
250          JOptionPane.showMessageDialog(
251              FileScriptingPanel.this, 
252              "Failed to save file!");
253      }
254      else {
255        m_SaveAction.setEnabled(false);
256      }
257
258      notifyTitleUpdatedListeners(new TitleUpdatedEvent(FileScriptingPanel.this));
259    }
260  }
261
262  /**
263   * The Print action.
264   *
265   * @author  fracpete (fracpete at waikato dot ac dot nz)
266   * @version $Revision: 5144 $
267   */
268  protected class PrintAction
269    extends BasicAction {
270   
271    /** for serialization. */
272    private static final long serialVersionUID = -6246539539545724632L;
273
274    /**
275     * Initializes the action.
276     */
277    public PrintAction() {
278      super("Print...", "print.gif", "ctrl P", 'P');
279      setEnabled(true);
280    }
281
282    /**
283     * Fired when action got executed.
284     *
285     * @param e         the event
286     */
287    public void actionPerformed(ActionEvent e) {
288      JTextPane         pane;
289      DocumentPrinting  doc;
290     
291      pane = newCodePane();
292      pane.setText(m_TextCode.getText());
293      doc = new DocumentPrinting();
294      doc.print(pane);
295    }
296  }
297
298  /**
299   * The Clear output action.
300   *
301   * @author  fracpete (fracpete at waikato dot ac dot nz)
302   * @version $Revision: 5144 $
303   */
304  protected class ClearOutputAction
305    extends BasicAction {
306   
307    /** for serialization. */
308    private static final long serialVersionUID = 47986890456997211L;
309
310    /**
311     * Initializes the action.
312     */
313    public ClearOutputAction() {
314      super("Clear output", "", "F2", 'C');
315      setEnabled(true);
316    }
317
318    /**
319     * Fired when action got executed.
320     *
321     * @param e         the event
322     */
323    public void actionPerformed(ActionEvent e) {
324      m_TextOutput.setText("");
325    }
326  }
327
328  /**
329   * The Exit action. Sends out a WindowEvent/WINDOW_CLOSED to all
330   * WindowListener objects of a jframe.
331   *
332   * @author  fracpete (fracpete at waikato dot ac dot nz)
333   * @version $Revision: 5144 $
334   */
335  protected class ExitAction
336    extends BasicAction {
337   
338    /** for serialization. */
339    private static final long serialVersionUID = -5884709836238884180L;
340
341    /**
342     * Initializes the action.
343     */
344    public ExitAction() {
345      super("Exit", "", "", 'x');
346      setEnabled(true);
347    }
348
349    /**
350     * Fired when action got executed.
351     *
352     * @param e         the event
353     */
354    public void actionPerformed(ActionEvent e) {
355      Dialog            dialog;
356      Frame             frame;
357      JFrame            jframe;
358      JInternalFrame    jintframe;
359      int               i;
360      WindowListener[]  listeners;
361      WindowEvent       event;
362     
363      if (!checkModified())
364        return;
365     
366      if (PropertyDialog.getParentDialog(FileScriptingPanel.this) != null) {
367        dialog = PropertyDialog.getParentDialog(FileScriptingPanel.this);
368        dialog.setVisible(false);
369      }
370      else if (PropertyDialog.getParentFrame(FileScriptingPanel.this) != null) {
371        jintframe = PropertyDialog.getParentInternalFrame(FileScriptingPanel.this);
372        if (jintframe != null) {
373          jintframe.doDefaultCloseAction();
374        }
375        else {
376          frame = PropertyDialog.getParentFrame(FileScriptingPanel.this);
377          if (frame instanceof JFrame) {
378            jframe = (JFrame) frame;
379            if (jframe.getDefaultCloseOperation() == JFrame.HIDE_ON_CLOSE)
380              jframe.setVisible(false);
381            else if (jframe.getDefaultCloseOperation() == JFrame.DISPOSE_ON_CLOSE)
382              jframe.dispose();
383            else if (jframe.getDefaultCloseOperation() == JFrame.EXIT_ON_CLOSE)
384              System.exit(0);
385
386            // notify listeners
387            listeners = jframe.getWindowListeners();
388            event     = new WindowEvent(jframe, WindowEvent.WINDOW_CLOSED);
389            for (i = 0; i < listeners.length; i++)
390              listeners[i].windowClosed(event);
391          }
392          else {
393            frame.dispose();
394        }
395        }
396      }
397    }
398  }
399
400  /**
401   * The Undo action.
402   *
403   * @author  Sun Microsystems Inc (see <a href="http://java.sun.com/docs/books/tutorial/uiswing/examples/components/TextComponentDemoProject/src/components/TextComponentDemo.java">TextComponentDemo.java</a>)
404   * @version $Revision: 5144 $
405   */
406  protected class UndoAction 
407    extends BasicAction {
408   
409    /** for serialization. */
410    private static final long serialVersionUID = 4298096648424808522L;
411
412    /**
413     * Initializes the action.
414     */
415    public UndoAction() {
416      super("Undo", "undo.gif", "ctrl Z", 'U');
417      setEnabled(false);
418    }
419
420    /**
421     * Fired when action got executed.
422     *
423     * @param e         the event
424     */
425    public void actionPerformed(ActionEvent e) {
426      try {
427        m_Undo.undo();
428      }
429      catch (CannotUndoException ex) {
430        System.out.println("Unable to undo: " + ex);
431        ex.printStackTrace();
432      }
433      updateUndoState();
434      m_RedoAction.updateRedoState();
435    }
436
437    /**
438     * Updates the redo state.
439     */
440    protected void updateUndoState() {
441      if (m_Undo.canUndo()) {
442        setEnabled(true);
443        putValue(Action.NAME, m_Undo.getUndoPresentationName());
444      }
445      else {
446        setEnabled(false);
447        putValue(Action.NAME, "Undo");
448      }
449    }
450  }
451
452  /**
453   * The Redo action.
454   *
455   * @author  Sun Microsystems Inc (see <a href="http://java.sun.com/docs/books/tutorial/uiswing/examples/components/TextComponentDemoProject/src/components/TextComponentDemo.java">TextComponentDemo.java</a>)
456   * @version $Revision: 5144 $
457   */
458  protected class RedoAction
459    extends BasicAction {
460   
461    /** for serialization. */
462    private static final long serialVersionUID = 4533966901523279350L;
463
464    /**
465     * Initializes the action.
466     */
467    public RedoAction() {
468      super("Redo", "redo.gif", "ctrl Y", 'R');
469      setEnabled(false);
470    }
471
472    /**
473     * Fired when action got executed.
474     *
475     * @param e         the event
476     */
477    public void actionPerformed(ActionEvent e) {
478      try {
479        m_Undo.redo();
480      }
481      catch (CannotRedoException ex) {
482        System.out.println("Unable to redo: " + ex);
483        ex.printStackTrace();
484      }
485      updateRedoState();
486      m_UndoAction.updateUndoState();
487    }
488
489    /**
490     * Updates the redo state.
491     */
492    protected void updateRedoState() {
493      if (m_Undo.canRedo()) {
494        setEnabled(true);
495        putValue(Action.NAME, m_Undo.getRedoPresentationName());
496      }
497      else {
498        setEnabled(false);
499        putValue(Action.NAME, "Redo");
500      }
501    }
502  }
503
504  /**
505   * The Commandline args action.
506   *
507   * @author  fracpete (fracpete at waikato dot ac dot nz)
508   * @version $Revision: 5144 $
509   */
510  protected class CommandlineArgsAction
511    extends BasicAction {
512   
513    /** for serialization. */
514    private static final long serialVersionUID = -3183470039010826204L;
515
516    /**
517     * Initializes the action.
518     */
519    public CommandlineArgsAction() {
520      super("Arguments...", "properties.gif", "", 'g');
521      setEnabled(true);
522    }
523
524    /**
525     * Fired when action got executed.
526     *
527     * @param e         the event
528     */
529    public void actionPerformed(ActionEvent e) {
530      String    retVal;
531     
532      retVal = JOptionPane.showInputDialog(
533          FileScriptingPanel.this, 
534          "Please enter the command-line arguments", 
535          Utils.joinOptions(m_Args));
536      if (retVal == null)
537        return;
538     
539      try {
540        m_Args = Utils.splitOptions(retVal);
541      }
542      catch (Exception ex) {
543        m_Args = new String[0];
544        ex.printStackTrace();
545        JOptionPane.showMessageDialog(
546            FileScriptingPanel.this, 
547            "Error setting command-line arguments:\n" + ex, 
548            "Error", 
549            JOptionPane.ERROR_MESSAGE);
550      }
551    }
552  }
553
554  /**
555   * The Start action.
556   *
557   * @author  fracpete (fracpete at waikato dot ac dot nz)
558   * @version $Revision: 5144 $
559   */
560  protected class StartAction
561    extends BasicAction {
562   
563    /** for serialization. */
564    private static final long serialVersionUID = -7936456072955996220L;
565
566    /**
567     * Initializes the action.
568     */
569    public StartAction() {
570      super((m_Script.canExecuteScripts() ? "Start" : "Start (missing classes?)"), "run.gif", "ctrl R", 'S');
571      setEnabled(false);
572    }
573
574    /**
575     * Fired when action got executed.
576     *
577     * @param e         the event
578     */
579    public void actionPerformed(ActionEvent e) {
580      if (!checkModified())
581        return;
582     
583      if (m_Script.getFilename() == null)
584        return;
585     
586      try {
587        m_Script.start(m_Args);
588      }
589      catch (Exception ex) {
590        ex.printStackTrace();
591        JOptionPane.showMessageDialog(
592            FileScriptingPanel.this, 
593            "Error running script:\n" + ex, 
594            "Error", 
595            JOptionPane.ERROR_MESSAGE);
596      }
597    }
598  }
599
600  /**
601   * The Stop action.
602   *
603   * @author  fracpete (fracpete at waikato dot ac dot nz)
604   * @version $Revision: 5144 $
605   */
606  protected class StopAction
607    extends BasicAction {
608   
609    /** for serialization. */
610    private static final long serialVersionUID = 8764023289575718872L;
611
612    /**
613     * Initializes the action.
614     */
615    public StopAction() {
616      super("Stop", "stop.gif", "ctrl shift R", 'o');
617      setEnabled(false);
618    }
619
620    /**
621     * Fired when action got executed.
622     *
623     * @param e         the event
624     */
625    public void actionPerformed(ActionEvent e) {
626      try {
627        m_Script.stop();
628      }
629      catch (Exception ex) {
630        // ignored
631      }
632    }
633  }
634
635  /**
636   * The About action.
637   *
638   * @author  fracpete (fracpete at waikato dot ac dot nz)
639   * @version $Revision: 5144 $
640   */
641  protected class AboutAction
642    extends BasicAction {
643   
644    /** for serialization. */
645    private static final long serialVersionUID = -6420463480569171227L;
646
647    /**
648     * Initializes the action.
649     */
650    public AboutAction() {
651      super("About...", "", "F1", 'A');
652      setEnabled(true);
653    }
654
655    /**
656     * Fired when action got executed.
657     *
658     * @param e         the event
659     */
660    public void actionPerformed(ActionEvent e) {
661      JDialog   dialog;
662     
663      if (PropertyDialog.getParentDialog(FileScriptingPanel.this) != null)
664        dialog = new JDialog(PropertyDialog.getParentDialog(FileScriptingPanel.this), getName());
665      else
666        dialog = new JDialog(PropertyDialog.getParentFrame(FileScriptingPanel.this), getName());
667      dialog.setTitle((String) getValue(Action.NAME));
668      dialog.getContentPane().setLayout(new BorderLayout());
669      dialog.getContentPane().add(getAboutPanel());
670      dialog.pack();
671      dialog.setLocationRelativeTo(FileScriptingPanel.this);
672      dialog.setVisible(true);
673    }
674  }
675 
676  /**
677   * This listener class listens for edits that can be undone.
678   *
679   * @author  Sun Microsystems Inc (see <a href="http://java.sun.com/docs/books/tutorial/uiswing/examples/components/TextComponentDemoProject/src/components/TextComponentDemo.java">TextComponentDemo.java</a>)
680   * @version $Revision: 5144 $
681   */
682  protected class ScriptUndoableEditListener
683    implements UndoableEditListener {
684   
685    /**
686     * Gets called when an undoable event gets triggered.
687     *
688     * @param e         the event
689     */
690    public void undoableEditHappened(UndoableEditEvent e) {
691      //Remember the edit and update the menus.
692      m_Undo.addEdit(e.getEdit());
693      m_UndoAction.updateUndoState();
694      m_RedoAction.updateRedoState();
695    }
696  }
697 
698  /** the directory with the scripting-specific images. */
699  public final static String IMAGES_DIR = "weka/gui/scripting/images";
700 
701  /** for loading/saving file. */
702  protected JFileChooser m_FileChooser;
703 
704  /** the script. */
705  protected Script m_Script;
706
707  /** the script area. */
708  protected JTextArea m_ScriptArea;
709
710  /** the output area. */
711  protected JTextArea m_OutputArea;
712 
713  /** for informing the user. */
714  protected JLabel m_LabelInfo;
715 
716  /** for storing the actions under their name. */
717  protected HashMap<Object, Action> m_Actions;
718
719  /** the new action. */
720  protected NewAction m_NewAction;
721  /** the open action. */
722  protected OpenAction m_OpenAction;
723  /** the Save action. */
724  protected SaveAction m_SaveAction;
725  /** the Save as action. */
726  protected SaveAction m_SaveAsAction;
727  /** the Print action. */
728  protected PrintAction m_PrintAction;
729  /** the clear output action. */
730  protected ClearOutputAction m_ClearOutputAction;
731  /** the exit action. */
732  protected ExitAction m_ExitAction;
733  /** the undo action. */
734  protected UndoAction m_UndoAction;
735  /** the redo action. */
736  protected RedoAction m_RedoAction;
737  /** the cut action. */
738  protected Action m_CutAction;
739  /** the copy action. */
740  protected Action m_CopyAction;
741  /** the paste action. */
742  protected Action m_PasteAction;
743  /** the start action. */
744  protected StartAction m_StartAction;
745  /** the stop action. */
746  protected StopAction m_StopAction;
747  /** the arguments action. */
748  protected CommandlineArgsAction m_ArgsAction;
749  /** the about action. */
750  protected AboutAction m_AboutAction;
751
752  /** the undo manager. */
753  protected UndoManager m_Undo;
754 
755  /** the text pane with the code. */
756  protected JTextPane m_TextCode;
757 
758  /** the text pane for the output. */
759  protected JTextPane m_TextOutput;
760 
761  /** the commandline arguments to use. */
762  protected String[] m_Args;
763 
764  /**
765   * For initializing member variables.
766   */
767  protected void initialize() {
768    super.initialize();
769   
770    m_FileChooser = new JFileChooser();
771    m_FileChooser.setAcceptAllFileFilterUsed(true);
772    m_FileChooser.setMultiSelectionEnabled(false);
773   
774    m_Undo = new UndoManager();
775    m_Args = new String[0];
776  }
777 
778  /**
779   * Sets up the GUI after initializing the members.
780   */
781  protected void initGUI() {
782    JPanel      panel;
783   
784    super.initGUI();
785
786    setLayout(new BorderLayout(0, 5));
787   
788    m_TextCode = newCodePane();
789    m_TextCode.setFont(new Font("monospaced", Font.PLAIN, 12));
790    m_TextCode.getDocument().addUndoableEditListener(new ScriptUndoableEditListener());
791    m_TextCode.getDocument().addDocumentListener(new DocumentListener() {
792      public void changedUpdate(DocumentEvent e) {
793        update();
794      }
795      public void insertUpdate(DocumentEvent e) {
796        update();
797      }
798      public void removeUpdate(DocumentEvent e) {
799        update();
800      }
801      protected void update() {
802        Document doc = m_TextCode.getDocument();
803        m_StartAction.setEnabled((doc.getLength() > 0) && m_Script.canExecuteScripts());
804        m_SaveAction.setEnabled(true);
805        notifyTitleUpdatedListeners(new TitleUpdatedEvent(FileScriptingPanel.this));
806      }
807    });
808    add(new JScrollPane(m_TextCode), BorderLayout.CENTER);
809   
810    panel = new JPanel(new BorderLayout(0, 5));
811    panel.setPreferredSize(new Dimension(50, 200));
812    add(panel, BorderLayout.SOUTH);
813   
814    m_TextOutput = new JTextPane();
815    panel.add(new JScrollPane(m_TextOutput), BorderLayout.CENTER);
816   
817    m_LabelInfo = new JLabel(" ");
818    m_LabelInfo.setBorder(BorderFactory.createLoweredBevelBorder());
819    panel.add(m_LabelInfo, BorderLayout.SOUTH);
820  }
821 
822  /**
823   * Finishes up after initializing members and setting up the GUI.
824   */
825  protected void initFinish() {
826    ExtensionFileFilter[]       filters;
827    int                         i;
828   
829    super.initFinish();
830   
831    m_Script = newScript(m_TextCode.getDocument());
832    m_Script.addScriptFinishedListener(this);
833    filters  = m_Script.getFilters();
834    for (i = filters.length - 1; i >= 0; i--)
835      m_FileChooser.addChoosableFileFilter(filters[i]);
836   
837    m_Actions = createActionTable(m_TextCode);
838
839    // file
840    m_NewAction         = new NewAction();
841    m_OpenAction        = new OpenAction();
842    m_SaveAction        = new SaveAction("Save", false);
843    m_SaveAsAction      = new SaveAction("Save As...", true);
844    m_PrintAction       = new PrintAction();
845    m_ClearOutputAction = new ClearOutputAction();
846    m_ExitAction        = new ExitAction();
847   
848    // edit
849    m_UndoAction        = new UndoAction();
850    m_RedoAction        = new RedoAction();
851    m_CutAction         = updateAction(m_Actions.get(DefaultEditorKit.cutAction), "Cut", "cut.gif", "ctrl X", 'C');
852    m_CopyAction        = updateAction(m_Actions.get(DefaultEditorKit.copyAction), "Copy", "copy.gif", "ctrl C", 'o');
853    m_PasteAction       = updateAction(m_Actions.get(DefaultEditorKit.pasteAction), "Paste", "paste.gif", "ctrl V", 'P');
854   
855    // script
856    m_StartAction       = new StartAction();
857    m_StopAction        = new StopAction();
858    m_ArgsAction        = new CommandlineArgsAction();
859   
860    // help
861    m_AboutAction       = new AboutAction();
862  }
863 
864  /**
865   * Updates the action and returns it.
866   *
867   * @param action      the action to update
868   * @param name        the name to be used as display, can be null
869   * @param icon        the icon to use (if located in weka/gui/images, not path required), can be null
870   * @param accel       the accelerator command to use (e.g., "ctrl N"), can be null
871   * @param mnemonic    the mnemonic character to use, can be null
872   * @return            the updated action
873   */
874  protected Action updateAction(Action action, String name, String icon, String accel, Character mnemonic) {
875    Action      result;
876   
877    // did we already update that action for another component?
878    if (action == null) {
879      result = m_Actions.get(name);
880      return result;
881    }
882   
883    result = action;
884   
885    if ((name != null) && (name.length() > 0))
886      result.putValue(Action.NAME, name);
887    if ((icon != null) && (icon.length() > 0))
888      result.putValue(Action.SMALL_ICON, ComponentHelper.getImageIcon(icon));
889    if ((accel != null) && (accel.length() > 0))
890      result.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(accel));
891    if (mnemonic != null)
892      result.putValue(Action.MNEMONIC_KEY, new Integer(mnemonic.charValue()));
893   
894    return result;
895  }
896 
897  /**
898   * Creates a new JTextPane for the code.
899   *
900   * @return            the text pane
901   */
902  protected abstract JTextPane newCodePane();
903
904  /**
905   * Returns an initialized script object.
906   *
907   * @param doc         the document to use as basis
908   * @return            the initialized script
909   */
910  protected abstract Script newScript(Document doc);
911
912  /**
913   * Gets sent when a script finishes execution.
914   *
915   * @param e           the event
916   */
917  public void scriptFinished(ScriptExecutionEvent e) {
918    if (e.getType() == Type.FINISHED)
919      showInfo("Script execution finished");
920    else if (e.getType() == Type.STOPPED)
921      showInfo("Script execution stopped by user");
922    else if (e.getType() == Type.ERROR)
923      showInfo("Script execution failed" + (e.hasAdditional() ? (": " + e.getAdditional()) : ""));
924   
925    if (e.getType() != Type.STARTED) {
926      m_NewAction.setEnabled(true);
927      m_OpenAction.setEnabled(true);
928      m_SaveAction.setEnabled(true);
929      m_SaveAsAction.setEnabled(true);
930      m_CutAction.setEnabled(true);
931      m_CopyAction.setEnabled(true);
932      m_PasteAction.setEnabled(true);
933      m_StartAction.setEnabled(true);
934      m_StopAction.setEnabled(false);
935    }
936    else {
937      m_NewAction.setEnabled(false);
938      m_OpenAction.setEnabled(false);
939      m_SaveAction.setEnabled(false);
940      m_SaveAsAction.setEnabled(false);
941      m_CutAction.setEnabled(false);
942      m_CopyAction.setEnabled(false);
943      m_PasteAction.setEnabled(false);
944      m_StartAction.setEnabled(false);
945      m_StopAction.setEnabled(true);
946    }
947  }
948 
949  /**
950   * The following two methods allow us to find an
951   * action provided by the editor kit by its name.
952   *
953   * @param comp        the component to get the actions from
954   * @return            the relation
955   */
956  protected HashMap<Object, Action> createActionTable(JTextComponent comp) {
957    HashMap<Object, Action>     result;
958    int                         i;
959    Action[]                    actions;
960    Action                      action;
961   
962    result  = new HashMap<Object, Action>();
963    actions = comp.getActions();
964    for (i = 0; i < actions.length; i++) {
965      action = actions[i];
966      result.put(action.getValue(Action.NAME), action);
967    }
968   
969    return result;
970  }
971 
972  /**
973   * Returns a panel to be displayed with the AboutAction.
974   *
975   * @return            the panel with some information on the scripting panel
976   */
977  protected abstract JPanel getAboutPanel();
978 
979  /**
980   * Returns the title (without the filename).
981   *
982   * @return            the plain title
983   */
984  public abstract String getPlainTitle();
985 
986  /**
987   * Returns the current title for the frame/dialog.
988   *
989   * @return            the title
990   */
991  public String getTitle() {
992    String      result;
993   
994    result = getPlainTitle();
995   
996    if (m_Script.isModified())
997      result = "*" + result;
998   
999    if (m_Script.getFilename() != null)
1000      result += " [" + m_Script.getFilename() + "]";
1001   
1002    return result;
1003  }
1004 
1005  /**
1006   * Returns the text area that is used for displaying output on stdout
1007   * and stderr.
1008   *
1009   * @return            the JTextArea
1010   */
1011  public JTextPane getOutput() {
1012    return m_TextOutput;
1013  }
1014 
1015  /**
1016   * Returns the menu bar to to be displayed in the frame.
1017   *
1018   * @return            the menu bar, null if not applicable
1019   */
1020  public JMenuBar getMenuBar() {
1021    JMenuBar    result;
1022    JMenu       menu;
1023    JMenuItem   menuitem;
1024   
1025    result = new JMenuBar();
1026   
1027    // File
1028    menu = new JMenu("File");
1029    menu.setMnemonic('F');
1030    result.add(menu);
1031   
1032    // File/New
1033    menuitem = new JMenuItem(m_NewAction);
1034    menu.add(menuitem);
1035   
1036    // File/Open
1037    menuitem = new JMenuItem(m_OpenAction);
1038    menu.addSeparator();
1039    menu.add(menuitem);
1040   
1041    // File/Save
1042    menuitem = new JMenuItem(m_SaveAction);
1043    menu.add(menuitem);
1044   
1045    // File/SaveAs
1046    menuitem = new JMenuItem(m_SaveAsAction);
1047    menu.add(menuitem);
1048   
1049    // File/Print
1050    menuitem = new JMenuItem(m_PrintAction);
1051    menu.addSeparator();
1052    menu.add(menuitem);
1053   
1054    // File/Clear output
1055    menuitem = new JMenuItem(m_ClearOutputAction);
1056    menu.addSeparator();
1057    menu.add(menuitem);
1058   
1059    // File/Exit
1060    menuitem = new JMenuItem(m_ExitAction);
1061    menu.addSeparator();
1062    menu.add(menuitem);
1063   
1064    // Edit
1065    menu = new JMenu("Edit");
1066    menu.setMnemonic('E');
1067    result.add(menu);
1068   
1069    // Edit/Undo
1070    menuitem = new JMenuItem(m_UndoAction);
1071    menu.add(menuitem);
1072   
1073    // Edit/Redo
1074    menuitem = new JMenuItem(m_RedoAction);
1075    menu.add(menuitem);
1076   
1077    // Edit/Cut
1078    menuitem = new JMenuItem(m_CutAction);
1079    menu.addSeparator();
1080    menu.add(menuitem);
1081   
1082    // Edit/Copy
1083    menuitem = new JMenuItem(m_CopyAction);
1084    menu.add(menuitem);
1085   
1086    // Edit/Paste
1087    menuitem = new JMenuItem(m_PasteAction);
1088    menu.add(menuitem);
1089   
1090    // Script
1091    menu = new JMenu("Script");
1092    menu.setMnemonic('S');
1093    result.add(menu);
1094   
1095    // Script/Start
1096    menuitem = new JMenuItem(m_StartAction);
1097    menu.add(menuitem);
1098   
1099    // Script/Stop
1100    menuitem = new JMenuItem(m_StopAction);
1101    menu.add(menuitem);
1102   
1103    // Script/Arguments
1104    menuitem = new JMenuItem(m_ArgsAction);
1105    menu.add(menuitem);
1106   
1107    // Help
1108    menu = new JMenu("Help");
1109    menu.setMnemonic('H');
1110    result.add(menu);
1111   
1112    // Help/About
1113    menuitem = new JMenuItem(m_AboutAction);
1114    menu.add(menuitem);
1115   
1116    return result;
1117  }
1118 
1119  /**
1120   * Updates the info shown in the bottom panel.
1121   *
1122   * @param msg         the message to display
1123   */
1124  protected void showInfo(String msg) {
1125    if (msg == null)
1126      msg = " ";
1127    m_LabelInfo.setText(msg);
1128  }
1129 
1130  /**
1131   * Opens the specified file.
1132   *
1133   * @param file        the file to open
1134   */
1135  public void open(File file) {
1136    m_Script.open(file);
1137  }
1138 
1139  /**
1140   * Checks whether the script is modified and asks the user to save it or not.
1141   * If everything is fine and one can ignore the modified state, true is
1142   * returned.
1143   *
1144   * @return            true if one can proceed
1145   */
1146  protected boolean checkModified() {
1147    boolean     result;
1148    int         retVal;
1149   
1150    result = true;
1151   
1152    if (m_Script.isModified()) {
1153      retVal = JOptionPane.showConfirmDialog(
1154          FileScriptingPanel.this, 
1155          "Script not saved - save it now?", 
1156          "Confirm", 
1157          JOptionPane.YES_NO_CANCEL_OPTION);
1158     
1159      if (retVal == JOptionPane.YES_OPTION) {
1160        if (m_Script.getFilename() != null)
1161          m_Script.save();
1162        else
1163          m_SaveAsAction.actionPerformed(null);
1164        result = !m_Script.isModified();
1165      }
1166      else if (retVal == JOptionPane.CANCEL_OPTION) {
1167        result = false;
1168      }
1169    }
1170   
1171    return result;
1172  }
1173}
Note: See TracBrowser for help on using the repository browser.