-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathMainFrame.java
More file actions
10205 lines (9071 loc) · 454 KB
/
MainFrame.java
File metadata and controls
10205 lines (9071 loc) · 454 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*BEGIN_COPYRIGHT_BLOCK
*
* Copyright (c) 2001-2015, JavaPLT group at Rice University (drjava@rice.edu)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the names of DrJava, DrScala, the JavaPLT group, Rice University, nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software is Open Source Initiative approved Open Source Software.
* Open Source Initative Approved is a trademark of the Open Source Initiative.
*
* This file is part of DrScala. Download the current version of this project
* from http://www.drscala.org/.
*
* END_COPYRIGHT_BLOCK*/
package edu.rice.cs.drjava.ui;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.text.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.print.*;
import java.awt.dnd.*;
import java.beans.*;
import java.io.*;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.net.URL;
import java.net.MalformedURLException;
import java.awt.datatransfer.*;
import java.lang.ref.WeakReference;
import edu.rice.cs.drjava.DrScala;
import edu.rice.cs.drjava.DrScalaRoot;
//import edu.rice.cs.drjava.RemoteControlClient;
//import edu.rice.cs.drjava.RemoteControlServer;
import edu.rice.cs.drjava.platform.*;
import edu.rice.cs.drjava.config.FileConfiguration;
import edu.rice.cs.drjava.config.*;
import edu.rice.cs.drjava.model.*;
import edu.rice.cs.drjava.model.compiler.CompilerListener;
import edu.rice.cs.drjava.model.compiler.CompilerModel;
import edu.rice.cs.drjava.model.definitions.ClassNameNotFoundException;
import edu.rice.cs.drjava.model.definitions.DefinitionsDocument;
import edu.rice.cs.drjava.model.definitions.DocumentUIListener;
import edu.rice.cs.drjava.model.definitions.InvalidPackageException;
import edu.rice.cs.drjava.model.definitions.NoSuchDocumentException;
import edu.rice.cs.drjava.model.repl.*;
import edu.rice.cs.drjava.model.repl.newjvm.MainJVM;
import edu.rice.cs.drjava.model.javadoc.ScaladocModel;
import edu.rice.cs.drjava.ui.config.ConfigFrame;
import edu.rice.cs.drjava.ui.predictive.PredictiveInputFrame;
import edu.rice.cs.drjava.ui.predictive.PredictiveInputModel;
import edu.rice.cs.drjava.ui.avail.*;
import edu.rice.cs.drjava.ui.avail.DefaultGUIAvailabilityNotifier;
import edu.rice.cs.drjava.ui.ClipboardHistoryFrame;
import edu.rice.cs.drjava.ui.RegionsTreePanel;
import edu.rice.cs.drjava.project.*;
import edu.rice.cs.plt.concurrent.JVMBuilder;
import edu.rice.cs.plt.io.IOUtil;
import edu.rice.cs.plt.iter.IterUtil;
import edu.rice.cs.plt.lambda.DelayedThunk;
import edu.rice.cs.plt.lambda.*;
import edu.rice.cs.plt.reflect.JavaVersion;
import edu.rice.cs.plt.tuple.Pair;
import edu.rice.cs.util.classloader.ClassFileError;
import edu.rice.cs.util.docnavigation.*;
import edu.rice.cs.drjava.model.FileMovedException;
import edu.rice.cs.util.FileOpenSelector;
import edu.rice.cs.util.FileOps;
import edu.rice.cs.util.Log;
import edu.rice.cs.util.OperationCanceledException;
import edu.rice.cs.util.StringOps;
import edu.rice.cs.util.swing.Utilities;
import edu.rice.cs.util.swing.*;
import edu.rice.cs.util.swing.ProcessingDialog;
import edu.rice.cs.util.text.ConsoleDocument;
import edu.rice.cs.util.text.SwingDocument;
import edu.rice.cs.util.UnexpectedException;
import edu.rice.cs.util.XMLConfig;
import static edu.rice.cs.drjava.config.OptionConstants.KEY_NEW_CLASS_FILE;
import static edu.rice.cs.drjava.ui.RecentFileManager.*;
import static edu.rice.cs.drjava.ui.predictive.PredictiveInputModel.*;
import static edu.rice.cs.util.XMLConfig.XMLConfigException;
import static edu.rice.cs.plt.object.ObjectUtil.hash;
import static edu.rice.cs.drjava.ui.MainFrameStatics.*;
/** DrScala's main window. */
public class MainFrame extends SwingFrame implements ClipboardOwner, DropTargetListener {
private static final Log _log = DrScala._log;
private static final int INTERACTIONS_TAB = 0;
private static final int CONSOLE_TAB = 1;
private static final String ICON_PATH = "/edu/rice/cs/drjava/ui/icons/";
// ------ Field Declarations -------
/** The model which controls all logic in DrScala. */
private volatile AbstractGlobalModel _model;
/** The main model listener attached by the main frame to the global model */
private volatile ModelListener _mainListener;
/** Maps an OpenDefDoc to its JScrollPane. Why doesn't OpenDefDoc contain a defScrollPane field? */
private volatile HashMap<OpenDefinitionsDocument, JScrollPane> _defScrollPanes;
/** The currently displayed DefinitionsPane. */
private volatile DefinitionsPane _currentDefPane;
/** The currently displayed DefinitionsDocument. */
private volatile DefinitionsDocument _currentDefDoc;
/** The filename currently being displayed. */
private volatile String _fileTitle = "";
// Tabbed panel fields
public final LinkedList<TabbedPanel> _tabs = new LinkedList<TabbedPanel>();
public final JTabbedPane _tabbedPane = new JTabbedPane();
private final LinkedList<Pair<FindResultsPanel, Map<MovingDocumentRegion, HighlightManager.HighlightInfo>>>
_findResults = new LinkedList<Pair<FindResultsPanel, Map<MovingDocumentRegion, HighlightManager.HighlightInfo>>>();
// The following three fields are conceptually final, but were downgraded to volatile to allow initialization in
// the event thread;
private volatile DetachedFrame _tabbedPanesFrame;
public volatile Component _lastFocusOwner;
private volatile CompilerErrorPanel _compilerErrorPanel;
private volatile JUnitPanel _junitPanel;
private volatile ScaladocErrorPanel _scaladocErrorPanel;
private volatile FindReplacePanel _findReplace;
private volatile BookmarksPanel _bookmarksPanel;
private volatile InteractionsPane _consolePane;
private volatile JScrollPane _consoleScroll; // redirects focus to embedded _consolePane
private volatile ConsoleController _consoleController;
private volatile InteractionsPane _interactionsPane;
private volatile JPanel _interactionsContainer; // redirects focus to embedded _interactionsPane
private volatile InteractionsController _interactionsController;
private volatile InteractionsScriptController _interactionsScriptController;
private volatile InteractionsScriptPane _interactionsScriptPane;
/** Panel to hold both InteractionsPane and its sync message. */
// Status bar fields
private final JPanel _statusBar = new JPanel(new BorderLayout()); //( layout );
private final JLabel _statusField = new JLabel();
private final JLabel _statusReport = new JLabel(); //("This is the text for the center message");
private final JLabel _currLocationField = new JLabel();
private final PositionListener _posListener = new PositionListener();
// Split panes for layout
private volatile JSplitPane _docSplitPane;
/* Debugger deactivated in DrScala */
// private volatile JSplitPane _debugSplitPane;
JSplitPane _mainSplit;
// private Container _docCollectionWidget;
private volatile JButton _compileButton;
private volatile JButton _closeButton;
private volatile JButton _undoButton;
private volatile JButton _redoButton;
private volatile JButton _runButton;
private volatile JButton _junitButton;
private volatile JButton _errorsButton;
private final JToolBar _toolBar = new JToolBar();
private final JFileChooser _interactionsHistoryChooser = new JFileChooser();
// Menu fields
private final JMenuBar _menuBar = new MenuBar(this);
private volatile JMenu _fileMenu;
private volatile JMenu _editMenu;
private volatile JMenu _toolsMenu;
private volatile JMenu _projectMenu;
private volatile JMenu _helpMenu;
/* Debugger deactivated in DrScala */
// private volatile JMenu _debugMenu;
// private volatile JMenuItem _debuggerEnabledMenuItem;
// Popup menus
private JPopupMenu _interactionsPanePopupMenu;
private JPopupMenu _consolePanePopupMenu;
// Cached frames and dialogs
private volatile ConfigFrame _configFrame;
private final HelpFrame _helpFrame = new HelpFrame();
private final QuickStartFrame _quickStartFrame = new QuickStartFrame();
private volatile AboutDialog _aboutDialog;
private volatile RecentDocFrame _recentDocFrame; /** Holds/shows the history of documents for ctrl-tab. */
// private ProjectPropertiesFrame _projectPropertiesFrame;
/** Keeps track of the recent files list in the File menu. */
private volatile RecentFileManager _recentFileManager;
/** Keeps track of the recent projects list in the Project menu */
private volatile RecentFileManager _recentProjectManager;
private volatile File _currentProjFile;
/** Timer to step into another line of code. The delay for each step is recorded in milliseconds. */
private volatile Timer _automaticTraceTimer;
/** The current highlight displaying the current location, used for FindAll and the of the debugger's thread,
* if there is one. If there is none, this is null.
*/
private volatile HighlightManager.HighlightInfo _currentLocationHighlight = null;
/** Table to map bookmarks to their corresponding highlight objects. */
private final IdentityHashMap<OrderedDocumentRegion, HighlightManager.HighlightInfo> _documentBookmarkHighlights =
new IdentityHashMap<OrderedDocumentRegion, HighlightManager.HighlightInfo>();
/** The timestamp for the last change to any document. */
private volatile long _lastChangeTime = 0;
/** Whether to display a prompt message before quitting. */
private volatile boolean _promptBeforeQuit;
/** Listener for Interactions JVM */
volatile private ConfigOptionListeners.SlaveJVMXMXListener _slaveJvmXmxListener;
/** Listener for Main JVM */
volatile private ConfigOptionListeners.MasterJVMXMXListener _masterJvmXmxListener;
/** GUI component availability notifier. */
final DefaultGUIAvailabilityNotifier _guiNotifier = DefaultGUIAvailabilityNotifier.ONLY;
/** Window adapter for "pseudo-modal" dialogs, i.e. non-modal dialogs that insist on keeping the focus. */
protected volatile java.util.HashMap<Window,WindowAdapter> _modalWindowAdapters
= new java.util.HashMap<Window,WindowAdapter>();
/** The owner of the modal window listener has already been taken by another window. */
protected volatile Window _modalWindowAdapterOwner = null;
/** For opening files. We have a persistent dialog to keep track of the last directory from which we opened. */
private volatile JFileChooser _openChooser;
/** For opening project files. */
private volatile JFileChooser _openProjectChooser;
/** For saving files. We have a persistent dialog to keep track of the last directory from which we saved. */
private volatile JFileChooser _saveChooser;
/** Filter for drscala project files (.drscala) */
private final javax.swing.filechooser.FileFilter _projectFilter = new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
return f.isDirectory() || f.getPath().endsWith(PROJECT_FILE_EXTENSION);
}
public String getDescription() {
return "DrScala Project Files (*" + PROJECT_FILE_EXTENSION + ")";
}
};
/** Filter for text files (.txt) */
private final javax.swing.filechooser.FileFilter _txtFileFilter = new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) { return f.isDirectory() || f.getPath().endsWith(TEXT_FILE_EXTENSION); }
public String getDescription() { return "Text Files (*"+TEXT_FILE_EXTENSION+")"; }
};
/** Filter for any files (*.*) */
private final javax.swing.filechooser.FileFilter _anyFileFilter = new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) { return true; }
public String getDescription() { return "All files (*.*)"; }
};
/** Thread pool for executing asynchronous tasks. */
private volatile ExecutorService _threadPool = Executors.newCachedThreadPool();
// ------ End Field Declarations ------
/** @return the source file filter as directed by the currently selected compiler. */
private javax.swing.filechooser.FileFilter getSourceFileFilter() {
CompilerModel cm = _model.getCompilerModel();
if (cm == null) return new SmartSourceFilter();
else return cm.getActiveCompiler().getFileFilter();
}
/** Return the suggested file extension that will be appended to a file without extension.
* @return the suggested file extension */
private String getSuggestedFileExtension() {
CompilerModel cm = _model.getCompilerModel();
if (cm == null) return DrScalaFileUtils.getSuggestedFileExtension();
else return cm.getActiveCompiler().getSuggestedFileExtension();
}
/** Returns the files to open to the model (command pattern). */
private final FileOpenSelector _openSelector = new FileOpenSelector() {
public File[] getFiles() throws OperationCanceledException {
_openChooser.resetChoosableFileFilters();
_openChooser.setFileFilter(getSourceFileFilter());
return getOpenFiles(_openChooser);
}
};
/** Returns the files to open to the model (command pattern). */
private final FileOpenSelector _openFileOrProjectSelector = new FileOpenSelector() {
public File[] getFiles() throws OperationCanceledException {
_openChooser.resetChoosableFileFilters();
_openChooser.addChoosableFileFilter(_projectFilter);
_openChooser.setFileFilter(getSourceFileFilter());
return getOpenFiles(_openChooser);
}
};
/** Returns the project file to open. */
private final FileOpenSelector _openProjectSelector = new FileOpenSelector() {
public File[] getFiles() throws OperationCanceledException { return getOpenFiles(_openProjectChooser); }
};
/** Returns the files to open. */
private final FileOpenSelector _openAnyFileSelector = new FileOpenSelector() {
public File[] getFiles() throws OperationCanceledException {
_openChooser.resetChoosableFileFilters();
_openChooser.setFileFilter(_anyFileFilter);
return getOpenFiles(_openChooser);
}
};
/** @return possibly renamed file, if it used an old LL extension and the user wanted it. */
private File proposeBetterFileName(File f) { return f; }
/** Returns the file to save to the model (command pattern). */
private final FileSaveSelector _saveSelector = new FileSaveSelector() {
public File getFile() throws OperationCanceledException {
return proposeBetterFileName(getSaveFile(_saveChooser));
}
public boolean warnFileOpen(File f) { return _warnFileOpen(f); }
public boolean verifyOverwrite(File f) { return MainFrameStatics.verifyOverwrite(MainFrame.this, f); }
public boolean shouldSaveAfterFileMoved(OpenDefinitionsDocument doc, File oldFile) {
_model.setActiveDocument(doc);
String text = "File " + oldFile.getAbsolutePath() +
"\ncould not be found on disk! It was probably moved\nor deleted. Would you like to save it in a new file?";
int rc = JOptionPane.showConfirmDialog(MainFrame.this, text, "File Moved or Deleted", JOptionPane.YES_NO_OPTION);
return (rc == JOptionPane.YES_OPTION);
}
public boolean shouldUpdateDocumentState() { return true; }
};
/** Returns the file to save to the model (command pattern). */
private final FileSaveSelector _saveAsSelector = new FileSaveSelector() {
public File getFile() throws OperationCanceledException {
return proposeBetterFileName(getSaveFile(_saveChooser));
}
public boolean warnFileOpen(File f) { return _warnFileOpen(f); }
public boolean verifyOverwrite(File f) { return MainFrameStatics.verifyOverwrite(MainFrame.this, f); }
public boolean shouldSaveAfterFileMoved(OpenDefinitionsDocument doc, File oldFile) { return true; }
public boolean shouldUpdateDocumentState() { return true; }
};
/** Returns the file to save to the model (command pattern) without updating the document state. */
private final FileSaveSelector _saveCopySelector = new FileSaveSelector() {
public File getFile() throws OperationCanceledException {
return proposeBetterFileName(getSaveFile(_saveChooser));
}
public boolean warnFileOpen(File f) { return _warnFileOpen(f); }
public boolean verifyOverwrite(File f) { return MainFrameStatics.verifyOverwrite(MainFrame.this, f); }
public boolean shouldSaveAfterFileMoved(OpenDefinitionsDocument doc, File oldFile) { return true; }
public boolean shouldUpdateDocumentState() { return false; }
};
/** Provides the view's contribution to the Scaladoc interaction. */
private final ScaladocDialog _scaladocSelector = new ScaladocDialog(this);
/** Provides a chooser to open a directory */
private volatile DirectoryChooser _folderChooser;
private final JCheckBox _openRecursiveCheckBox = new JCheckBox("Open folders recursively");
private final Action _moveToAuxiliaryAction = new AbstractAction("Include With Project") {
{ /* initalization block */
String msg =
"<html>Open this document each time this project is opened.<br>"+
"This file would then be compiled and tested with the<br>"+
"rest of the project.</html>";
putValue(Action.LONG_DESCRIPTION, msg);
}
public void actionPerformed(ActionEvent ae) { _moveToAuxiliary(); }
};
private final Action _removeAuxiliaryAction = new AbstractAction("Do Not Include With Project") {
{ putValue(Action.LONG_DESCRIPTION, "Do not open this document next time this project is opened."); } // init
public void actionPerformed(ActionEvent ae) { _removeAuxiliary(); }
};
private final Action _moveAllToAuxiliaryAction = new AbstractAction("Include All With Project") {
{ /* initalization block */
String msg =
"<html>Open these documents each time this project is opened.<br>"+
"These files would then be compiled and tested with the<br>"+
"rest of the project.</html>";
putValue(Action.LONG_DESCRIPTION, msg);
}
public void actionPerformed(ActionEvent ae) { _moveAllToAuxiliary(); }
};
private final Action _removeAllAuxiliaryAction = new AbstractAction("Do Not Include Any With Project") {
{ putValue(Action.LONG_DESCRIPTION, "Do not open these documents next time this project is opened."); } // init
public void actionPerformed(ActionEvent ae) { _removeAllAuxiliary(); }
};
/** Creates a new blank document and select it in the definitions pane. */
private final Action _newAction = new AbstractAction("New") {
public void actionPerformed(ActionEvent ae) { _new(); }
};
//newclass addition
/** Creates a new Java class file. */
private final Action _newClassAction = new AbstractAction("New Java Class...") {
public void actionPerformed(ActionEvent ae) { _newJavaClass(); }
};
public void _newJavaClass() {
NewJavaClassDialog njc = new NewJavaClassDialog(this);
njc.setVisible(true);
}
private final Action _newProjectAction = new AbstractAction("New") {
{ putValue(Action.SHORT_DESCRIPTION, "New DrScala project"); } // init
public void actionPerformed(ActionEvent ae) { _newProject(); }
};
private volatile AbstractAction _runProjectAction = new AbstractAction("Run Main Class of Project") {
{ /* initalization block */
_addGUIAvailabilityListener(this,
GUIAvailabilityListener.ComponentType.PROJECT,
GUIAvailabilityListener.ComponentType.PROJECT_MAIN_CLASS,
GUIAvailabilityListener.ComponentType.COMPILER,
GUIAvailabilityListener.ComponentType.INTERACTIONS);
}
public void actionPerformed(ActionEvent ae) { _runProject(); }
};
/** The jar options dialog. */
private volatile JarOptionsDialog _jarOptionsDialog;
/** Initializes the "Create Jar from Project" dialog. */
private void initJarOptionsDialog() {
if (DrScala.getConfig().getSetting(DIALOG_JAROPTIONS_STORE_POSITION).booleanValue())
_jarOptionsDialog.setFrameState(DrScala.getConfig().getSetting(DIALOG_JAROPTIONS_STATE));
}
/** Reset the position of the "Create Jar from Project" dialog. */
public void resetJarOptionsDialogPosition() {
_jarOptionsDialog.setFrameState("default");
if (DrScala.getConfig().getSetting(DIALOG_JAROPTIONS_STORE_POSITION).booleanValue()) {
DrScala.getConfig().setSetting(DIALOG_JAROPTIONS_STATE, "default");
}
}
private final Action _jarProjectAction = new AbstractAction("Create Jar File from Project...") {
{ _addGUIAvailabilityListener(this,
GUIAvailabilityListener.ComponentType.PROJECT,
GUIAvailabilityListener.ComponentType.COMPILER); }
public void actionPerformed(ActionEvent ae) { _jarOptionsDialog.setVisible(true); }
};
/** Initializes the "Tabbed Panes" frame. */
private void initTabbedPanesFrame() {
if (DrScala.getConfig().getSetting(DIALOG_TABBEDPANES_STORE_POSITION).booleanValue()) {
_tabbedPanesFrame.setFrameState(DrScala.getConfig().getSetting(DIALOG_TABBEDPANES_STATE));
}
}
/** Reset the position of the "Tabbed Panes" dialog. */
public void resetTabbedPanesFrame() {
_tabbedPanesFrame.setFrameState("default");
if (DrScala.getConfig().getSetting(DIALOG_TABBEDPANES_STORE_POSITION).booleanValue()) {
DrScala.getConfig().setSetting(DIALOG_TABBEDPANES_STATE, "default");
}
}
/** Action that detaches the tabbed panes. Only runs in the event thread. */
private final Action _detachTabbedPanesAction = new AbstractAction("Detach Tabbed Panes") {
public void actionPerformed(ActionEvent ae) {
JMenuItem m = (JMenuItem)ae.getSource();
boolean b = m.isSelected();
_detachTabbedPanesMenuItem.setSelected(b);
DrScala.getConfig().setSetting(DETACH_TABBEDPANES, b);
_tabbedPanesFrame.setDisplayInFrame(b);
}
};
// menu item (checkbox menu) for detaching the tabbed panes
private volatile JMenuItem _detachTabbedPanesMenuItem = null;
/* Debugger deactivated in DrScala */
// /** Initializes the "Debugger" frame. */
// private void initDebugFrame() {
// if (_debugFrame == null) return; // debugger isn't used
// if (DrScala.getConfig().getSetting(DIALOG_DEBUGFRAME_STORE_POSITION).booleanValue()) {
// _debugFrame.setFrameState(DrScala.getConfig().getSetting(DIALOG_DEBUGFRAME_STATE));
// }
// }
//
// /** Reset the position of the "Debugger" dialog. */
// public void resetDebugFrame() {
// if (_debugFrame == null) return; // debugger isn't used
// _debugFrame.setFrameState("default");
// if (DrScala.getConfig().getSetting(DIALOG_DEBUGFRAME_STORE_POSITION).booleanValue()) {
// DrScala.getConfig().setSetting(DIALOG_DEBUGFRAME_STATE, "default");
// }
// }
//
// /** Action that detaches the debugger pane. Only runs in the event thread. */
// private final Action _detachDebugFrameAction = new AbstractAction("Detach Debugger") {
// { _addGUIAvailabilityListener(this, GUIAvailabilityListener.ComponentType.DEBUGGER); }
// public void actionPerformed(ActionEvent ae) {
// if (_debugFrame == null) return; // debugger isn't used
// JMenuItem m = (JMenuItem)ae.getSource();
// boolean b = m.isSelected();
// _detachDebugFrameMenuItem.setSelected(b);
// DrScala.getConfig().setSetting(DETACH_DEBUGGER, b);
// _debugFrame.setDisplayInFrame(b);
// }
// };
/* Debugger deactivated in DrScala */
// // menu item (checkbox menu) for detaching the debugger pane
// private volatile JMenuItem _detachDebugFrameMenuItem;
/** Sets the document in the definitions pane to a new templated junit test class. */
private final Action _newJUnitTestAction = new AbstractAction("New JUnit Test Case...") {
public void actionPerformed(ActionEvent ae) {
String testName = JOptionPane.showInputDialog(MainFrame.this,
"Please enter a name for the test class:",
"New JUnit Test Case",
JOptionPane.QUESTION_MESSAGE);
if (testName != null) {
String ext;
for(int i = 0; i < OptionConstants.LANGUAGE_EXTENSIONS.length; i++) {
ext = OptionConstants.LANGUAGE_EXTENSIONS[i];
if (testName.endsWith(ext)) testName = testName.substring(0, testName.length() - ext.length());
}
// For now, don't include setUp and tearDown
_model.newTestCase(testName, false, false);
}
}
};
/** Asks user for file name and and reads that file into the definitions pane. */
private final Action _openAction = new AbstractAction("Open...") {
public void actionPerformed(ActionEvent ae) {
_open();
_findReplace.updateFirstDocInSearch();
}
};
/** Asks user for directory name and and reads it's files (and subdirectories files, on request) to
* the definitions pane.
*/
private final Action _openFolderAction = new AbstractAction("Open Folder...") {
public void actionPerformed(ActionEvent ae) {
_openFolder();
_findReplace.updateFirstDocInSearch();
}
};
/** Asks user for file name and and reads that file into the definitions pane. */
private final Action _openFileOrProjectAction = new AbstractAction("Open...") {
public void actionPerformed(ActionEvent ae) {
_openFileOrProject();
_findReplace.updateFirstDocInSearch();
}
};
/** Asks user for project file name and and reads the associated files into the file navigator (and places the first
* source file in the editor pane)
*/
private final Action _openProjectAction = new AbstractAction("Open...") {
{ putValue(Action.SHORT_DESCRIPTION, "Open DrScala project"); }
public void actionPerformed(ActionEvent ae) { _openProject(); }
};
private final Action _closeProjectAction = new AbstractAction("Close") {
{ _addGUIAvailabilityListener(this, GUIAvailabilityListener.ComponentType.PROJECT);
putValue(Action.SHORT_DESCRIPTION, "Close DrScala project"); }
public void actionPerformed(ActionEvent ae) {
closeProject();
_findReplace.updateFirstDocInSearch();
}
};
/** Closes the current active document, prompting to save if necessary. */
private final Action _closeAction = new AbstractAction("Close") {
public void actionPerformed(ActionEvent ae) {
_close();
_findReplace.updateFirstDocInSearch();
}
};
/** Closes all open documents, prompting to save if necessary. */
private final Action _closeAllAction = new AbstractAction("Close All") {
public void actionPerformed(ActionEvent ae) {
_closeAll();
_findReplace.updateFirstDocInSearch();
}
};
/** Closes all open documents, prompting to save if necessary. */
private final Action _closeFolderAction = new AbstractAction("Close Folder") {
public void actionPerformed(ActionEvent ae) {
_closeFolder();
_findReplace.updateFirstDocInSearch();
// Set the document currently visible in the definitions pane as active document in the document navigator.
// This action makes sure that something is selected in the navigator after the folder was closed.
_model.getDocumentNavigator().selectDocument(_currentDefPane.getOpenDefDocument());
}
};
/** Opens all the files in the current folder. */
private final Action _openAllFolderAction = new AbstractAction("Open All Files") {
public void actionPerformed(ActionEvent ae) {
// now works with multiple selected folders
List<File> l= _model.getDocumentNavigator().getSelectedFolders();
for(File f: l) {
File fAbs = new File(_model.getProjectRoot(), f.toString());
_openFolder(fAbs, false, _model.getOpenAllFilesInFolderExtension());
}
// The following does not apply anymore:
// Get the Folder that was clicked on by the user. When the user clicks on a directory component in the
// navigation pane, the current directory is updated in the openChooser JFileChooser component. So the
// clicked on directory is obtained in this way
// File dir = _openChooser.getCurrentDirectory();
// _openFolder(dir, false);
_findReplace.updateFirstDocInSearch();
}
};
/** Opens a files in the current folder. */
private final Action _openOneFolderAction = new AbstractAction("Open File in Folder") {
public void actionPerformed(ActionEvent ae) {
_open();
_findReplace.updateFirstDocInSearch();
}
};
/** Creates a new untitled, empty file in the current folder. */
public final Action _newFileFolderAction = new AbstractAction("Create New File in Folder") {
public void actionPerformed(ActionEvent ae) {
//make this new document the document in the document pane
_new();
_findReplace.updateFirstDocInSearch();
}
};
/** Tests all the files in a folder. */
private volatile AbstractAction _junitFolderAction = new AbstractAction("Test Folder") {
{ _addGUIAvailabilityListener(this,
GUIAvailabilityListener.ComponentType.JUNIT,
GUIAvailabilityListener.ComponentType.COMPILER,
GUIAvailabilityListener.ComponentType.INTERACTIONS); }
public final void actionPerformed(ActionEvent ae) { _junitFolder(); }
};
/** Saves the current document. */
private final Action _saveAction = new AbstractAction("Save") {
public final void actionPerformed(ActionEvent ae) { _save(); }
};
/** Returns the changed status of the MainFrame. */
public long getLastChangeTime() { return _lastChangeTime; }
/** Ensures that pack() is run in the event thread. Only used in test code */
public void pack() {
Utilities.invokeAndWait(new Runnable() { public void run() { packHelp(); } });
}
/** Helper method that provides access to super.pack() within the anonymous class new Runnable() {...} above */
private void packHelp() { super.pack(); }
/** Supports MainFrameTest.*/
public boolean isSaveEnabled() { return _saveAction.isEnabled(); }
/** Asks the user for a file name and saves the active document (in the definitions pane) to that file. */
private final Action _saveAsAction = new AbstractAction("Save As...") {
public void actionPerformed(ActionEvent ae) { _saveAs(); }
};
/** Asks the user for a file name and saves a copy of the active document (in the definitions pane) to
* that file. DrScala's state is not modified (i.e. it does not set the document to 'unchanged'). */
private final Action _saveCopyAction = new AbstractAction("Save Copy...") {
public void actionPerformed(ActionEvent ae) { _saveCopy(); }
};
/** Asks the user for a file name and renames and saves the active document (in the definitions pane) to that file. */
private final Action _renameAction = new AbstractAction("Rename") {
public void actionPerformed(ActionEvent ae) { _rename(); }
};
private final Action _saveProjectAction = new AbstractAction("Save") {
{ _addGUIAvailabilityListener(this, GUIAvailabilityListener.ComponentType.PROJECT); // init
putValue(Action.SHORT_DESCRIPTION, "Save DrScala project"); }
public void actionPerformed(ActionEvent ae) {
_saveAll(); // saves project file and all modified project source files; does not save external files
}
};
private final Action _saveProjectAsAction = new AbstractAction("Save As...") {
{ _addGUIAvailabilityListener(this, GUIAvailabilityListener.ComponentType.PROJECT); // init
putValue(Action.SHORT_DESCRIPTION, "Save DrScala project As");
putValue(Action.LONG_DESCRIPTION, "Save DrScala project under different name"); }
public void actionPerformed(ActionEvent ae) {
if (_saveProjectAs()) { // asks user for new project file name; sets _projectFile in global model to this value
_saveAll(); // performs saveAll operation using new project file name, assuming "Save as" was not cancelled
}
}
};
// private final Action _exportProjectInOldFormatAction =
// new AbstractAction("Export Project In Old \"" + OLD_PROJECT_FILE_EXTENSION + "\" Format") {
// { _addGUIAvailabilityListener(this, GUIAvailabilityListener.ComponentType.PROJECT); } // init
// public void actionPerformed(ActionEvent ae) {
// File cpf = _currentProjFile;
// _currentProjFile = FileOps.NULL_FILE;
// if (_saveProjectAs()) { // asks user for new project file name; sets _projectFile in global model to this value
// _saveAllOld(); // performs saveAll operation using new project file name, assuming "Save as" was not cancelled
// }
// _currentProjFile = cpf;
// _model.setProjectFile(cpf);
// _recentProjectManager.updateOpenFiles(cpf);
// }
// };
/** Reverts the current document. */
private final Action _revertAction = new AbstractAction("Revert to Saved") {
public void actionPerformed(ActionEvent ae) {
String title = "Revert to Saved?";
// update message to reflect the number of files
int count = _model.getDocumentNavigator().getDocumentSelectedCount();
String message;
if (count==1)
message = "Are you sure you want to revert the current file to the version on disk?";
else
message = "Are you sure you want to revert the " + count + " selected files to the versions on disk?";
int rc;
Object[] options = {"Yes", "No"};
rc = JOptionPane.showOptionDialog(MainFrame.this, message, title, JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
if (rc == JOptionPane.YES_OPTION) _revert();
}
};
/** Reverts all open documents.
* (not working yet)
private Action _revertAllAction = new AbstractAction("Revert All to Saved") {
public void actionPerformed(ActionEvent ae) {
String title = "Revert All to Saved?";
String message = "Are you sure you want to revert all open " +
"files to the versions on disk?";
int rc = JOptionPane.showConfirmDialog(MainFrame.this,
message,
title,
JOptionPane.YES_NO_OPTION);
if (rc == JOptionPane.YES_OPTION) {
_revertAll();
}
}
};*/
/** Saves all documents, prompting for file names as necessary. */
final Action _saveAllAction = new AbstractAction("Save All") {
public void actionPerformed(ActionEvent ae) { _saveAll(); }
};
/** Prints the current document. */
private final Action _printDefDocAction = new AbstractAction("Print...") {
public void actionPerformed(ActionEvent ae) { _printDefDoc(); }
};
/** Prints the console document. */
private final Action _printConsoleAction = new AbstractAction("Print Console...") {
public void actionPerformed(ActionEvent ae) { _printConsole(); }
};
/** Prints the interactions document. */
private final Action _printInteractionsAction = new AbstractAction("Print Interactions...") {
public void actionPerformed(ActionEvent ae) { _printInteractions(); }
};
/** Opens the print preview window. */
private final Action _printDefDocPreviewAction = new AbstractAction("Print Preview...") {
public void actionPerformed(ActionEvent ae) { _printDefDocPreview(); }
};
/** Opens the print preview window. */
private final Action _printConsolePreviewAction = new AbstractAction("Print Preview...") {
public void actionPerformed(ActionEvent ae) { _printConsolePreview(); }
};
/** Opens the print preview window. */
private final Action _printInteractionsPreviewAction = new AbstractAction("Print Preview...") {
public void actionPerformed(ActionEvent ae) { _printInteractionsPreview(); }
};
/** Opens the page setup window. */
private final Action _pageSetupAction = new AbstractAction("Page Setup...") {
public void actionPerformed(ActionEvent ae) { _pageSetup(); }
};
/** Compiles the document in the definitions pane. */
private final Action _compileAction = new AbstractAction("Compile Current Document") {
public void actionPerformed(ActionEvent ae) {
if (_mainSplit.getDividerLocation() > _mainSplit.getMaximumDividerLocation())
_mainSplit.resetToPreferredSizes();
updateStatusField("Compiling " + _fileTitle);
_compile();
updateStatusField("Compilation of current document completed");
}
};
/** Compiles all the project. */
private volatile AbstractAction _compileProjectAction = new AbstractAction("Compile Project") {
{ _addGUIAvailabilityListener(this, // init
GUIAvailabilityListener.ComponentType.PROJECT,
GUIAvailabilityListener.ComponentType.COMPILER); }
public void actionPerformed(ActionEvent ae) {
if (_mainSplit.getDividerLocation() > _mainSplit.getMaximumDividerLocation())
_mainSplit.resetToPreferredSizes();
String projectName = _model.getProjectFile().getName();
updateStatusField("Compiling all source files of project " + projectName);
_compileProject();
// _findReplace.updateFirstDocInSearch(); // why is this necessary?
updateStatusField("Compilation of project " + projectName + " is complete");
/* The _clearInteractionsListener performs a resetInteractions operation. */
}
};
/** Compiles all documents in the navigators active group. */
private volatile AbstractAction _compileFolderAction = new AbstractAction("Compile Folder") {
{ _addGUIAvailabilityListener(this, GUIAvailabilityListener.ComponentType.COMPILER); } // init
public void actionPerformed(ActionEvent ae) {
if (_mainSplit.getDividerLocation() > _mainSplit.getMaximumDividerLocation())
_mainSplit.resetToPreferredSizes();
updateStatusField("Compiling all sources in current folder");
_compileFolder();
// _findReplace.updateFirstDocInSearch(); // why is this necessary?
updateStatusField("Compilation of folder completed");
}
};
/** Compiles all open documents. */
private volatile AbstractAction _compileAllAction = new AbstractAction("Compile All Documents") {
{ _addGUIAvailabilityListener(this, GUIAvailabilityListener.ComponentType.COMPILER); } // init
public void actionPerformed(ActionEvent ae) {
if (_mainSplit.getDividerLocation() > _mainSplit.getMaximumDividerLocation())
_mainSplit.resetToPreferredSizes();
_compileAll();
// _findReplace.updateFirstDocInSearch(); // why is this necessary?
}
};
/** cleans the build directory */
private volatile AbstractAction _cleanAction = new AbstractAction("Clean Build Directory") {
{ _addGUIAvailabilityListener(this, // init
GUIAvailabilityListener.ComponentType.COMPILER,
GUIAvailabilityListener.ComponentType.PROJECT,
GUIAvailabilityListener.ComponentType.PROJECT_BUILD_DIR); }
public void actionPerformed(ActionEvent ae) { _clean(); }
};
/** auto-refresh the project and open new files */
private volatile AbstractAction _autoRefreshAction = new AbstractAction("Auto-Refresh Project") {
{ _addGUIAvailabilityListener(this, // init
GUIAvailabilityListener.ComponentType.PROJECT,
GUIAvailabilityListener.ComponentType.COMPILER); }
public void actionPerformed(ActionEvent ae) { _model.autoRefreshProject(); }
};
/** Finds and runs the main method of the current document, if it exists. */
private volatile AbstractAction _runAction = new AbstractAction("Run Document's Main Method") {
{ _addGUIAvailabilityListener(this, // init
GUIAvailabilityListener.ComponentType.COMPILER,
GUIAvailabilityListener.ComponentType.INTERACTIONS); }
public void actionPerformed(ActionEvent ae) { _runMain(); }
};
/** Tries to run the current document as an applet. */
private volatile AbstractAction _runAppletAction = new AbstractAction("Run Document as Applet") {
{ _addGUIAvailabilityListener(this, // init
GUIAvailabilityListener.ComponentType.COMPILER,
GUIAvailabilityListener.ComponentType.INTERACTIONS); }
public void actionPerformed(ActionEvent ae) { _runApplet(); }
};
/** Runs JUnit on the document in the definitions pane. */
private volatile AbstractAction _junitAction = new AbstractAction("Test Current Document") {
{ _addGUIAvailabilityListener(this, // init
GUIAvailabilityListener.ComponentType.JUNIT,
GUIAvailabilityListener.ComponentType.COMPILER,
GUIAvailabilityListener.ComponentType.INTERACTIONS); }
public void actionPerformed(ActionEvent ae) {
if (_mainSplit.getDividerLocation() > _mainSplit.getMaximumDividerLocation()) _mainSplit.resetToPreferredSizes();
_junit();
}
};
/** Runs JUnit over all open JUnit tests. */
private volatile AbstractAction _junitAllAction = new AbstractAction("Test All Documents") {
{ _addGUIAvailabilityListener(this, // init
GUIAvailabilityListener.ComponentType.JUNIT,
GUIAvailabilityListener.ComponentType.COMPILER,
GUIAvailabilityListener.ComponentType.INTERACTIONS); }
public void actionPerformed(ActionEvent e) {
if (_mainSplit.getDividerLocation() > _mainSplit.getMaximumDividerLocation()) _mainSplit.resetToPreferredSizes();
_junitAll();
// _findReplace.updateFirstDocInSearch();
}
};
/** Runs JUnit over all open JUnit tests in the project directory. */
private volatile AbstractAction _junitProjectAction = new AbstractAction("Test Project") {
{ _addGUIAvailabilityListener(this, // init
GUIAvailabilityListener.ComponentType.PROJECT,
GUIAvailabilityListener.ComponentType.JUNIT,
GUIAvailabilityListener.ComponentType.COMPILER,
GUIAvailabilityListener.ComponentType.INTERACTIONS); }
public void actionPerformed(ActionEvent e) {
if (_mainSplit.getDividerLocation() > _mainSplit.getMaximumDividerLocation()) _mainSplit.resetToPreferredSizes();
_junitProject();
// _findReplace.updateFirstDocInSearch();
}
};
/** Runs Scaladoc on all open documents (and the files in their packages). */
private volatile AbstractAction _scaladocAllAction = new AbstractAction("Scaladoc All Documents") {
{ _addGUIAvailabilityListener(this, // init
GUIAvailabilityListener.ComponentType.SCALADOC,
GUIAvailabilityListener.ComponentType.COMPILER); }
public void actionPerformed(ActionEvent ae) {
if (_mainSplit.getDividerLocation() > _mainSplit.getMaximumDividerLocation())
_mainSplit.resetToPreferredSizes();
try {
ScaladocModel jm = _model.getScaladocModel();
File suggestedDir = jm.suggestScaladocDestination(_model.getActiveDocument());
_scaladocSelector.setSuggestedDir(suggestedDir);
jm.scaladocAll(_scaladocSelector, _saveSelector);
}
catch (IOException ioe) { MainFrameStatics.showIOError(MainFrame.this, ioe); }
}
};
/** Runs Scaladoc on the current document. */
private volatile AbstractAction _scaladocCurrentAction = new AbstractAction("Preview Scaladoc for Current Document") {
{ _addGUIAvailabilityListener(this, // init
GUIAvailabilityListener.ComponentType.SCALADOC,
GUIAvailabilityListener.ComponentType.COMPILER); }
public void actionPerformed(ActionEvent ae) {
if (_mainSplit.getDividerLocation() > _mainSplit.getMaximumDividerLocation())
_mainSplit.resetToPreferredSizes();
try {