propane 3.4.2-java → 3.8.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -1
  3. data/.mvn/wrapper/MavenWrapperDownloader.java +2 -2
  4. data/.mvn/wrapper/maven-wrapper.properties +2 -2
  5. data/.travis.yml +1 -1
  6. data/CHANGELOG.md +9 -1
  7. data/Gemfile +2 -0
  8. data/README.md +7 -10
  9. data/Rakefile +10 -11
  10. data/bin/propane +3 -1
  11. data/lib/propane.rb +4 -2
  12. data/lib/propane/app.rb +5 -1
  13. data/lib/propane/creators/sketch_class.rb +7 -1
  14. data/lib/propane/creators/sketch_factory.rb +4 -2
  15. data/lib/propane/creators/sketch_writer.rb +1 -0
  16. data/lib/propane/helper_methods.rb +22 -23
  17. data/lib/propane/helpers/numeric.rb +2 -0
  18. data/lib/propane/helpers/version_error.rb +1 -0
  19. data/lib/propane/library.rb +5 -1
  20. data/lib/propane/library_loader.rb +2 -0
  21. data/lib/propane/native_folder.rb +10 -9
  22. data/lib/propane/native_loader.rb +3 -0
  23. data/lib/propane/runner.rb +20 -14
  24. data/lib/propane/version.rb +2 -1
  25. data/library/boids/boids.rb +21 -11
  26. data/library/color_group/color_group.rb +2 -0
  27. data/library/control_panel/control_panel.rb +8 -5
  28. data/library/dxf/dxf.rb +2 -0
  29. data/library/file_chooser/chooser.rb +10 -9
  30. data/library/file_chooser/file_chooser.rb +10 -9
  31. data/library/library_proxy/library_proxy.rb +2 -0
  32. data/library/net/net.rb +2 -0
  33. data/library/slider/slider.rb +23 -22
  34. data/library/vector_utils/vector_utils.rb +4 -0
  35. data/library/video_event/video_event.rb +2 -0
  36. data/pom.rb +37 -36
  37. data/pom.xml +7 -7
  38. data/propane.gemspec +13 -9
  39. data/src/main/java/japplemenubar/JAppleMenuBar.java +3 -3
  40. data/src/main/java/monkstone/ColorUtil.java +1 -3
  41. data/src/main/java/monkstone/MathToolModule.java +1 -1
  42. data/src/main/java/monkstone/PropaneLibrary.java +2 -2
  43. data/src/main/java/monkstone/fastmath/DegLutTables.java +111 -0
  44. data/src/main/java/monkstone/fastmath/Deglut.java +6 -56
  45. data/src/main/java/monkstone/filechooser/Chooser.java +1 -1
  46. data/src/main/java/monkstone/noise/Noise.java +116 -0
  47. data/src/main/java/monkstone/noise/NoiseGenerator.java +63 -0
  48. data/src/main/java/monkstone/noise/NoiseMode.java +15 -0
  49. data/src/main/java/monkstone/noise/SimplexNoise.java +137 -103
  50. data/src/main/java/monkstone/noise/ValueNoise.java +170 -0
  51. data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +1 -1
  52. data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
  53. data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +1 -1
  54. data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +1 -1
  55. data/src/main/java/monkstone/slider/SliderBar.java +1 -1
  56. data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
  57. data/src/main/java/monkstone/slider/WheelHandler.java +1 -1
  58. data/src/main/java/monkstone/vecmath/package-info.java +1 -1
  59. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +1 -1
  60. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -2
  61. data/src/main/java/monkstone/videoevent/CaptureEvent.java +1 -1
  62. data/src/main/java/monkstone/videoevent/MovieEvent.java +1 -1
  63. data/src/main/java/monkstone/videoevent/package-info.java +1 -1
  64. data/src/main/java/processing/awt/PGraphicsJava2D.java +781 -285
  65. data/src/main/java/processing/awt/PImageAWT.java +377 -0
  66. data/src/main/java/processing/awt/PShapeJava2D.java +56 -52
  67. data/src/main/java/processing/awt/PSurfaceAWT.java +308 -208
  68. data/src/main/java/processing/awt/ShimAWT.java +581 -0
  69. data/src/main/java/processing/core/PApplet.java +13142 -13883
  70. data/src/main/java/processing/core/PConstants.java +477 -447
  71. data/src/main/java/processing/core/PFont.java +914 -880
  72. data/src/main/java/processing/core/PGraphics.java +152 -136
  73. data/src/main/java/processing/core/PImage.java +275 -372
  74. data/src/main/java/processing/core/PMatrix.java +172 -159
  75. data/src/main/java/processing/core/PMatrix2D.java +478 -415
  76. data/src/main/java/processing/core/PMatrix3D.java +762 -735
  77. data/src/main/java/processing/core/PShape.java +2887 -2651
  78. data/src/main/java/processing/core/PShapeOBJ.java +97 -92
  79. data/src/main/java/processing/core/PShapeSVG.java +1705 -1490
  80. data/src/main/java/processing/core/PStyle.java +40 -37
  81. data/src/main/java/processing/core/PSurface.java +139 -97
  82. data/src/main/java/processing/core/PSurfaceNone.java +296 -218
  83. data/src/main/java/processing/core/PVector.java +995 -963
  84. data/src/main/java/processing/core/ThinkDifferent.java +12 -8
  85. data/src/main/java/processing/data/DoubleDict.java +756 -710
  86. data/src/main/java/processing/data/DoubleList.java +749 -696
  87. data/src/main/java/processing/data/FloatDict.java +748 -702
  88. data/src/main/java/processing/data/FloatList.java +751 -697
  89. data/src/main/java/processing/data/IntDict.java +720 -673
  90. data/src/main/java/processing/data/IntList.java +699 -633
  91. data/src/main/java/processing/data/JSONArray.java +931 -873
  92. data/src/main/java/processing/data/JSONObject.java +1262 -1165
  93. data/src/main/java/processing/data/JSONTokener.java +351 -341
  94. data/src/main/java/processing/data/LongDict.java +710 -663
  95. data/src/main/java/processing/data/LongList.java +701 -635
  96. data/src/main/java/processing/data/Sort.java +37 -41
  97. data/src/main/java/processing/data/StringDict.java +525 -486
  98. data/src/main/java/processing/data/StringList.java +626 -580
  99. data/src/main/java/processing/data/Table.java +3690 -3510
  100. data/src/main/java/processing/data/TableRow.java +182 -183
  101. data/src/main/java/processing/data/XML.java +957 -883
  102. data/src/main/java/processing/event/Event.java +87 -67
  103. data/src/main/java/processing/event/KeyEvent.java +48 -41
  104. data/src/main/java/processing/event/MouseEvent.java +88 -113
  105. data/src/main/java/processing/event/TouchEvent.java +10 -6
  106. data/src/main/java/processing/javafx/PGraphicsFX2D.java +20 -345
  107. data/src/main/java/processing/javafx/PSurfaceFX.java +149 -121
  108. data/src/main/java/processing/net/Client.java +20 -20
  109. data/src/main/java/processing/net/Server.java +9 -9
  110. data/src/main/java/processing/opengl/FontTexture.java +286 -266
  111. data/src/main/java/processing/opengl/FrameBuffer.java +389 -377
  112. data/src/main/java/processing/opengl/LinePath.java +132 -89
  113. data/src/main/java/processing/opengl/LineStroker.java +588 -581
  114. data/src/main/java/processing/opengl/PGL.java +660 -567
  115. data/src/main/java/processing/opengl/PGraphics2D.java +408 -315
  116. data/src/main/java/processing/opengl/PGraphics3D.java +107 -72
  117. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +12378 -12075
  118. data/src/main/java/processing/opengl/PJOGL.java +1753 -1670
  119. data/src/main/java/processing/opengl/PShader.java +369 -461
  120. data/src/main/java/processing/opengl/PShapeOpenGL.java +4678 -4580
  121. data/src/main/java/processing/opengl/PSurfaceJOGL.java +1114 -1027
  122. data/src/main/java/processing/opengl/Texture.java +1492 -1401
  123. data/src/main/java/processing/opengl/VertexBuffer.java +57 -55
  124. data/test/create_test.rb +21 -20
  125. data/test/deglut_spec_test.rb +4 -2
  126. data/test/helper_methods_test.rb +49 -20
  127. data/test/math_tool_test.rb +39 -32
  128. data/test/native_folder.rb +47 -0
  129. data/test/respond_to_test.rb +3 -2
  130. data/test/sketches/key_event.rb +2 -2
  131. data/test/sketches/library/my_library/my_library.rb +3 -0
  132. data/test/test_helper.rb +2 -0
  133. data/test/vecmath_spec_test.rb +35 -22
  134. data/vendors/Rakefile +35 -40
  135. metadata +47 -23
  136. data/library/simplex_noise/simplex_noise.rb +0 -3
  137. data/src/main/java/processing/opengl/shaders/LightVert-brcm.glsl +0 -154
  138. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +0 -154
  139. data/src/main/java/processing/opengl/shaders/TexLightVert-brcm.glsl +0 -160
  140. data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +0 -160
@@ -0,0 +1,581 @@
1
+ package processing.awt;
2
+
3
+ import java.awt.Desktop;
4
+ import java.awt.EventQueue;
5
+ import java.awt.FileDialog;
6
+ import java.awt.Frame;
7
+ import java.awt.HeadlessException;
8
+ import java.awt.Image;
9
+ import java.awt.Toolkit;
10
+ import java.awt.color.ColorSpace;
11
+ import java.awt.image.BufferedImage;
12
+ import java.io.File;
13
+ import java.io.IOException;
14
+ import java.io.InputStream;
15
+ import java.net.URI;
16
+ import java.net.URISyntaxException;
17
+
18
+ import java.awt.DisplayMode;
19
+ import java.awt.GraphicsConfiguration;
20
+ import java.awt.GraphicsDevice;
21
+ import java.awt.GraphicsEnvironment;
22
+ import java.awt.geom.AffineTransform;
23
+
24
+ import javax.imageio.ImageIO;
25
+ import javax.swing.ImageIcon;
26
+ import javax.swing.JFileChooser;
27
+ import javax.swing.UIManager;
28
+ import javax.swing.UnsupportedLookAndFeelException;
29
+
30
+ // used by desktopFile() method
31
+ import javax.swing.filechooser.FileSystemView;
32
+
33
+ import processing.core.PApplet;
34
+ import processing.core.PConstants;
35
+ import processing.core.PImage;
36
+
37
+
38
+ /**
39
+ * This class exists as an abstraction layer to remove AWT from PApplet.
40
+ * It is a staging area for AWT-specific code that's shared by the Java2D,
41
+ * JavaFX, and JOGL renderers. Once PSurfaceFX and PSurfaceJOGL have
42
+ * their own implementations, these methods will move to PSurfaceAWT.
43
+ */
44
+ public class ShimAWT implements PConstants {
45
+ /*
46
+ PGraphics graphics;
47
+ PApplet sketch;
48
+
49
+
50
+ public ShimAWT(PApplet sketch) {
51
+ this.graphics = graphics;
52
+ this.sketch = sketch;
53
+ }
54
+ */
55
+ static private ShimAWT instance;
56
+
57
+ private GraphicsDevice[] displayDevices;
58
+
59
+ private final int displayWidth;
60
+ private final int displayHeight;
61
+
62
+
63
+ /** Only needed for display functions */
64
+ static private ShimAWT getInstance() {
65
+ if (instance == null) {
66
+ instance = new ShimAWT();
67
+ }
68
+ return instance;
69
+ }
70
+
71
+
72
+ private ShimAWT() {
73
+ // Need the list of display devices to be queried already for usage below.
74
+ // https://github.com/processing/processing/issues/3295
75
+ // https://github.com/processing/processing/issues/3296
76
+ // Not doing this from a static initializer because it may cause
77
+ // PApplet to cache and the values to stick through subsequent runs.
78
+ // Instead make it a runtime thing and a local variable.
79
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
80
+ GraphicsDevice device = ge.getDefaultScreenDevice();
81
+ displayDevices = ge.getScreenDevices();
82
+
83
+ // // Default or unparsed will be -1, spanning will be 0, actual displays will
84
+ // // be numbered from 1 because it's too weird to say "display 0" in prefs.
85
+ // if (display > 0 && display <= displayDevices.length) {
86
+ // device = displayDevices[display-1];
87
+ // }
88
+ // When this was called, display will always be unset (even in 3.x),
89
+ // since this happens before settings() is called.
90
+
91
+ // Set displayWidth and displayHeight for people still using those.
92
+ DisplayMode displayMode = device.getDisplayMode();
93
+ displayWidth = displayMode.getWidth();
94
+ displayHeight = displayMode.getHeight();
95
+ }
96
+
97
+
98
+ static public int getDisplayWidth() {
99
+ return getInstance().displayWidth;
100
+ }
101
+
102
+
103
+ static public int getDisplayHeight() {
104
+ return getInstance().displayHeight;
105
+ }
106
+
107
+
108
+ static public int getDisplayCount() {
109
+ return getInstance().displayDevices.length;
110
+ }
111
+
112
+
113
+ static public int getDisplayDensity(int num) {
114
+ return getInstance().displayDensityImpl(num);
115
+ }
116
+
117
+
118
+ /*
119
+ private int displayDensityImpl() {
120
+ if (display != SPAN && (fullScreen || present)) {
121
+ return displayDensity(display);
122
+ }
123
+ // walk through all displays, use 2 if any display is 2
124
+ for (int i = 0; i < displayDevices.length; i++) {
125
+ if (displayDensity(i+1) == 2) {
126
+ return 2;
127
+ }
128
+ }
129
+ // If nobody's density is 2 then everyone is 1
130
+ return 1;
131
+ }
132
+ */
133
+
134
+
135
+ private int displayDensityImpl(int display) {
136
+ if (display > 0 && display <= displayDevices.length) {
137
+ GraphicsConfiguration graphicsConfig =
138
+ displayDevices[display - 1].getDefaultConfiguration();
139
+ AffineTransform tx = graphicsConfig.getDefaultTransform();
140
+ return (int) Math.round(tx.getScaleX());
141
+ }
142
+
143
+ System.err.println("Display " + display + " does not exist, " +
144
+ "returning 1 for displayDensity(" + display + ")");
145
+ return 1; // not the end of the world, so don't throw a RuntimeException
146
+ }
147
+
148
+
149
+ static public PImage loadImage(PApplet sketch, String filename, Object... args) {
150
+ String extension = null;
151
+ if (args != null && args.length > 0) {
152
+ // the only one that's supported for now
153
+ extension = (String) args[0];
154
+ }
155
+
156
+ if (extension == null) {
157
+ String lower = filename.toLowerCase();
158
+ int dot = filename.lastIndexOf('.');
159
+ if (dot == -1) {
160
+ extension = "unknown"; // no extension found
161
+
162
+ } else {
163
+ extension = lower.substring(dot + 1);
164
+
165
+ // check for, and strip any parameters on the url, i.e.
166
+ // filename.jpg?blah=blah&something=that
167
+ int question = extension.indexOf('?');
168
+ if (question != -1) {
169
+ extension = extension.substring(0, question);
170
+ }
171
+ }
172
+ }
173
+
174
+ // just in case. them users will try anything!
175
+ extension = extension.toLowerCase();
176
+
177
+ if (extension.equals("tga")) {
178
+ try {
179
+ InputStream input = sketch.createInput(filename);
180
+ if (input == null) return null;
181
+
182
+ PImage image = PImage.loadTGA(input);
183
+ image.parent = sketch;
184
+ return image;
185
+
186
+ } catch (IOException e) {
187
+ return null;
188
+ }
189
+ }
190
+
191
+ if (extension.equals("tif") || extension.equals("tiff")) {
192
+ InputStream input = sketch.createInput(filename);
193
+ PImage image = (input == null) ? null : PImage.loadTIFF(input);
194
+ return image;
195
+ }
196
+
197
+ // For jpeg, gif, and png, load them using createImage(),
198
+ // because the javax.imageio code was found to be much slower.
199
+ // http://dev.processing.org/bugs/show_bug.cgi?id=392
200
+ try {
201
+ if (extension.equals("jpg") || extension.equals("jpeg") ||
202
+ extension.equals("gif") || extension.equals("png") ||
203
+ extension.equals("unknown")) {
204
+ byte[] bytes = sketch.loadBytes(filename);
205
+ if (bytes == null) {
206
+ return null;
207
+ } else {
208
+ //Image awtImage = Toolkit.getDefaultToolkit().createImage(bytes);
209
+ Image awtImage = new ImageIcon(bytes).getImage();
210
+
211
+ if (awtImage instanceof BufferedImage) {
212
+ BufferedImage buffImage = (BufferedImage) awtImage;
213
+ int space = buffImage.getColorModel().getColorSpace().getType();
214
+ if (space == ColorSpace.TYPE_CMYK) {
215
+ System.err.println(filename + " is a CMYK image, " +
216
+ "only RGB images are supported.");
217
+ return null;
218
+ /*
219
+ // wishful thinking, appears to not be supported
220
+ // https://community.oracle.com/thread/1272045?start=0&tstart=0
221
+ BufferedImage destImage =
222
+ new BufferedImage(buffImage.getWidth(),
223
+ buffImage.getHeight(),
224
+ BufferedImage.TYPE_3BYTE_BGR);
225
+ ColorConvertOp op = new ColorConvertOp(null);
226
+ op.filter(buffImage, destImage);
227
+ image = new PImage(destImage);
228
+ */
229
+ }
230
+ }
231
+
232
+ PImage image = new PImageAWT(awtImage);
233
+ if (image.width == -1) {
234
+ System.err.println("The file " + filename +
235
+ " contains bad image data, or may not be an image.");
236
+ }
237
+
238
+ // if it's a .gif image, test to see if it has transparency
239
+ if (extension.equals("gif") || extension.equals("png") ||
240
+ extension.equals("unknown")) {
241
+ image.checkAlpha();
242
+ }
243
+
244
+ image.parent = sketch;
245
+ return image;
246
+ }
247
+ }
248
+ } catch (Exception e) {
249
+ // show error, but move on to the stuff below, see if it'll work
250
+
251
+ }
252
+
253
+ if (loadImageFormats == null) {
254
+ loadImageFormats = ImageIO.getReaderFormatNames();
255
+ }
256
+ if (loadImageFormats != null) {
257
+ for (String loadImageFormat : loadImageFormats) {
258
+ if (extension.equals(loadImageFormat)) {
259
+ return loadImageIO(sketch, filename);
260
+ }
261
+ }
262
+ }
263
+
264
+ // failed, could not load image after all those attempts
265
+ System.err.println("Could not find a method to load " + filename);
266
+ return null;
267
+ }
268
+
269
+
270
+ static protected String[] loadImageFormats;
271
+
272
+
273
+ /**
274
+ * Use Java 1.4 ImageIO methods to load an image.
275
+ */
276
+ static protected PImage loadImageIO(PApplet sketch, String filename) {
277
+ InputStream stream = sketch.createInput(filename);
278
+ if (stream == null) {
279
+ System.err.println("The image " + filename + " could not be found.");
280
+ return null;
281
+ }
282
+
283
+ try {
284
+ BufferedImage bi = ImageIO.read(stream);
285
+ //PImage outgoing = new PImage(bi.getWidth(), bi.getHeight());
286
+ PImage outgoing = new PImageAWT(bi);
287
+ outgoing.parent = sketch;
288
+
289
+ //bi.getRGB(0, 0, outgoing.width, outgoing.height,
290
+ // outgoing.pixels, 0, outgoing.width);
291
+
292
+ // check the alpha for this image
293
+ // was gonna call getType() on the image to see if RGB or ARGB,
294
+ // but it's not actually useful, since gif images will come through
295
+ // as TYPE_BYTE_INDEXED, which means it'll still have to check for
296
+ // the transparency. also, would have to iterate through all the other
297
+ // types and guess whether alpha was in there, so.. just gonna stick
298
+ // with the old method.
299
+ outgoing.checkAlpha();
300
+
301
+ stream.close();
302
+ // return the image
303
+ return outgoing;
304
+
305
+ } catch (IOException e) {
306
+ return null;
307
+ }
308
+ }
309
+
310
+
311
+ static public void initRun() {
312
+ // Supposed to help with flicker, but no effect on OS X.
313
+ // TODO IIRC this helped on Windows, but need to double check.
314
+ System.setProperty("sun.awt.noerasebackground", "true");
315
+
316
+ // Remove 60fps limit on the JavaFX "pulse" timer
317
+ System.setProperty("javafx.animation.fullspeed", "true");
318
+
319
+ // Catch any HeadlessException to provide more useful feedback
320
+ try {
321
+ // Call validate() while resize events are in progress
322
+ Toolkit.getDefaultToolkit().setDynamicLayout(true);
323
+ } catch (HeadlessException e) {
324
+ System.err.println("Cannot run sketch without a display. Read this for possible solutions:");
325
+ System.err.println("https://github.com/processing/processing/wiki/Running-without-a-Display");
326
+ System.exit(1);
327
+ }
328
+ }
329
+
330
+
331
+ /*
332
+ public int displayDensity() {
333
+ if (sketch.display != PConstants.SPAN && (sketch.fullScreen || sketch.present)) {
334
+ return displayDensity(sketch.display);
335
+ }
336
+ // walk through all displays, use 2 if any display is 2
337
+ for (int i = 0; i < displayDevices.length; i++) {
338
+ if (displayDensity(i+1) == 2) {
339
+ return 2;
340
+ }
341
+ }
342
+ // If nobody's density is 2 then everyone is 1
343
+ return 1;
344
+ }
345
+ */
346
+
347
+
348
+ /**
349
+ * @param display the display number to check
350
+ * (1-indexed to match the Preferences dialog box)
351
+ */
352
+ /*
353
+ public int displayDensity(int display) {
354
+ if (display > 0 && display <= displayDevices.length) {
355
+ GraphicsConfiguration graphicsConfig =
356
+ displayDevices[display - 1].getDefaultConfiguration();
357
+ AffineTransform tx = graphicsConfig.getDefaultTransform();
358
+ return (int) Math.round(tx.getScaleX());
359
+ }
360
+
361
+ System.err.println("Display " + display + " does not exist, returning ");
362
+ return 1; // not the end of the world, so don't throw a RuntimeException
363
+ }
364
+ */
365
+
366
+
367
+ static public void selectInput(String prompt, String callbackMethod,
368
+ File file, Object callbackObject) {
369
+ EventQueue.invokeLater(() -> {
370
+ selectImpl(prompt, callbackMethod, file,
371
+ callbackObject, null, FileDialog.LOAD);
372
+ });
373
+ }
374
+
375
+
376
+ /*
377
+ static public void selectOutput(String prompt, String callbackMethod,
378
+ File file, Object callbackObject, Frame parent) {
379
+ selectImpl(prompt, callbackMethod, file, callbackObject, parent, FileDialog.SAVE, null);
380
+ }
381
+
382
+
383
+ static public void selectOutput(String prompt, String callbackMethod,
384
+ File file, Object callbackObject, Frame parent,
385
+ PApplet sketch) {
386
+ selectImpl(prompt, callbackMethod, file, callbackObject, parent, FileDialog.SAVE, sketch);
387
+ }
388
+ */
389
+
390
+
391
+ static public void selectOutput(String prompt, String callbackMethod,
392
+ File file, Object callbackObject) {
393
+ EventQueue.invokeLater(() -> {
394
+ selectImpl(prompt, callbackMethod, file,
395
+ callbackObject, null, FileDialog.SAVE);
396
+ });
397
+ }
398
+
399
+
400
+ /*
401
+ // Will remove the 'sketch' parameter once we get an upstream JOGL fix
402
+ // https://github.com/processing/processing/issues/3831
403
+ static protected void selectEvent(final String prompt,
404
+ final String callbackMethod,
405
+ final File defaultSelection,
406
+ final Object callbackObject,
407
+ final Frame parentFrame,
408
+ final int mode,
409
+ final PApplet sketch) {
410
+ EventQueue.invokeLater(new Runnable() {
411
+ public void run() {
412
+ boolean hide = (sketch != null) &&
413
+ (sketch.g instanceof PGraphicsOpenGL) &&
414
+ (PApplet.platform == PConstants.WINDOWS);
415
+ if (hide) sketch.getSurface().setVisible(false);
416
+
417
+ selectImpl(prompt, callbackMethod, defaultSelection, callbackObject,
418
+ parentFrame, mode, sketch);
419
+
420
+ if (hide) sketch.getSurface().setVisible(true);
421
+ }
422
+ });
423
+ }
424
+ */
425
+
426
+
427
+ static public void selectImpl(final String prompt,
428
+ final String callbackMethod,
429
+ final File defaultSelection,
430
+ final Object callbackObject,
431
+ final Frame parentFrame,
432
+ final int mode) {
433
+ File selectedFile = null;
434
+
435
+ if (PApplet.useNativeSelect) {
436
+ FileDialog dialog = new FileDialog(parentFrame, prompt, mode);
437
+ if (defaultSelection != null) {
438
+ dialog.setDirectory(defaultSelection.getParent());
439
+ dialog.setFile(defaultSelection.getName());
440
+ }
441
+
442
+ dialog.setVisible(true);
443
+ String directory = dialog.getDirectory();
444
+ String filename = dialog.getFile();
445
+ if (filename != null) {
446
+ selectedFile = new File(directory, filename);
447
+ }
448
+
449
+ } else {
450
+ JFileChooser chooser = new JFileChooser();
451
+ chooser.setDialogTitle(prompt);
452
+ if (defaultSelection != null) {
453
+ chooser.setSelectedFile(defaultSelection);
454
+ }
455
+
456
+ int result = -1;
457
+ if (mode == FileDialog.SAVE) {
458
+ result = chooser.showSaveDialog(parentFrame);
459
+ } else if (mode == FileDialog.LOAD) {
460
+ result = chooser.showOpenDialog(parentFrame);
461
+ }
462
+ if (result == JFileChooser.APPROVE_OPTION) {
463
+ selectedFile = chooser.getSelectedFile();
464
+ }
465
+ }
466
+ PApplet.selectCallback(selectedFile, callbackMethod, callbackObject);
467
+ }
468
+
469
+
470
+ static public void selectFolder(final String prompt,
471
+ final String callbackMethod,
472
+ final File defaultSelection,
473
+ final Object callbackObject) {
474
+ EventQueue.invokeLater(() -> {
475
+ selectFolderImpl(prompt, callbackMethod, defaultSelection,
476
+ callbackObject, null);
477
+ });
478
+ }
479
+
480
+
481
+ /*
482
+ static public void selectFolder(final String prompt,
483
+ final String callbackMethod,
484
+ final File defaultSelection,
485
+ final Object callbackObject,
486
+ final Frame parentFrame) {
487
+ selectFolderEvent(prompt, callbackMethod, defaultSelection, callbackObject, parentFrame, null);
488
+ }
489
+
490
+
491
+ // Will remove the 'sketch' parameter once we get an upstream JOGL fix
492
+ // https://github.com/processing/processing/issues/3831
493
+ static public void selectFolderEvent(final String prompt,
494
+ final String callbackMethod,
495
+ final File defaultSelection,
496
+ final Object callbackObject,
497
+ final Frame parentFrame,
498
+ final PApplet sketch) {
499
+ EventQueue.invokeLater(() -> {
500
+ selectFolderImpl(prompt, callbackMethod, defaultSelection,
501
+ callbackObject, parentFrame, sketch);
502
+ });
503
+ }
504
+ */
505
+
506
+
507
+ static public void selectFolderImpl(final String prompt,
508
+ final String callbackMethod,
509
+ final File defaultSelection,
510
+ final Object callbackObject,
511
+ final Frame parentFrame) {
512
+ File selectedFile = null;
513
+ if (PApplet.platform == PConstants.MACOS && PApplet.useNativeSelect) {
514
+ FileDialog fileDialog =
515
+ new FileDialog(parentFrame, prompt, FileDialog.LOAD);
516
+ if (defaultSelection != null) {
517
+ fileDialog.setDirectory(defaultSelection.getAbsolutePath());
518
+ }
519
+ System.setProperty("apple.awt.fileDialogForDirectories", "true");
520
+ fileDialog.setVisible(true);
521
+ System.setProperty("apple.awt.fileDialogForDirectories", "false");
522
+ String filename = fileDialog.getFile();
523
+ if (filename != null) {
524
+ selectedFile = new File(fileDialog.getDirectory(), fileDialog.getFile());
525
+ }
526
+ } else {
527
+ checkLookAndFeel();
528
+ JFileChooser fileChooser = new JFileChooser();
529
+ fileChooser.setDialogTitle(prompt);
530
+ fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
531
+ if (defaultSelection != null) {
532
+ fileChooser.setCurrentDirectory(defaultSelection);
533
+ }
534
+
535
+ int result = fileChooser.showOpenDialog(parentFrame);
536
+ if (result == JFileChooser.APPROVE_OPTION) {
537
+ selectedFile = fileChooser.getSelectedFile();
538
+ }
539
+ }
540
+ PApplet.selectCallback(selectedFile, callbackMethod, callbackObject);
541
+ }
542
+
543
+
544
+ static private boolean lookAndFeelCheck;
545
+
546
+ /**
547
+ * Initialize the Look & Feel if it hasn't been already.
548
+ * Call this before using any Swing-related code in PApplet methods.
549
+ */
550
+ static private void checkLookAndFeel() {
551
+ if (!lookAndFeelCheck) {
552
+ if (PApplet.platform == PConstants.WINDOWS) {
553
+ // Windows is defaulting to Metal or something else awful.
554
+ // Which also is not scaled properly with HiDPI interfaces.
555
+ try {
556
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
557
+ } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) { }
558
+ }
559
+ lookAndFeelCheck = true;
560
+ }
561
+ }
562
+
563
+
564
+ // TODO maybe call this with reflection from inside PApplet?
565
+ // longer term, develop a more general method for other platforms
566
+ static public File getWindowsDesktop() {
567
+ return FileSystemView.getFileSystemView().getHomeDirectory();
568
+ }
569
+
570
+
571
+ static public boolean openLink(String url) {
572
+ try {
573
+ if (Desktop.isDesktopSupported()) {
574
+ Desktop.getDesktop().browse(new URI(url));
575
+ return true;
576
+ }
577
+ } catch (IOException | URISyntaxException e) {
578
+ }
579
+ return false;
580
+ }
581
+ }