3535import java .awt .GraphicsConfiguration ;
3636import java .awt .GraphicsDevice ;
3737import java .awt .GraphicsEnvironment ;
38+ import java .awt .Image ;
39+ import java .awt .MediaTracker ;
3840import java .awt .Rectangle ;
41+ import java .awt .Toolkit ;
3942import java .awt .event .InputEvent ;
4043import java .awt .event .MouseWheelEvent ;
4144import java .awt .geom .Rectangle2D ;
4851import java .util .regex .*;
4952import java .util .zip .*;
5053
54+ // used by loadImage() functions
5155import javax .imageio .ImageIO ;
56+ import javax .swing .ImageIcon ;
57+
5258import javax .swing .JFrame ;
5359import javax .swing .JFileChooser ;
5460import javax .swing .filechooser .FileSystemView ;
@@ -170,16 +176,6 @@ public class PApplet implements PConstants {
170176 static public final int DEFAULT_WIDTH = 100 ;
171177 static public final int DEFAULT_HEIGHT = 100 ;
172178
173- /**
174- * Minimum dimensions for the window holding an applet. This varies between
175- * platforms, Mac OS X 10.3 (confirmed with 10.7 and Java 6) can do any
176- * height but requires at least 128 pixels width. Windows XP has another
177- * set of limitations. And for all I know, Linux probably allows window
178- * sizes to be negative numbers.
179- */
180- static public final int MIN_WINDOW_WIDTH = 128 ;
181- static public final int MIN_WINDOW_HEIGHT = 128 ;
182-
183179// /**
184180// * Exception thrown when size() is called the first time.
185181// * <p>
@@ -700,7 +696,7 @@ public class PApplet implements PConstants {
700696 public Frame frame ;
701697
702698
703- private Frame getFrame () {
699+ public Frame getFrame () {
704700 return frame ;
705701 }
706702
@@ -728,21 +724,22 @@ public void init() {
728724
729725 // this will be cleared by draw() if it is not overridden
730726 looping = true ;
731- redraw = true ; // draw this guy once
727+ redraw = true ; // draw this guy at least once
732728 firstMouse = true ;
733729
734730 // Removed in 2.1.2, brought back for 2.1.3. Usually sketchPath is set
735- // inside runSketch(), but if this sketch takes care of calls to init()
736- // and setup () itself (i.e. it's in a larger Java application), it'll
737- // still need to be set here so that fonts, etc can be retrieved .
731+ // inside runSketch(), but if this sketch takes care of calls to init()
732+ // when PApplet.main () is not used (i.e. it's in a Java application).
733+ // THe path needs to be set here so that loadXxxx() functions work .
738734 if (sketchPath == null ) {
739735 sketchPath = calcSketchPath ();
740736 }
741737
742- // Figure out the available display width and height.
743- // No major problem if this fails, we have to try again anyway in
744- // handleDraw() on the first (== 0) frame.
745- checkDisplaySize ();
738+ // set during Surface.initFrame()
739+ // // Figure out the available display width and height.
740+ // // No major problem if this fails, we have to try again anyway in
741+ // // handleDraw() on the first (== 0) frame.
742+ // checkDisplaySize();
746743
747744 // Set the default size, until the user specifies otherwise
748745 int w = sketchWidth ();
@@ -757,6 +754,7 @@ public void init() {
757754 width = g .width ;
758755 height = g .height ;
759756
757+ // prior to 3a5, thread was started here
760758 }
761759
762760
@@ -1423,7 +1421,8 @@ protected void resizeRenderer(int newWidth, int newHeight) {
14231421 * @see PApplet#height
14241422 */
14251423 public void size (int w , int h ) {
1426- size (w , h , JAVA2D , null );
1424+ //size(w, h, JAVA2D, null);
1425+ size (w , h , sketchRenderer (), null );
14271426 }
14281427
14291428 /**
@@ -1452,11 +1451,14 @@ public void run() {
14521451
14531452 String currentRenderer = g .getClass ().getName ();
14541453 if (currentRenderer .equals (renderer )) {
1455- // Avoid infinite loop of throwing exception to reset renderer
1456- resizeRenderer (w , h );
1457- //redraw(); // will only be called insize draw()
1458-
1459- } else { // renderer is being changed
1454+ // // Avoid infinite loop of throwing exception to reset renderer
1455+ // resizeRenderer(w, h);
1456+ surface .setSize (w , h );
1457+
1458+ } else { // renderer change attempted
1459+ // no longer kosher with 3.0a5
1460+ throw new RuntimeException ("Y'all need to implement sketchRenderer()" );
1461+ /*
14601462 // otherwise ok to fall through and create renderer below
14611463 // the renderer is changing, so need to create a new object
14621464 g = makeGraphics(w, h, renderer, path, true);
@@ -1474,6 +1476,7 @@ public void run() {
14741476 // this is for opengl, which needs a valid, properly sized
14751477 // display before calling anything inside setup().
14761478 throw new RendererChangeException();
1479+ */
14771480 }
14781481 }
14791482
@@ -3109,25 +3112,12 @@ public String insertFrame(String what) {
31093112 //
31103113
31113114
3112- int cursorType = ARROW ; // cursor type
3113- boolean cursorVisible = true ; // cursor visibility flag
3114- // PImage invisibleCursor;
3115- Cursor invisibleCursor ;
3116-
3117-
31183115 /**
31193116 * Set the cursor type
31203117 * @param kind either ARROW, CROSS, HAND, MOVE, TEXT, or WAIT
31213118 */
31223119 public void cursor (int kind ) {
3123- // Swap the HAND cursor because MOVE doesn't seem to be available on OS X
3124- // https://github.com/processing/processing/issues/2358
3125- if (platform == MACOSX && kind == MOVE ) {
3126- kind = HAND ;
3127- }
3128- setCursor (Cursor .getPredefinedCursor (kind ));
3129- cursorVisible = true ;
3130- this .cursorType = kind ;
3120+ surface .setCursor (kind );
31313121 }
31323122
31333123
@@ -3169,17 +3159,7 @@ public void cursor(PImage img) {
31693159 * @param y the vertical active spot of the cursor
31703160 */
31713161 public void cursor (PImage img , int x , int y ) {
3172- // don't set this as cursor type, instead use cursor_type
3173- // to save the last cursor used in case cursor() is called
3174- //cursor_type = Cursor.CUSTOM_CURSOR;
3175- Image jimage =
3176- createImage (new MemoryImageSource (img .width , img .height ,
3177- img .pixels , 0 , img .width ));
3178- Point hotspot = new Point (x , y );
3179- Toolkit tk = Toolkit .getDefaultToolkit ();
3180- Cursor cursor = tk .createCustomCursor (jimage , hotspot , "Custom Cursor" );
3181- setCursor (cursor );
3182- cursorVisible = true ;
3162+ surface .setCursor (img , x , y );
31833163 }
31843164
31853165
@@ -3188,14 +3168,7 @@ public void cursor(PImage img, int x, int y) {
31883168 * Notice that the program remembers the last set cursor type
31893169 */
31903170 public void cursor () {
3191- // maybe should always set here? seems dangerous, since
3192- // it's likely that java will set the cursor to something
3193- // else on its own, and the applet will be stuck b/c bagel
3194- // thinks that the cursor is set to one particular thing
3195- if (!cursorVisible ) {
3196- cursorVisible = true ;
3197- setCursor (Cursor .getPredefinedCursor (cursorType ));
3198- }
3171+ surface .showCursor ();
31993172 }
32003173
32013174
@@ -3214,20 +3187,7 @@ public void cursor() {
32143187 * @usage Application
32153188 */
32163189 public void noCursor () {
3217- // in 0216, just re-hide it?
3218- // if (!cursorVisible) return; // don't hide if already hidden.
3219-
3220- if (invisibleCursor == null ) {
3221- BufferedImage cursorImg =
3222- new BufferedImage (16 , 16 , BufferedImage .TYPE_INT_ARGB );
3223- invisibleCursor =
3224- getToolkit ().createCustomCursor (cursorImg , new Point (8 , 8 ), "blank" );
3225- }
3226- // was formerly 16x16, but the 0x0 was added by jdf as a fix
3227- // for macosx, which wasn't honoring the invisible cursor
3228- // cursor(invisibleCursor, 8, 8);
3229- setCursor (invisibleCursor );
3230- cursorVisible = false ;
3190+ surface .hideCursor ();
32313191 }
32323192
32333193
@@ -4660,8 +4620,12 @@ public PImage loadImage(String filename, String extension) { //, Object params)
46604620 if (bytes == null ) {
46614621 return null ;
46624622 } else {
4663- Image awtImage = Toolkit .getDefaultToolkit ().createImage (bytes );
4664- PImage image = loadImageMT (awtImage );
4623+ //Image awtImage = Toolkit.getDefaultToolkit().createImage(bytes);
4624+ //PImage image = loadImageMT(awtImage);
4625+ Image awtImage = new ImageIcon (bytes ).getImage ();
4626+ PImage image = new PImage (awtImage );
4627+ image .parent = this ;
4628+
46654629 if (image .width == -1 ) {
46664630 System .err .println ("The file " + filename +
46674631 " contains bad image data, or may not be an image." );
@@ -4803,23 +4767,24 @@ public void run() {
48034767 }
48044768
48054769
4806- /**
4807- * Load an AWT image synchronously by setting up a MediaTracker for
4808- * a single image, and blocking until it has loaded.
4809- */
4810- protected PImage loadImageMT (Image awtImage ) {
4811- MediaTracker tracker = new MediaTracker (this );
4812- tracker .addImage (awtImage , 0 );
4813- try {
4814- tracker .waitForAll ();
4815- } catch (InterruptedException e ) {
4816- //e.printStackTrace(); // non-fatal, right?
4817- }
4818-
4819- PImage image = new PImage (awtImage );
4820- image .parent = this ;
4821- return image ;
4822- }
4770+ // done internally by ImageIcon
4771+ // /**
4772+ // * Load an AWT image synchronously by setting up a MediaTracker for
4773+ // * a single image, and blocking until it has loaded.
4774+ // */
4775+ // protected PImage loadImageMT(Image awtImage) {
4776+ // MediaTracker tracker = new MediaTracker(this);
4777+ // tracker.addImage(awtImage, 0);
4778+ // try {
4779+ // tracker.waitForAll();
4780+ // } catch (InterruptedException e) {
4781+ // //e.printStackTrace(); // non-fatal, right?
4782+ // }
4783+ //
4784+ // PImage image = new PImage(awtImage);
4785+ // image.parent = this;
4786+ // return image;
4787+ // }
48234788
48244789
48254790 /**
@@ -9196,8 +9161,11 @@ static public void main(final String mainClass, final String[] passedArgs) {
91969161
91979162
91989163 static public void runSketch (final String args [], final PApplet constructedApplet ) {
9199- // Doesn't seem to do much to help avoid flicker
9164+ // Supposed to help with flicker, but no effect on OS X.
9165+ // TODO IIRC this helped on Windows, but need to double check.
92009166 System .setProperty ("sun.awt.noerasebackground" , "true" );
9167+ // Call validate() while resize events are in progress
9168+ Toolkit .getDefaultToolkit ().setDynamicLayout (true );
92019169
92029170 if (args .length < 1 ) {
92039171 System .err .println ("Usage: PApplet <appletname>" );
@@ -9305,7 +9273,6 @@ static public void runSketch(final String args[], final PApplet constructedApple
93059273 PSurface surface = (PSurface ) surfaceMethod .invoke (null , new Object [] { });
93069274
93079275 // A handful of things that need to be set before init/start.
9308- // applet.frame = frame;
93099276 applet .sketchPath = folder ;
93109277 // If the applet doesn't call for full screen, but the command line does,
93119278 // enable it. Conversely, if the command line does not, don't disable it.
@@ -9316,13 +9283,19 @@ static public void runSketch(final String args[], final PApplet constructedApple
93169283 applet .args = PApplet .subset (args , argIndex + 1 );
93179284 applet .external = external ;
93189285
9319- //frame.setTitle(name);
9286+ // For backwards compatability, initFrame() returns an AWT Frame object,
9287+ // whether or not one is actually used. There's lots of code that uses
9288+ // frame.setTitle() and frame.setResizable() out there...
93209289 Frame frame =
9321- surface .initFrame (applet .sketchWidth (), applet .sketchHeight (),
9322- backgroundColor ,
9290+ surface .initFrame (applet , backgroundColor ,
93239291 displayIndex , present , spanDisplays );
9292+ applet .frame = frame ;
9293+ frame .setTitle (name );
93249294
93259295 applet .init ();
9296+ // TODO this used to be inside init()... does it need to stay there for
9297+ // other external things like Python or embedding in Java apps?
9298+ surface .startThread ();
93269299// applet.start();
93279300
93289301 // Wait until the applet has figured out its width.
@@ -9340,10 +9313,28 @@ static public void runSketch(final String args[], final PApplet constructedApple
93409313 }
93419314
93429315 if (present ) {
9343- surface .placeFullScreen ();
9316+ //surface.placeFullScreen(hideStop);
9317+ if (hideStop ) {
9318+ stopColor = null ; // they'll get the hint
9319+ }
9320+ surface .placePresent (stopColor );
93449321 } else {
93459322 surface .placeWindow ();
93469323 }
9324+ // not always running externally when in present mode
9325+ if (external ) {
9326+ surface .setupExternalMessages ();
9327+ }
9328+ }
9329+
9330+
9331+ /** Convenience method, should only be called by PSurface subclasses. */
9332+ static public void hideMenuBar () {
9333+ if (PApplet .platform == PConstants .MACOSX ) {
9334+ // Call some native code to remove the menu bar on OS X. Not necessary
9335+ // on Linux and Windows, who are happy to make full screen windows.
9336+ japplemenubar .JAppleMenuBar .hide ();
9337+ }
93479338 }
93489339
93499340
@@ -9629,6 +9620,11 @@ public void updatePixels(int x1, int y1, int x2, int y2) {
96299620 // public functions for processing.core
96309621
96319622
9623+ static public PSurface createSurface () {
9624+ return PGraphics .createSurface ();
9625+ }
9626+
9627+
96329628 /**
96339629 * Store data of some kind for the renderer that requires extra metadata of
96349630 * some kind. Usually this is a renderer-specific representation of the
0 commit comments