Skip to content

Commit cfd4689

Browse files
author
mgricken
committed
This commit contains two new features:
1) Drag-and-drop for Java files. Files from Windows Explorer, MacOS Finder, and Nautilus on Linux (other file browsers not tested) can be dragged and dropped into DrJava. Since drag-and-drop targets are enabled on a per-component basis and not globally for a frame or application, there are some parts of DrJava's GUI that are NOT drop targets. However, most big GUI parts, like the list and tree navigators, the interactions pane and the definitions pane, are enabled as drop targets. 2) Connecting to a running DrJava instance to make it open files. When DrJava is started and a file (or files) is specified on the command line (or by dragging and dropping a file over the DrJava exe on Windows), DrJava will attempt to open the file in an already existing instance of DrJava. If no running instance is found, a new instance of DrJava is started and the file opened. This is accomplished by letting the first instance of DrJava listen on a socket (default: 4444) and having subsequent instances send a message to that socket. If there is no response within 250 ms, it is assumed that no "remote control"-enabled instance of DrJava is running. To force DrJava to always start a new instance, the -new command line switch can be used. M src/edu/rice/cs/drjava/DrJava.java M src/edu/rice/cs/drjava/DrJavaRoot.java M src/edu/rice/cs/drjava/model/repl/DynamicJavaAdapter.java A src/edu/rice/cs/drjava/RemoteControlServer.java M src/edu/rice/cs/drjava/config/OptionConstants.java M src/edu/rice/cs/drjava/CommandLineTest.java A src/edu/rice/cs/drjava/RemoteControlClient.java M src/edu/rice/cs/drjava/ui/MainFrame.java M src/edu/rice/cs/drjava/ui/TabbedPanel.java M src/edu/rice/cs/drjava/ui/config/ConfigFrame.java M src/edu/rice/cs/drjava/ui/AbstractDJPane.java M src/edu/rice/cs/util/docnavigation/JListSortNavigator.java M src/edu/rice/cs/util/docnavigation/JTreeSortNavigator.java M src/edu/rice/cs/util/PreventExitSecurityManager.java M src/edu/rice/cs/util/newjvm/SlaveJVMRunner.java M src/edu/rice/cs/util/newjvm/AbstractSlaveJVM.java git-svn-id: file:///tmp/test-svn/trunk@4260 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent 34ce848 commit cfd4689

16 files changed

+757
-120
lines changed

drjava/src/edu/rice/cs/drjava/CommandLineTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ public void tearDown() throws Exception {
209209

210210
/** Tests DrJava with no command line arguments. Should open a new, untitled document. */
211211
public void testNone() {
212-
DrJavaRoot.openCommandLineFiles(_mf, new String[0]);
212+
DrJavaRoot.openCommandLineFiles(_mf, new String[0],false);
213213
// ListModel<DefinitionsDocument> docs =
214214
// Wouldn't that be nice?
215215
List<OpenDefinitionsDocument> docs = _mf.getModel().getOpenDefinitionsDocuments();
@@ -223,7 +223,7 @@ public void testNone() {
223223
public void testOpenOne() throws BadLocationException {
224224
String[] list = new String[1];
225225
list[0] = f1_name;
226-
DrJavaRoot.openCommandLineFiles(_mf, list);
226+
DrJavaRoot.openCommandLineFiles(_mf, list,false);
227227
// _log.log("openCommandLineFiles completed");
228228
List<OpenDefinitionsDocument> docs = _mf.getModel().getOpenDefinitionsDocuments();
229229
// Utilities.showDebug(docs.toString());
@@ -241,7 +241,7 @@ public void testOpenOne() throws BadLocationException {
241241
public void testNE() {
242242
String[] list = new String[1];
243243
list[0] = nof1_name;
244-
DrJavaRoot.openCommandLineFiles(_mf, list);
244+
DrJavaRoot.openCommandLineFiles(_mf, list, false);
245245
// _log.log("openCommandLineFiles completed");
246246
List<OpenDefinitionsDocument> docs = _mf.getModel().getOpenDefinitionsDocuments();
247247
assertEquals("Exactly one document?", 1, docs.size());
@@ -256,7 +256,7 @@ public void testOpenMany() throws BadLocationException {
256256
list[0] = f1_name;
257257
list[1] = f2_name;
258258
list[2] = f3_name;
259-
DrJavaRoot.openCommandLineFiles(_mf, list);
259+
DrJavaRoot.openCommandLineFiles(_mf, list, false);
260260
// _log.log("openCommandLineFiles completed");
261261
List<OpenDefinitionsDocument> docs = _mf.getModel().getOpenDefinitionsDocuments();
262262
assertEquals("Exactly three documents?", 3, docs.size());
@@ -285,7 +285,7 @@ public void testMixed() throws BadLocationException {
285285
list[3] = f5_name;
286286
list[4] = f6_name;
287287
list[5] = nof3_name;
288-
DrJavaRoot.openCommandLineFiles(_mf, list);
288+
DrJavaRoot.openCommandLineFiles(_mf, list, false);
289289
// _log.log("openCommandLineFiles completed");
290290
List<OpenDefinitionsDocument> docs = _mf.getModel().getOpenDefinitionsDocuments();
291291
assertEquals("Exactly three documents?", 3, docs.size());
@@ -314,7 +314,7 @@ public void testDups() throws BadLocationException {
314314
list[3] = f8_name;
315315
list[4] = f8_name;
316316
list[5] = f7_name;
317-
DrJavaRoot.openCommandLineFiles(_mf, list);
317+
DrJavaRoot.openCommandLineFiles(_mf, list, false);
318318
// _log.log("openCommandLineFiles in testDups completed");
319319

320320
List<OpenDefinitionsDocument> docs = _mf.getModel().getOpenDefinitionsDocuments();
@@ -390,7 +390,7 @@ private void checkFile(File relativeFile, String funnyName) throws IOException,
390390
assertTrue("file exists", relativeFile.exists());
391391

392392
String path = relativeFile.getCanonicalPath();
393-
DrJavaRoot.openCommandLineFiles(_mf, new String[] { path });
393+
DrJavaRoot.openCommandLineFiles(_mf, new String[] { path }, false);
394394

395395
List<OpenDefinitionsDocument> docs = _mf.getModel().getOpenDefinitionsDocuments();
396396
assertEquals("Number of open documents", 1, docs.size());

drjava/src/edu/rice/cs/drjava/DrJava.java

Lines changed: 113 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@
6767
import edu.rice.cs.plt.debug.DebugUtil;
6868

6969
/** Startup class for DrJava consisting entirely of static members. The main method reads the .drjava file (creating
70-
* one if none exists) to get the critical information required to start the main JVM for DrJava:
71-
* (i) the location of tools.jar in the Java JDK installed on this machine (so DrJava can invoke the javac compiler
72-
* stored in tools.jar)
73-
* (ii) the argument string for invoking the main JVM (notably -X options used to determine maximum heap size, etc.)
74-
* @version $Id$
75-
*/
70+
* one if none exists) to get the critical information required to start the main JVM for DrJava:
71+
* (i) the location of tools.jar in the Java JDK installed on this machine (so DrJava can invoke the javac compiler
72+
* stored in tools.jar)
73+
* (ii) the argument string for invoking the main JVM (notably -X options used to determine maximum heap size, etc.)
74+
* @version $Id$
75+
*/
7676
public class DrJava {
7777

7878
private static Log _log = new Log("DrJava.txt", false);
@@ -81,13 +81,17 @@ public class DrJava {
8181

8282
private static final ArrayList<String> _filesToOpen = new ArrayList<String>();
8383
private static final ArrayList<String> _jvmArgs = new ArrayList<String>();
84-
84+
8585
static volatile boolean _showDebugConsole = false;
8686

87+
/** true if a new instance of DrJava should be started instead of
88+
* connecting to an already running instance. */
89+
static volatile boolean _forceNewInstance = false;
90+
8791
/* Config objects can't be public static final, since we have to delay construction until we know the
8892
* config file's location. (Might be specified on command line.) Instead, use accessor methods to
8993
* prevent others from assigning new values. */
90-
94+
9195
/** Default properties file used by the configuration object, i.e. ".drjava" in the user's home directory. */
9296
public static final File DEFAULT_PROPERTIES_FILE = new File(System.getProperty("user.home"), ".drjava");
9397

@@ -99,76 +103,112 @@ public class DrJava {
99103

100104
/** Returns the properties file used by the configuration object. */
101105
public static File getPropertiesFile() { return _propertiesFile; }
102-
106+
103107
/** Returns the configuration object with all customized and default values. */
104108
public static FileConfiguration getConfig() { return _config; }
105-
109+
106110
/** @return an array of the files that were passed on the command line. */
107111
public static String[] getFilesToOpen() { return _filesToOpen.toArray(new String[0]); }
108112

109113
/** @return true if the debug console should be enabled */
110114
public static boolean getShowDebugConsole() { return _showDebugConsole; }
111115

112116
/** Starts running DrJava.
113-
* @param args Command line argument array
114-
*/
117+
* @param args Command line argument array
118+
*/
115119
public static void main(final String[] args) {
116120
// Platform-specific UI setup.
117121
PlatformFactory.ONLY.beforeUISetup();
118122

119-
new SplashScreen().flash();
123+
// handleCommandLineArgs will return true if DrJava should be loaded
124+
if (handleCommandLineArgs(args)) {
125+
if (!_forceNewInstance && (_filesToOpen.size()>0)) {
126+
try {
127+
boolean ret = RemoteControlClient.openFile(null);
128+
if (!RemoteControlClient.isServerRunning()) {
129+
// server not running, display splash screen
130+
new SplashScreen().flash();
131+
}
132+
}
133+
catch(IOException ioe) {
134+
// ignore
135+
}
136+
}
137+
else {
138+
// either forcing new instance or no files specified, display splash screen
139+
new SplashScreen().flash();
140+
}
141+
120142
// Utilities.showDebug("Calling configureAndLoadDrJavaRoot with args = " + args);
121-
configureAndLoadDrJavaRoot(args);
143+
configureAndLoadDrJavaRoot(args);
144+
}
122145
}
123146

124147
public static void configureAndLoadDrJavaRoot(String[] args) {
125148
try {
126-
// handleCommandLineArgs will return true if DrJava should be loaded
127-
if (handleCommandLineArgs(args)) {
128-
129-
// Restart if there are custom JVM args
130-
boolean restart = getConfig().getSetting(MASTER_JVM_ARGS).length() > 0;
131-
132-
LinkedList<String> classArgsList = new LinkedList<String>();
133-
classArgsList.addAll(_filesToOpen);
134-
135-
// Add the parameters "-debugConsole" to classArgsList if _showDebugConsole is true
136-
if (_showDebugConsole) { classArgsList.addFirst("-debugConsole"); }
137-
138-
if (!_propertiesFile.equals(DEFAULT_PROPERTIES_FILE)) {
139-
// Placed in reversed order to get "-config filename"
140-
classArgsList.addFirst(_propertiesFile.getAbsolutePath());
141-
classArgsList.addFirst("-config");
149+
// if there were files passed on the command line,
150+
// try to open them in an existing instance
151+
if (!_forceNewInstance &&
152+
DrJava.getConfig().getSetting(edu.rice.cs.drjava.config.OptionConstants.REMOTE_CONTROL_ENABLED) &&
153+
(_filesToOpen.size()>0)) {
154+
try {
155+
boolean ret = RemoteControlClient.openFile(null);
156+
if (RemoteControlClient.isServerRunning()) {
157+
// existing instance is running and responding
158+
for (int i=0; i<_filesToOpen.size(); ++i) {
159+
RemoteControlClient.openFile(new File(_filesToOpen.get(i)));
160+
}
161+
// files opened in existing instance, quit
162+
System.exit(0);
163+
}
142164
}
143-
144-
String[] classArgs = classArgsList.toArray(new String[0]);
165+
catch(IOException ioe) {
166+
ioe.printStackTrace();
167+
}
168+
}
169+
170+
// Restart if there are custom JVM args
171+
boolean restart = getConfig().getSetting(MASTER_JVM_ARGS).length() > 0;
172+
173+
LinkedList<String> classArgsList = new LinkedList<String>();
174+
classArgsList.addAll(_filesToOpen);
175+
176+
// Add the parameters "-debugConsole" to classArgsList if _showDebugConsole is true
177+
if (_showDebugConsole) { classArgsList.addFirst("-debugConsole"); }
178+
179+
if (!_propertiesFile.equals(DEFAULT_PROPERTIES_FILE)) {
180+
// Placed in reversed order to get "-config filename"
181+
classArgsList.addFirst(_propertiesFile.getAbsolutePath());
182+
classArgsList.addFirst("-config");
183+
}
184+
185+
String[] classArgs = classArgsList.toArray(new String[0]);
186+
187+
if (restart) {
188+
String classPath = System.getProperty("java.class.path");
145189

146-
if (restart) {
147-
String classPath = System.getProperty("java.class.path");
148-
149-
// Run a new copy of DrJava and exit
150-
try {
190+
// Run a new copy of DrJava and exit
191+
try {
151192
// Utilities.showDebug("Starting DrJavaRoot with classArgs = " + Arrays.toString(classArgs) + "; classPath = " + classPath +
152193
// "; jvmArgs = " + _jvmArgs + "; workDir = " + workDir);
153-
ExecJVM.runJVM("edu.rice.cs.drjava.DrJavaRoot", classArgs, classPath, _jvmArgs.toArray(new String[0]), null);
154-
}
155-
catch (IOException ioe) {
156-
// Display error
157-
final String[] text = {
158-
"DrJava was unable to load its compiler and debugger. Would you ",
159-
"like to start DrJava without a compiler and debugger?", "\nReason: " + ioe.toString()
160-
};
161-
int result = JOptionPane.showConfirmDialog(null, text, "Could Not Load Compiler and Debugger",
162-
JOptionPane.YES_NO_OPTION);
163-
if (result != JOptionPane.YES_OPTION) { System.exit(0); }
164-
}
194+
ExecJVM.runJVM("edu.rice.cs.drjava.DrJavaRoot", classArgs, classPath, _jvmArgs.toArray(new String[0]), null);
165195
}
166-
167-
else {
168-
// No restart -- just invoke DrJavaRoot.main.
169-
DrJavaRoot.main(classArgs);
196+
catch (IOException ioe) {
197+
// Display error
198+
final String[] text = {
199+
"DrJava was unable to load its compiler and debugger. Would you ",
200+
"like to start DrJava without a compiler and debugger?", "\nReason: " + ioe.toString()
201+
};
202+
int result = JOptionPane.showConfirmDialog(null, text, "Could Not Load Compiler and Debugger",
203+
JOptionPane.YES_NO_OPTION);
204+
if (result != JOptionPane.YES_OPTION) { System.exit(0); }
170205
}
171206
}
207+
208+
else {
209+
// No restart -- just invoke DrJavaRoot.main.
210+
DrJavaRoot.main(classArgs);
211+
}
172212
}
173213
catch(Throwable t) {
174214
// Show any errors to the System.err and in an DrJavaErrorHandler
@@ -179,8 +219,8 @@ public static void configureAndLoadDrJavaRoot(String[] args) {
179219
}
180220

181221
/** Handles any command line arguments that have been specified.
182-
* @return true if DrJava should load, false if not
183-
*/
222+
* @return true if DrJava should load, false if not
223+
*/
184224
static boolean handleCommandLineArgs(String[] args) {
185225
boolean heapSizeGiven = false; // indicates whether args includes an argument of the form -Xmx<number>
186226

@@ -209,6 +249,8 @@ else if (arg.startsWith("-X") || arg.startsWith("-D")) {
209249

210250
else if (arg.equals("-debugConsole")) _showDebugConsole = true;
211251

252+
else if (arg.equals("-new")) _forceNewInstance = true;
253+
212254
else if (arg.equals("-help") || arg.equals("-?")) {
213255
displayUsage();
214256
return false;
@@ -225,7 +267,7 @@ else if (arg.equals("-help") || arg.equals("-?")) {
225267
if (arg.startsWith("-Xmx")) { heapSizeGiven = true; }
226268
_jvmArgs.add(arg);
227269
}
228-
270+
229271
if (PlatformFactory.ONLY.isMacPlatform()) {
230272
String iconLoc = System.getProperty("edu.rice.cs.drjava.icon");
231273
if (iconLoc != null) { // we are running inside the Mac app wrapper
@@ -235,21 +277,23 @@ else if (arg.equals("-help") || arg.equals("-?")) {
235277
}
236278

237279
if (!heapSizeGiven) { _jvmArgs.add(DEFAULT_MAX_HEAP_SIZE_ARG); }
238-
280+
239281
_log.log("_jvmArgs = " + _jvmArgs);
240-
282+
241283
// Open the remaining args as filenames
242-
284+
243285
for (int i = argIndex; i < len; i++) { _filesToOpen.add(args[i]); }
244286
return true;
245287
}
246-
288+
247289
/** Displays a usage message about the available options. */
248290
static void displayUsage() {
249291
final StringBuilder buf = new StringBuilder();
250292
buf.append("Usage: java -jar drjava.jar [OPTIONS] [FILES]\n\n");
251293
buf.append("where options include:\n");
252294
buf.append(" -config [FILE] use a custom config file\n");
295+
buf.append(" -new force the creation of a new DrJava instance;");
296+
buf.append(" do not connect to existing instance");
253297
buf.append(" -help | -? print this help message\n");
254298
buf.append(" -X<jvmOption> specify a JVM configuration option for the master DrJava JVM\n");
255299
buf.append(" -D<name>[=<value>] set a Java property for the master DrJava JVM\n");
@@ -322,23 +366,23 @@ static void displayUsage() {
322366
// }
323367
// }
324368

325-
369+
326370
/** Switches the config object to use a custom config file. Ensures that Java source files aren't
327-
* accidentally used.
328-
*/
371+
* accidentally used.
372+
*/
329373
static void setPropertiesFile(String fileName) {
330374
if (!fileName.endsWith(".java")) _propertiesFile = new File(fileName);
331375
}
332376

333377
/** Initializes the configuration object with the current notion of the properties file.
334-
* @throws IllegalStateException if config has already been assigned
335-
*/
378+
* @throws IllegalStateException if config has already been assigned
379+
*/
336380
static FileConfiguration _initConfig() throws IllegalStateException {
337381
// // Make sure someone doesn't try to change the config object.
338382
// if (_config != null) throw new IllegalStateException("Can only call initConfig once!");
339383

340384
FileConfiguration config;
341-
385+
342386
try { _propertiesFile.createNewFile(); } // be nice and ensure a config file if there isn't one
343387
catch (IOException e) { /* IOException occurred, continue without a real file */ }
344388

@@ -352,7 +396,7 @@ static FileConfiguration _initConfig() throws IllegalStateException {
352396
_config = config; // required to support calls on DrJava._initConfig() in unit tests
353397
return config;
354398
}
355-
399+
356400
/** Saves the contents of the config file. TO DO: log any IOExceptions that occur. */
357401
protected static void _saveConfig() {
358402
try { getConfig().saveConfiguration(); }
@@ -366,7 +410,7 @@ protected static void _saveConfig() {
366410
// TODO: log this error
367411
}
368412
}
369-
413+
370414
// /** Displays a prompt to the user indicating that tools.jar could not be found in the specified location, and asks
371415
// * if he would like to specify a new location.
372416
// */
@@ -406,6 +450,5 @@ protected static void _saveConfig() {
406450
//
407451
// int result = JOptionPane.showConfirmDialog(null, text, "Locate 'tools.jar'?", JOptionPane.YES_NO_OPTION);
408452
// return result == JOptionPane.YES_OPTION;
409-
// }
410-
453+
// }
411454
}

0 commit comments

Comments
 (0)