I am trying to show a processing 3 sketch inside a Jpanel from a swing application window. (I am using eclipse) please help!
I need the complexity and features of a swing based GUI and also want the user friendliness of processing to create visual content in my application.
I have used Kevin's very helpful answer and created a more specific question. Thanks Kevin!
I want the processing sketch to be a subclass that is called from MainGUI.java and inserted into a JPanel. The problem I am having is eclipse is saying pt.initSurface() is not visible.
Thanks again for your help.
MainGUI.java
import processing.awt.PSurfaceAWT;
import processing.awt.PSurfaceAWT.SmoothCanvas;
import processing.core.PApplet;
import processing.core.PSurface;
import processing.opengl.*;
import processing.data.*;
import processing.event.*;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import patterns.ProcessingTest;
import java.awt.BorderLayout;
import javax.swing.JButton;
public class MainGUI {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainGUI window = new MainGUI();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MainGUI() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBounds(52, 24, 110, 143);
//create your sketch
ProcessingTest pt = new ProcessingTest();
//get the PSurface from the sketch
PSurface ps = pt.initSurface();
//initialize the PSurface
ps.setSize(200, 200);
//get the SmoothCanvas that holds the PSurface
SmoothCanvas smoothCanvas = (SmoothCanvas)ps.getNative();
panel.setSize(200, 200);
//SmoothCanvas can be used as a Component
panel.add(smoothCanvas);
frame.getContentPane().add(panel);
//start your sketch
ps.startThread();
}
}
ProcessingTest.java
package patterns;
import javax.swing.JFrame;
import processing.awt.PSurfaceAWT.SmoothCanvas;
import processing.core.PApplet;
import processing.core.PSurface;
public class ProcessingTest extends PApplet{
public void settings(){
size(200, 200);
}
public void draw(){
background(0);
ellipse(mouseX, mouseY, 20, 20);
}
}
A JPanel is a subclass of JComponent class and it is an invisible component in Java. The FlowLayout is a default layout for a JPanel. We can add most of the components like buttons, text fields, labels, tables, lists, trees, etc. to a JPanel. We can also add multiple sub-panels to the main panel using the add () method of Container class.
Since there are different versions for add (), which method is used depends on the panel’s layout manager. 1. Add (Component cmp) method will be used for layout managers such as GridLayout, FlowLayout , SpringLayout, BoxLayout. jp is the object of JPanel. 2.
The JPanel class resides in the package javax.swing and it’s a subclass of the javax.swing.JComponent class. That creates a new JPanel with double enabled by default. By default, the panel has a flow layout manager.
The FlowLayout is a default layout for a JPanel. We can add most of the components like buttons, text fields, labels, tables, lists, trees, etc. to a JPanel. We can also add multiple sub-panels to the main panel using the add () method of Container class.
In Processing 2, PApplet
extended Applet
, so you could embed it in an AWT
or Swing
Component
like JPanel
.
As of Processing 3, PApplet
no longer extends Applet
, so you can no longer embed it as a Component
.
That being said, you have three options:
Option 1: Are you really sure you need to embed your Processing sketch?
Think about exactly why you need to embed your Processing sketch. Is there a way around it? You can write GUI code in Processing using one of these GUI libraries.
You could also create a separate JFrame
from Processing.
Option 2: Do you just need to launch your Processing sketch from Java?
If so, you can simply call the PApplet.main("YourSketchNameHere")
function. This will tell Processing to start up your sketch, and Processing will handle the creation of your window, calling setup()
, and starting the draw()
loop for you.
Here's a little example that can be run from eclipse:
import processing.core.PApplet;
public class ProcessingTest extends PApplet{
public void settings(){
size(200, 200);
}
public void draw(){
background(0);
ellipse(mouseX, mouseY, 20, 20);
}
public static void main(String... args){
PApplet.main("ProcessingTest");
}
}
Option 3: Are you really, really, really sure you need to embed your PApplet
?
If the first two options don't work, then you can still get to the underlying component. Processing 3 introduced a PSurface
class, and this class contains the component. To embed your sketch, you have to get its PSurface
, then you have to get the native component from the PSurface
. This isn't exactly straightforward, but it's doable:
import javax.swing.JFrame;
import processing.awt.PSurfaceAWT.SmoothCanvas;
import processing.core.PApplet;
import processing.core.PSurface;
public class ProcessingTest extends PApplet{
public void settings(){
size(200, 200);
}
public void draw(){
background(0);
ellipse(mouseX, mouseY, 20, 20);
}
public static void main(String... args){
//create your JFrame
JFrame frame = new JFrame("JFrame Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//create your sketch
ProcessingTest pt = new ProcessingTest();
//get the PSurface from the sketch
PSurface ps = pt.initSurface();
//initialize the PSurface
ps.setSize(200, 200);
//get the SmoothCanvas that holds the PSurface
SmoothCanvas smoothCanvas = (SmoothCanvas)ps.getNative();
//SmoothCanvas can be used as a Component
frame.add(smoothCanvas);
//make your JFrame visible
frame.setSize(200, 200);
frame.setVisible(true);
//start your sketch
ps.startThread();
}
}
Once you have the native component, you can treat it like you would any other Swing component.
Note that you have to know ahead of time what type of native component will be returned from the PSurface.getNative()
function. This depends on which renderer you're using. The default renderer uses SmoothCanvas
, but other renderers use other native components.
Also note that you have to inititalize and start your sketch.
You should use one of the first two options if at all possible, but if you really really need to embed your sketch, then option 3 is available.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With