diff --git a/app/src/processing/app/ChangeDetector.java b/app/src/processing/app/ChangeDetector.java
index 88e3db081..4e3160646 100644
--- a/app/src/processing/app/ChangeDetector.java
+++ b/app/src/processing/app/ChangeDetector.java
@@ -1,10 +1,13 @@
package processing.app;
+import java.awt.EventQueue;
+import java.awt.Frame;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
public class ChangeDetector implements WindowFocusListener {
private Sketch sketch;
@@ -46,12 +49,76 @@ public class ChangeDetector implements WindowFocusListener {
th.start();
}
+ private void showErrorAsync(final String title, final String message,
+ final Exception e) {
+ EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ Base.showError(title, message, e);
+ }
+ });
+ }
+
+ private void showWarningAsync(final String title, final String message) {
+ EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ Base.showWarning(title, message);
+ }
+ });
+ }
+
+ private void showWarningTieredAsync(final String title,
+ final String message1,
+ final String message2, final Exception e) {
+ EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ Base.showWarningTiered(title, message1, message2, e);
+ }
+ });
+ }
+
+ private int showYesNoQuestionAsync(final Frame editor, final String title,
+ final String message1,
+ final String message2) {
+ final int[] res = { -1 };
+ try {
+ //have to wait for a response on this one
+ EventQueue.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ res[0] = Base.showYesNoQuestion(editor, title, message1, message2);
+ }
+ });
+ } catch (InvocationTargetException e) {
+ //occurs if Base.showYesNoQuestion throws an error, so, shouldn't happen
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ //occurs if the EDT is interrupted, so, shouldn't happen
+ e.printStackTrace();
+ }
+ return res[0];
+ }
+
+ private void rebuildHeaderAsync() {
+ EventQueue.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ editor.header.rebuild();
+ }
+ });
+ }
+
private void checkFileChange() {
//check that the content of each of the files in sketch matches what is in memory
if (sketch == null) {
return;
}
+ //make sure the sketch folder exists at all. if it does not, it will be re-saved, and no changes will be detected
+ //
+ sketch.ensureExistence();
//check file count first
File sketchFolder = sketch.getFolder();
int fileCount = sketchFolder.list(new FilenameFilter() {
@@ -59,7 +126,7 @@ public class ChangeDetector implements WindowFocusListener {
@Override
public boolean accept(File dir, String name) {
for (String s : editor.getMode().getExtensions()) {
- if (name.endsWith(s)) {
+ if (name.toLowerCase().endsWith(s.toLowerCase())) {
return true;
}
}
@@ -68,14 +135,14 @@ public class ChangeDetector implements WindowFocusListener {
}).length;
if (fileCount != sketch.getCodeCount()) {
- reloadSketch(null);
- if (fileCount < 1) {
+ //if they chose to reload and there aren't any files left
+ if (reloadSketch(null) && fileCount < 1) {
try {
//make a blank file
sketch.getMainFile().createNewFile();
} catch (Exception e1) {
//if that didn't work, tell them it's un-recoverable
- Base.showError("Reload failed", "The sketch contains no code files.",
+ showErrorAsync("Reload failed", "The sketch contains no code files.",
e1);
//don't try to reload again after the double fail
//this editor is probably trashed by this point, but a save-as might be possible
@@ -84,11 +151,9 @@ public class ChangeDetector implements WindowFocusListener {
}
//it's okay to do this without confirmation, because they already confirmed to deleting the unsaved changes above
sketch.reload();
- editor.header.rebuild();
- Base
- .showWarning("Modified Reload",
- "You cannot delete the last code file in a sketch.\n"
- + "A new blank sketch file has been generated for you.");
+ showWarningAsync("Modified Reload",
+ "You cannot delete the last code file in a sketch.\n"
+ + "A new blank sketch file has been generated for you.");
}
return;
@@ -108,10 +173,9 @@ public class ChangeDetector implements WindowFocusListener {
try {
onDisk = Base.loadFile(sketchFile);
} catch (IOException e1) {
- Base
- .showWarningTiered("File Change Detection Failed",
- "Checking for changed files for this sketch has failed.",
- "The file change detector will be disabled.", e1);
+ showWarningTieredAsync("File Change Detection Failed",
+ "Checking for changed files for this sketch has failed.",
+ "The file change detector will be disabled.", e1);
enabled = false;
return;
}
@@ -130,18 +194,17 @@ public class ChangeDetector implements WindowFocusListener {
}
//returns true if the files in the sketch have been reloaded
- private void reloadSketch(SketchCode changed) {
- int response = Base
- .showYesNoQuestion(editor,
- "File Modified",
- "Your sketch has been modified externally.
Would you like to reload the sketch?",
- "If you reload the sketch, any unsaved changes will be lost!");
+ private boolean reloadSketch(SketchCode changed) {
+ int response = showYesNoQuestionAsync(editor,
+ "File Modified",
+ "Your sketch has been modified externally.
Would you like to reload the sketch?",
+ "If you reload the sketch, any unsaved changes will be lost!");
if (response == 0) {
//reload the sketch
sketch.reload();
- editor.header.rebuild();
-
+ rebuildHeaderAsync();
+ return true;
} else {
//they said no, make it possible for them to stop the errors by saving
if (changed != null) {
@@ -157,11 +220,10 @@ public class ChangeDetector implements WindowFocusListener {
}
//if files were simply added, then nothing needs done
}
- editor.header.rebuild();
+ rebuildHeaderAsync();
skip = true;
- return;
+ return false;
}
- return;
}
@Override
diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PSurfaceLWJGL.java b/java/libraries/lwjgl/src/processing/lwjgl/PSurfaceLWJGL.java
index 80367c96e..014c3ddad 100644
--- a/java/libraries/lwjgl/src/processing/lwjgl/PSurfaceLWJGL.java
+++ b/java/libraries/lwjgl/src/processing/lwjgl/PSurfaceLWJGL.java
@@ -6,13 +6,9 @@ import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
-import java.awt.Image;
-import java.awt.Point;
import java.awt.Rectangle;
-import java.awt.Toolkit;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
-import java.awt.image.MemoryImageSource;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
@@ -52,6 +48,7 @@ public class PSurfaceLWJGL implements PSurface {
int cursorType = PConstants.ARROW; // cursor type
boolean cursorVisible = true; // cursor visibility flag
Cursor invisibleCursor;
+ Cursor currentCursor;
// ........................................................
@@ -199,8 +196,15 @@ public class PSurfaceLWJGL implements PSurface {
@Override
public void placeWindow(int[] location) {
- Display.setLocation(location[0], location[1]);
-
+ if (location != null) {
+ // a specific location was received from the Runner
+ // (applet has been run more than once, user placed window)
+ Display.setLocation(location[0], location[1]);
+ } else { // just center on screen
+ // Can't use frame.setLocationRelativeTo(null) because it sends the
+ // frame to the main display, which undermines the --display setting.
+ setFrameCentered();
+ }
}
@Override
@@ -208,6 +212,13 @@ public class PSurfaceLWJGL implements PSurface {
// TODO Auto-generated method stub
}
+
+ private void setFrameCentered() {
+ // Can't use frame.setLocationRelativeTo(null) because it sends the
+ // frame to the main display, which undermines the --display setting.
+ Display.setLocation(screenRect.x + (screenRect.width - sketchWidth) / 2,
+ screenRect.y + (screenRect.height - sketchHeight) / 2);
+ }
@Override
public void placePresent(Color stopColor) {
@@ -319,11 +330,13 @@ public class PSurfaceLWJGL implements PSurface {
@Override
public void setCursor(int kind) {
+ System.err.println("Sorry, cursor types not supported in OpenGL, provide your cursor image");
// TODO Auto-generated method stub
- if (PApplet.platform == PConstants.MACOSX && kind == PConstants.MOVE) {
- kind = PConstants.HAND;
- }
- java.awt.Cursor cursor0 = java.awt.Cursor.getPredefinedCursor(kind);
+// if (PApplet.platform == PConstants.MACOSX && kind == PConstants.MOVE) {
+// kind = PConstants.HAND;
+// }
+//
+// java.awt.Cursor cursor0 = java.awt.Cursor.getPredefinedCursor(kind);
// Cursor cursor1 = Cursor(cursor0.,
@@ -336,9 +349,8 @@ public class PSurfaceLWJGL implements PSurface {
// Mouse.setNativeCursor(cursor1);
- cursorVisible = true;
- this.cursorType = kind;
-
+// cursorVisible = true;
+// this.cursorType = kind;
}
@Override
@@ -347,9 +359,9 @@ public class PSurfaceLWJGL implements PSurface {
IntBuffer buf = IntBuffer.wrap(jimg.getRGB(0, 0, jimg.getWidth(), jimg.getHeight(),
null, 0, jimg.getWidth()));
try {
- Cursor cursor = new Cursor(jimg.getWidth(), jimg.getHeight(),
+ currentCursor = new Cursor(jimg.getWidth(), jimg.getHeight(),
hotspotX, hotspotY, 1, buf, null);
- Mouse.setNativeCursor(cursor);
+ Mouse.setNativeCursor(currentCursor);
cursorVisible = true;
} catch (LWJGLException e) {
// TODO Auto-generated catch block
@@ -359,10 +371,18 @@ public class PSurfaceLWJGL implements PSurface {
@Override
public void showCursor() {
-// if (!cursorVisible) {
+ if (!cursorVisible) {
+// setCursor(cursorType);
// cursorVisible = true;
// Mouse.setCursor(Cursor.getPredefinedCursor(cursorType));
-// }
+ try {
+ Mouse.setNativeCursor(currentCursor);
+ cursorVisible = true;
+ } catch (LWJGLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
}
@Override
@@ -426,6 +446,8 @@ public class PSurfaceLWJGL implements PSurface {
mousePoller = new MousePoller(sketch);
mousePoller.start();
+ System.err.println(Mouse.getNativeCursor());
+
long beforeTime = System.nanoTime();
long overSleepTime = 0L;
@@ -551,6 +573,12 @@ public class PSurfaceLWJGL implements PSurface {
KeyPoller(PApplet parent) {
this.parent = parent;
stopRequested = false;
+ try {
+ Keyboard.create();
+ } catch (LWJGLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
@Override
@@ -642,6 +670,13 @@ public class PSurfaceLWJGL implements PSurface {
MousePoller(PApplet parent) {
this.parent = parent;
stopRequested = false;
+ try {
+ Mouse.create();
+// Mouse.setNativeCursor(null);
+ } catch (LWJGLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
}
@Override