drjava: Is closing upon cancelling intended? - java

Whenever I try to close a file in drjava after making some edits and not saving, the program, as expected, gives the dialog box:
"[Filename] has been modified. Would you like to save it?"
In many cases, I'll decide at this point to cancel the closing and make some more edits, then save the file manually.
Unfortunately, hitting "Cancel" has the same effect as hitting "No": the window closes without saving, and I lose my work.
Is this the intended behavior of drjava? Or is there some option to select / some code I can use to fix the problem? Although as long as I remember the behavior it's manageable, it's still pretty inconvenient.

It's open source, so we can take a look at the implementation. Here's the code that opens the dialog (some code omitted) from the newest branch:
private boolean _fileSaveHelper(OpenDefinitionsDocument doc, int paneOption) {
...
int rc = JOptionPane.showConfirmDialog(MainFrame.this, text, "Save " + fname + "?", paneOption);
switch (rc) {
case JOptionPane.YES_OPTION:
boolean saved = false;
if (notFound) saved = _saveAs();
else saved = _save();
if (doc != lastActive) {
_model.setActiveDocument(lastActive); // breaks when "if" clause omitted
}
return saved;
case JOptionPane.NO_OPTION:
if (doc != lastActive) {
_model.setActiveDocument(lastActive); // breaks when "if" clause omitted
}
return true;
case JOptionPane.CLOSED_OPTION:
case JOptionPane.CANCEL_OPTION:
return false;
default: // never executed
throw new RuntimeException("Invalid option: " + rc);
}
}
There are separate cases for "no" and "cancel", so it looks like they do try to handle it properly. Thus it's probably a bug. The method is referenced by this method
public boolean quitFile(OpenDefinitionsDocument doc) {
return _fileSaveHelper(doc, JOptionPane.YES_NO_CANCEL_OPTION);
}
which is referenced somewhere outside MainFrame.java. I am not inclined to look into it as I don't even have a Java IDE installed. If you wish, you can fork the project and use an IDE like Eclipse to quickly find the references to the method. Speaking of which, I'd suggest just using Eclipse as I remember Dr. Java offering little in the way of basic features such as code completion and formatting.

Related

Method scope inside Java switch statement

In a rather loose way this question follows on from my previous one. The context here is building Android APKs with Phonegap CLI configured, via build-extras.gradle to use Java 7. Here is my code
public boolean execute(String action, JSONArray data,
CallbackContext cbc) throws JSONException
{
Context ctxt = cordova.getActivity().getApplicationContext();
// return doSave(data,cbc,ctxt);
//the above compiles correctly
//doSave is a private method in the same class
switch(action)
{
case "save":return doSave(data,cbc,ctxt);break;
//the compiler complains about an `unreachable statement`
//other case statements ommitted for clarity
default:cbc.error("Unknown action: " + action);return false;
}
return false;
//without this return the compiler is upset.
}
I am having some difficulty understanding two issues here
As far as I can tell even without that last return I have defined a clear path of execution thanks to the switch...default clause so I cannot see why it requires a return statement there
So inside the switch statement the private doSave method in the same class somehow becomes invisible?
I am coming back to Java after a long gap where I did only JS and PHP. However, I have done a great deal of Delphi coding at one time so I appreciate the rigor imposed by the Java compiler. In this instance though it seems to me that it is a bit excessive. Or perhaps I am misunderstanding something?
return doSave(data,cbc,ctxt);break;
Your break statement is unreachable.
You should remove that statement, as well as the final return false; statement, which is also unreachable.

Jumping to return null

I have only ever seen something like this once before when I accidentally tried to debug in release mode, but that isn't the case here. To my question. I have this block of code in an android app:
if (leftRight[0] != null && leftRight[1] != null) {
Log.d("", "test");
return leftRight;
} else {
Log.e("", "test134");
return null;
}
When debugging, the if statement is true and it executes the first Log.d(). However, when stepping to the next line it jumps straight to the return null which I don't understand how that is possible since it is in the else rather than the if. The second Log.d() is skipped over also.
Hopefully I am just missing some small thing, but I am completely baffled as to what is going on. Anything to point me in the right direction is appreciated.
EDIT
If it matters, leftRight is a Point[] containing two Points.
Basically, you are right, it should not happen. However, consider this code:
Log.d("", "test");
if (leftRight[0] != null && leftRight[1] != null) {
return leftRight;
} else {
return null;
}
It has the same effect. Maybe your compiler restructures the code in this way and the debugger is just reflecting this as best as he can ...
EDIT: you can find out whether this is the case using "javap"
EDIT2: you may also try out whether the behavior changes if you change the log messages to do something different ...
If your function returns correct value, there is big chance there are some issues with debugger. Mismatch between lines might happened in example when your code was modified after you build it. I suggest you to clean your workspace, rebuild it and try again.

Discovering the reason for File.mkdirs() failure

If I call one of the methods File.mkdir() or File.mkdirs() in Java, and it returns false, is there a way to know why was the directory not created?
Not really, no. If a SecurityException is NOT thrown, then the most likely cause is a typo in the path, meaning you've accidentally specified a parent path to the new directories that is somehow invalid.
I don't suppose you have it wrapped in a try { ... } catch (Exception e) block, where you don't realize a SecurityException is being thrown, because you're catching an ancestor of SecurityException, do you?
If you have a high belief that everything looks right, and it still fails, I suppose you could simply put it in a loop to retry, say, three times. If it still fails, and depending on your application, you might raise some kind of alert at the UI level, or log the error in a log file (assuming you can write to it).
I suppose it's possible that some deeper I/O issue is preventing it from working, but beyond simply notifying the user of a failure there isn't much you can (or really should) do at an application level. If there's something deeper in the I/O wrong, that's more likely a problem with the system/hardware/OS, or something completely wonky that you have no control over like a subsystem/service crash.
...and if that's happening, that's the responsibility of the IT guy to fix, not your application. Unless of course your app is somehow causing the crash.
I had a mkdirs() failure on windows on a UNC path.
The code looks like this:
public File getOldDirectoryPath(String root, String name)
{
File fulldir = new File(root, name)
boolean created = false
int retry = 0
while (!created) {
retry++
if (!(created = fulldir.exists())) {
if (20 == retry) break
if (!fulldir.mkdirs()) {
sleep(100)
fulldir = new File(root, name)
}
}
}
return fulldir.exists() ? fulldir : null
}
There appears to be some sort of caching involved where exists() returns false (does not exists) but the mkdir on the file system fails because it does exist. Recreating the File() entry or lengthing the timeout did not make a difference.
I discovered a plugin on elasticsearch to fix a SMB problem on Windows. Researching the solution, it uses nio.file instead of io.File. Rewriting the function fixed the issue:
public File getDirectoryPath(String root, String name)
{
Path fulldir = Paths.get(root, name)
boolean created = false
int retry = 0
while (!created) {
retry++
if (!(created = Files.isDirectory(fulldir))) {
if (20 == retry) break
try {
Files.createDirectories(fulldir)
} catch (Throwable thx) {
// error handling
}
}
}
return fulldir.toFile()
}
createDirectories() sometimes fail, but recovers where mkdirs() does not.

How to detect that code is running inside eclipse IDE

How to detect that code is running inside eclipse IDE
I am not aware of a generic way to get this kind of information.
One suggestion:
When you start a Java program (or a web server) inside Tomcat, simply add an argument that will indicate that this program is launched by Eclipse.
You can do that by opening the "Open Run Dialog" ("Run" menu), then select your type of application and add in the "Arguments" tab a -DrunInEclipse=true.
In your Java code, you can check the value of the property:
String inEclipseStr = System.getProperty("runInEclipse");
boolean inEclipse = "true".equalsIgnoreCase(inEclipseStr);
This way, if the program is not running inside Eclipse (or unfortunately if you forgot to set the property) the property will be null and then the boolean inEclipse will be equal to false.
Although I agree that having the code detecting a single IDE as the dev env is not an optimal solution, the following code works.
Like others proposed, using a flag at runtime is better.
public static boolean isEclipse() {
boolean isEclipse = System.getProperty("java.class.path").toLowerCase().contains("eclipse");
return isEclipse;
}
1) Create a helper method like:
public boolean isDevelopmentEnvironment() {
boolean isEclipse = true;
if (System.getenv("eclipse42") == null) {
isEclipse = false;
}
return isEclipse;
}
2) Add an environment variable to your launch configuration:
3) Usage example:
if (isDevelopmentEnvironment()) {
// Do bla_yada_bla because the IDE launched this app
}
Actually the code is not being run inside Eclipse, but in a separate Java process started by Eclipse, and there is per default nothing being done by Eclipse to make it any different than any other invocation of your program.
Is the thing you want to know, if your program is being run under a debugger? If so, you cannot say for certain. You CAN, however, inspect the arguments used to invoke your program and see if there is anything in there you do not like.
If your workspace matches some pattern like "/home/user/workspace/Project" you can use the code below:
Boolean desenv = null;
boolean isDevelopment() {
if (desenv != null) return desenv;
try {
desenv = new File(".").getCanonicalPath().contains("workspace");
}
catch (IOException e) {
e.printStackTrace();
}
return desenv;
}
A more generic and precise way, that can be used on any IDE would be loop at:
ManagementFactory.getRuntimeMXBean().getInputArguments()
looking for "-Xdebug" || (starting with) "-agentlib:jdwp=".
I came with this from #saugata comment here.
This is excellent if you want to throw a conditional exception preventing the application from simply exiting. Use a boolean like "ideWait" and add it to Eclipse watch expressions as ideWait=false, so whenever you stop at that throw, and "drop to frame" you can continue debugging happily (I mean it!)
I don't think there is any way to do this. But what I would suggest is just a command line argument such as 'debug'. Then in your main method just do
if (args.length > 0 && args[0].equalsIgnoreCase("debug")) {
// do whatever extra work you require here or set a flag for the rest of the code
}
This way you can also get your extra code to run whenever you want just by specifiying the debug parameter but under normal conditions it will never execute.
This might work if your alternative execution work flow provides a different set of dependencies:
boolean isRunningInEclipe = false;
try {
Workbench.getInstance();
isRunningInEclipe = true;
} catch (NoClassDefFoundError error) {
//not running in Eclipse that would provide the Workbench class
}
You could detect if you're inside a JAR or not, as per Can you tell on runtime if you're running java from within a jar?
Eclipse will run your app from the classes/ dir, whereas most of your end users will be running the app from a JAR.
System.out.println("Is my parent eclipse[.exe]? " +
ProcessHandle.current()
.parent()
.flatMap(parent -> parent.info().command())
.orElse("")
.matches("^.*eclipse(\\.exe)?$"));
You may try something like this:
if (ClassLoader.getSystemResource("org/eclipse/jdt/core/BindingKey.class")!=null){
System.out.println("Running within Eclipse!!!");
} else {
System.out.println("Running outside Eclipse!!!");
}

Testing if Quicktime and Java are installed?

In Javascript how can I test if the user has the quicktime plugin and java plugins installed?
For Java, you can use navigator.javaEnabled(). Or you can look here: http://www.pinlady.net/PluginDetect/JavaDetect.htm
For QuickTime, you can do:
var QtPlugin = navigator.plugins["Quicktime"];
if (QtPlugin) {//QuickTime is installed}
See here: http://javascript.internet.com/miscellaneous/check-plugins.html
This of course does not work in IE. The only way to check plugins in IE is using VB script, and it is very strange and messy. You can only test for specific plugin versions, for example, "quicktime" won't cut it. You have to specify the version, which is not published for versions older than 5, and I can't find a reference for version 7
The above examples haven't got the answer to the QuickTime part of your question, so here's what I'm writing right now even though the question has been closed and is a little old.
var p = navigator.plugins;
var qtcheck = 0;
for (i=0;i<p.length;i++) {
if (p[i].name.match(/QuickTime/) != null) {
qtcheck++
}
}
if (qtcheck > 0) { // do nothing, QuickTime is intalled }
else {
videos = document.querySelectorAll('object[type="video/quicktime"]')
// use .getElementById instead if there are multiple videos
// replace them with document.createElement('img')
For a more comprehensive and foolproof method i.e. without worry of a plug-in being renamed for whatever reason, you can check within the array of MimeTypes for type="video/quicktime" which is the ultimate answer of whether the object will be supported (or if you're not using the QT video, whatever else you're using it for instead).
This means creating a loop inside the loop through the plugins instead, but is a more firm verification than just a string match:
function checkQT() {
var p = navigator.plugins;
var QT = false; // assume you don't have it
for (i=0;i<p.length;i++) {
for (j=0;j<p[i].length;j++) {
if (p[i][j].type == "video/quicktime") {
QT = true;
return true;
}
else continue;
return false;
}
}
}
I searched around online and found a bunch of great IE fallback scripts here (not sure if this paste service code is going to persist so I gisted it for posterity), from which I took the QuickTime one:
function IEhasQT() {
if (!window.ActiveXObject) return false;
try { if(new ActiveXObject("QuickTime.QuickTime")) return true; }
catch (e) {}
try { if (new ActiveXObject('QuickTimeCheckObject.QuickTimeCheck')) return true; }
catch (e) {}
return false;
}
I tested some others and they just didn't work - catching the exceptions is important.
If you're doing what I'm doing (QuickTime fallback to a gif animation) you might want to take the attributes of the video to provide to the image (or whatever else you're using). The downside to this is that you have to couple it to an onscroll as well as onload (or use Jquery) as the browser is liable to try and find the element before the DOM has loaded no matter how you try and avoid it.
If anyone else reading this is looking for a similar answer, the code to do so is
function noQTfallback() {
var vid1 = document.getElementById("<insert your object id>");
var vid1gif = document.createElement('img');
vid1gif.setAttribute("src","<insert your URL source>");
vid1gif.setAttribute("style",vid1.getAttribute("style"));
document.getElementById("<...>").replaceChild(vid1gif, vid1);
}
function IEhasQT() {
// as above
}
function checkQT() {
// as above
}
function QTbackup(){
if (!checkQT() && !IEhasQT()) {
noQTfallback();
}
}
window.document.body.onload = QTbackup;
window.onscroll = QTbackup;
Oddly, you can have multiple versions of QuickTime installed, my Chrome browser on Windows has 7 copies... Luckily I have a Chromebook which doesn't have QT plug-in either installed or available, so I'm checking and seeing what works to distinguish it, this is the best I've come up with.
I never understood why testing was so important until looking at everyone's awful code on this online, incredible. I know no one cares about IE but basic things like || instead of && are just bad to leave lying around for other developers to reuse.
I've checked this on Windows, Linux and Android (IE and Chrome). The onscroll gives a bit of a jump but without Jquery or some other framework it's unavoidable I guess (and beats "plug-in not supported" !

Categories