Loading...
Logo
Processing Forum
Hi,

     I am trying to draw a picture in the "setup" method of a PApplet and then add (or embed) the PApplet into a JFrame. I have used "noLoop" in the last line of "setup" and have not used the "draw" method (I leave it blank). I have used the same size for the PApplet and the JFrame. However, when the JFrame is displayed, only a blank picture is shown on the PApplet's drawing area. The drawing area keeps blank until I perform an initial mouse click on this area. The drawing area then shows the blue rectangle correctly (but just after an initial mouse click).

The code snippet of the PApplet's program (in Java) is shown below :

    public void setup() {
        size(500, 500, P2D);
        drawImpl();
        // do something else not related to drawing
        noLoop();
    }

    public void drawImpl()  {
        stroke(50);
        fill(0,0,255);
        translate(0, 0);
        rect(0,0,30,30);
    }

     It seems that the blue rectangle is drawn normally in the PApplet's drawing area but Java has just not painted the PApplet's drawing area initially.

     Is there any way that I can put some Java codes into the PApplet's program or the JFrame's program to trigger the initial painting of the drawing area of the PApplet ?

     Thanks for any suggestion.

Regards
Lawrence



Replies(8)

It would help if you could post the part of your code where you initialize your PApplet and add it to the JFrame. After initializing, init() has to be invoked to begin running it.
Hi phi.lho and All,

     JFrame.pack() helps, but no always. If the JFrame's size and the PApplet's size is the same or nearly the same, then the pack() method seems could correctly repaint / refresh the PApplet's drawing area. However, if the PApplet's size is much smaller than the JFrame's size, e.g. PApplet's size is 100x100 while JFrame's size is 500x500, then the PApplet's drawing area would frequently not being displayed / refreshed correctly (just see a blank picture).

     Here I list my modified PApplet's and JFrame's code for your reference :

----------
package mytest.papplet_in_java_frame;

import processing.core.*;

public class Embedded_Demo extends PApplet {
    public boolean ok = false;

    public void setup() {
        size(100, 100, P2D);
        drawImpl();
        // Indicator to external program to show that the drawing process has finished.
        ok = true;
        noLoop();
    }
    public void draw() {
//        drawImpl();
    }
    public void drawImpl()  {
        stroke(50);
        fill(0,0,255);
        translate(0, 0);
        rect(0,0,30,30);
    }
//    public void mousePressed() {
//        loop();
//    }
//    public void mouseReleased() {
//        noLoop();
//    }
}
----------
package mytest.papplet_in_java_frame;

import java.awt.*;
import javax.swing.JFrame;

public class ExampleJFrame_Demo extends JFrame {
    Embedded_Demo embed;

    public ExampleJFrame_Demo() {
        super("Embedded PApplet");
        setLayout(new BorderLayout());
        embed = new Embedded_Demo();
        embed.init();
       
        // *** Because PApplet runs with its own thread, so here we must
        //        wait for its thread to finish processing its graphics.
        while (embed.ok == false )  {
            System.out.println("PApplet is not ready !");
        }
        System.out.println("It's now ready");
       
        // The embedded PApplet should be added to the JFrame after it is
        //   fully initialized.
        add(embed, BorderLayout.CENTER);
    }
    public static void main(String[] args) throws Exception {
        ExampleJFrame_Demo myFrame = new ExampleJFrame_Demo();
        myFrame.setResizable(true);
        myFrame.setSize(500,500);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        myFrame.pack();

        myFrame.setVisible(true);
    }
}
----------

     As PApplet runs on its own thread, it seems that, in the JFrame's thread,  it is difficult to know when the PApplet is fully initialized. I have used the "embed.ok" boolean flag as a primitive mean to monitor the PApplet's initialization for the time when the PApplet has finished drawing the static picture in its "setup" method. However, I am not sure that such monitoring is accurate or not, or there are better means for such monitoring.

     Thanks for all the suggestions. Hope to have a solution for this problem.

Regards
Lawrence



Hi manindra29 and All,

     My PApplet and JFrame programs are listed below :

----------
package mytest.papplet_in_java_frame;

import processing.core.*;

public class Embedded_Demo extends PApplet {
    public boolean ok = false;

    public void setup() {
        size(500, 500, P2D);
        drawImpl();
        // Indicator to external program to show that the drawing process has finished.
        ok = true;
        noLoop();
    }
    public void draw() {
        drawImpl();
    }
    public void drawImpl()  {
        stroke(50);
        fill(0,0,255);
        translate(0, 0);
        rect(0,0,30,30);
    }
    public void mousePressed() {
        loop();
    }
    public void mouseReleased() {
        noLoop();
    }
}
----------
package mytest.papplet_in_java_frame;

import java.awt.*;
import javax.swing.JFrame;

public class ExampleJFrame_Demo extends JFrame {
    Embedded_Demo embed;

    public ExampleJFrame_Demo() {
        super("Embedded PApplet");
        setLayout(new BorderLayout());
        embed = new Embedded_Demo();
        embed.init();
       
        // *** Because PApplet runs with its own thread, so here we must
        //        wait for its thread to finish processing its graphics.
        while (embed.ok == false )  {
            System.out.println("PApplet is not ready !");
        }
        System.out.println("It's now ready");
       
        // The embedded PApplet should be added to the JFrame after it is
        //   fully initialized.
        add(embed, BorderLayout.CENTER);
    }
    public static void main(String[] args) throws Exception {
        ExampleJFrame_Demo myFrame = new ExampleJFrame_Demo();
        myFrame.setResizable(true);
        myFrame.setSize(500,500);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setVisible(true);
    }
}
----------

     I am sorry that I have made a mistake in my previous post. As I have defined the "mousePressed()" method with the "loop()" command in the "Embedded_Demo" class, so I have actually drawn my picture when I make a mouse click ! (There may be nothing to concern with Java GUI painting)

     However, what I really wonder is that if I delete the "mousePressed()" and "mouseReleased()" method in the "Embedded_Demo" class, I could NOT see any picture (only a blank picture) in the drawing area of the PApplet, even when I make mouse clicks on it. I suppose that I have drawn the picture once in the "setup()" method of the "Embedded_Demo" class, but that picture is lost (or not being displayed / refreshed) when the PApplet is added (embedded) into a JFrame.

     In the "ExampleJFrame_Demo" class, I have inserted codes to init the PApplet and wait for it to be ready. But I could still not able to display the statically drawn picture in the PApplet.

     Is there any way that I could temporarily by-pass the PApplet's "draw" method and just use its "setup" method to draw a static picture that could be embedded and displayed in a JFrame ? Or is there a good approach that I could use PApplet to draw a static picture and display it in a JFrame ?

     Thanks for your suggestions.

Regards
Lawrence



Random suggestion: put the drawing code in draw(), and add the noLoop() at the end of draw().
Hi phi.lho and All,

     When the drawing code is put in draw() and noLoop() is added at the end of draw(), the problem is nearly the same. The PApplet's drawing area is mostly displayed with a blank picture in the runs, but sometimes with a correctly drawn blue rectangle. The PApplet's behavior is un-stable.

     I suspect that the problem is due to the fact that PApplet runs on its own thread, so the JFrame's thread may not synchronize with the PApplet's thread and therefore producing un-stable behavior.

     Is there any other suggestion. Thanks.

Regards
Lawrence

So, I tested your code, with some minor changes to check (only one file, to simplify).
For the record, I compiled it with the command javac -cp core.jar ExampleJFrame_Demo.java and ran it with java -cp .;core.jar ExampleJFrame_Demo
(on Windows 7, with Java 1.6.0_25
Each time I ran it, I saw the Processing applet, no problem like those you describe. Perhaps you have an issue with your configuration.
Copy code
  1. import java.awt.*;
  2. import javax.swing.JFrame;
  3. import processing.core.*;

  4. class Embedded_Demo extends PApplet {
  5.     public boolean ok;
  6.     public void setup() {
  7.         size(500, 500, P2D);
  8.         drawImpl();
  9.         // Indicator to external program to show that the drawing process has finished.
  10.         ok = true;
  11.         noLoop();
  12.     }

  13.     public void drawImpl()  {
  14.         stroke(50);
  15.         fill(0,0,255);
  16.         for (int i = 0; i < 10; i++) {
  17.             translate(20, 20);
  18.             rect(0,0,30,30);
  19.         }
  20.     }
  21. }

  22. public class ExampleJFrame_Demo extends JFrame {
  23.     Embedded_Demo embed;

  24.     public ExampleJFrame_Demo() {
  25.         super("Embedded PApplet");
  26.         setLayout(new BorderLayout());
  27.         embed = new Embedded_Demo();
  28.         embed.init();
  29.         add(embed, BorderLayout.CENTER);
  30.     }

  31.     public static void main(String[] args) throws Exception {
  32.         ExampleJFrame_Demo myFrame = new ExampleJFrame_Demo();
  33.         myFrame.setResizable(true);
  34.         myFrame.setSize(500,500);
  35.         myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  36.         myFrame.pack();
  37.         myFrame.setVisible(true);
  38.     }
  39.  
  40. // Canonical Swing should be started this way, in its own thread.
  41. //~     public static void main(String[] args) throws Exception {
  42. //~         javax.swing.SwingUtilities.invokeLater(new Runnable()
  43. //~         {
  44. //~             public void run()
  45. //~             {
  46. //~                 ExampleJFrame_Demo myFrame = new ExampleJFrame_Demo();
  47. //~                 myFrame.setResizable(true);
  48. //~                 myFrame.setSize(500, 500);
  49. //~                 myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  50. //~                 myFrame.pack();
  51. //~                 myFrame.setVisible(true);
  52. //~             }
  53. //~         });
  54. //~     }
  55. }

Hi phi.lho and All,

     Your version of the program works perfectly in my system.

     I notice that you have not defined the "draw()" method in the embedded PApplet. After studying the source code of
processing.core.PApplet, I find that it is equivalent to have defined the following "draw()" method :

  public void draw() {
    // if no draw method, then shut things down
    finished = true;
  }

     And your version of the program works fine with such modifications.

     Thanks a lot for your help. Glad to have discussed with you.

Regards
Lawrence