How to make canvas with Swing?
I'm trying to make a paint editor with Java in which I have a toolbar with the objects that I would like to paste in the canvas. I'm using Swing components to make the GUI, but when I looked for the way of making the canvas, I only found the class canvas from AWT.
Is there any way to make something similar to canvas with Swing? (for example, JPanel?) I have read that using the class canvas from AWT with a GUI made with swing won't work correctly, is that true?
Solution 1:
In order to make a custom 'Canvas' in swing you usually write a subclass of a JPanel
. Then, you must overwrite the protected paintComponent(Graphics g)
method of JPanel
.
In the paint method, you can call methods on the Graphics
object to actually draw on the JPanel
.
As always, the Java Tutorials have a great reference on this to get you started.
Solution 2:
You'll probably want to make a subclass of JPanel
and implement your own way of painting components you want to draw onto the panel.
The basic approach will probably be along the line of assigning a MouseListener
to the subclass of JPanel
, then implement painting functionality.
The basic idea may be something along the line of:
class MyCanvas extends JPanel implements MouseListener
{
Image img; // Contains the image to draw on MyCanvas
public MyCanvas()
{
// Initialize img here.
this.addMouseListener(this);
}
public void paintComponent(Graphics g)
{
// Draws the image to the canvas
g.drawImage(img, 0, 0, null);
}
public void mouseClicked(MouseEvent e)
{
int x = e.getX();
int y = e.getY();
Graphics g = img.getGraphics();
g.fillOval(x, y, 3, 3);
g.dispose();
}
// ... other MouseListener methods ... //
}
The above example is incomplete (and not tested -- it definitely won't compile), but it gives an idea about how to implement a MyCanvas
class in which a user can click on and draw circles.
The img
object is used to hold the image of the canvas. The paintComponent
method is used to paint the img
object to the canvas. In the mouseClicked
method, the Graphics
object associated with img
is retrieved in order to fillOval
onto the image.
Since one the requirements is to paste images onto the canvas, it may be a good idea to hold some Image
s that you want to paste into the canvas. Perhaps something along the line of:
Image[] myImages; // Used to store images to paint to screen.
Then, in the routine to paint the image onto img
stored in MyCanvas
:
g.drawImage(myImage[INDEX_OF_DESIRED_IMAGE], 0, 0, null);
By using the drawImage
method of the Graphics
object, other Image
s can be drawn onto Image
s.
As for the question on AWT and Swing, yes, it is true that you do not want to mix components from the AWT and Swing, as they differ in the way they render GUI components. AWT is based on heavyweight components, meaning they native windowing for painting the GUI, while Swing is based on lightweight components, meaning the GUI is drawn by Java itself without using native components.
A good guide on the difference of AWT and Swing is provided in Painting in AWT and Swing article from Sun.