Swing JFrameComponents With Default AWTCanvas

The following code allows the use of Swing JFrame components with the default AWT canvas. This combination allows us to use the normal draw() function for drawing with Processing calls instead of painting into a JPanel or other Swing component. A JColor needs to be converted to int r,g,b values in order to be used with Processing calls.

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

javax.swing.JFrame frame;
java.awt.Canvas canvas;

int _wndW = 700;
int _wndH = 600;

int diameter = 200;
int r = 255;
int g = 0;
int b = 0;

void slider(int x, int y, int w, int h, int min, int max, int value) {
  JSlider slider = new JSlider(JSlider.HORIZONTAL, min, max, value);
  slider.setBounds(x, y, w, h);
  slider.setToolTipText("set diameter");
  frame.add(slider);
  // **** Action **** //
  slider.addChangeListener(new ChangeListener() {
    void stateChanged(ChangeEvent changeEvent) {
      diameter = slider.getValue();
    }
  }
  );
}

void colorBtn(int x, int y, int w, int h) {
  JButton colorBtn = new JButton("Color");
  colorBtn.setBounds(x, y, w, h);
  frame.add(colorBtn);
  // **** Action **** //
  colorBtn.addActionListener( new ActionListener() {
    void actionPerformed(ActionEvent actionEvent) {
     Color dotColor = JColorChooser.showDialog(null, "Choose color", Color.RED);
      r = dotColor.getRed();
      g = dotColor.getGreen();
      b = dotColor.getBlue();
    }
  }
  );
}

void buildWnd() {
  slider(150, 10, 300, 30, 5, 490, 200);
  colorBtn(480, 10, 80, 30);
}

void setup() {
  size(_wndW, _wndH);
  surface.setTitle("Swing JFrame Components with Default AWT Canvas");
  frame = (javax.swing.JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative()).getFrame();
  canvas = (processing.awt.PSurfaceAWT.SmoothCanvas) ((processing.awt.PSurfaceAWT)surface).getNative();
  frame.setBounds(600, 150, _wndW, _wndH); // Makes it possible to add swing components
  canvas.setBounds(0, 60, _wndW, _wndH-60); // Default canvas used for draw()
  javax.swing.SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      buildWnd(); // Builds components on EventDispatchThread
    }
  }
  );
}

void draw() {
  background(209);
  fill(color(r, g, b));
  stroke(0);
  strokeWeight(4.0);
  circle(350, 255, diameter);
}

Output:

2 Likes

Hello. @svan Using the code you provided above. if you set frame.resizable to true it hides all swing components but the circle stays. I’ve tried multiple options and examples for resizing but can’t find a solution. Thanks.:smiling_face_with_sunglasses:

Look at using a componentListener with the canvas being the component. Something like this:

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

javax.swing.JFrame frame;
java.awt.Canvas canvas;
JScrollPane txtScrlPane;

final int _wndW = 600;
final int _wndH = 400;

void setup() {
size(_wndW, _wndH);
surface.setTitle(“Swing Components with Resizable Default Canvas”);
surface.setResizable(true);
frame = (javax.swing.JFrame) ((processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative()).getFrame();
canvas = (processing.awt.PSurfaceAWT.SmoothCanvas) ((processing.awt.PSurfaceAWT)surface).getNative();
canvas.setBounds(0, 60, _wndW, _wndH - 60); // Default canvas used for draw()
frame.addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentResized(ComponentEvent e) {
JFrame tmp = (JFrame)e.getSource();
canvas.setBounds(0, 60, tmp.getWidth(), tmp.getHeight() - 60);
}
}
);
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Build components on EventDispatchThread
}
}
);
}
1 Like

Thanks that did the trick. :smiling_face_with_sunglasses: