Question

I have not used Swing/G2D much, so please be patient. I have the following class which is a component on my GUI (meant to be a kind of Canvas to draw on):

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

public class DrawPanel extends JComponent{
public void paintComponent(Graphics g){
    Graphics2D g2 = (Graphics2D) g;

    g2.setPaint(Color.black);
    g2.fillRect(0, 0, getWidth(), getHeight());

    BrushStroke bs = new BrushStroke();     
    add(bs);
}
}

I have been trying to add the following to the above JComponent:

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

public class BrushStroke extends JComponent{
public void paintComponent(Graphics g){
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);

    g2.setPaint(Color.red);
    g2.fillOval(0, 0, 10, 10);          
}
}

The BrushStroke does not show on the DrawPanel.

I have been searching forever for an answer, and each example I look at seems to be contradictory.

If anybody has attempted what I am, then help would be greatly appreciated. Also, if I am taking the completely wrong approach, please do say.

Was it helpful?

Solution

On the JComponent.add method, the documentation says:

Note: If a component has been added to a container that has been displayed, validate must be called on that container to display the new component. If multiple components are being added, you can improve efficiency by calling validate only once, after all the components have been added.

You should refresh your DrawPanel after adding an element to it. Watch out not to do it in the painComponent method, you will end up in an infinite recursion.

Do the following instead:

DrawPanel drawPanel = new DrawPanel();
drawPanel.add(new BrushStroke());
drawPanel.repaint();

EDIT Here is a fully working solution (extending JPanels instead of JComponent)

public static void main(String[] args){
   JFrame frame = new JFrame();
   DrawPanel drawPanel = new DrawPanel();
   drawPanel.add(new BrushStroke());
   frame.getContentPane().add(drawPanel);
   frame.pack();
   frame.setVisible(true);
}
class DrawPanel extends JPanel{
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setPaint(Color.black);
        g2.fillRect(0, 0, getWidth(), getHeight());
    }
    @Override
    public  Dimension getPreferredSize(){
        return new Dimension(100, 100);
    }
}
class BrushStroke extends JPanel{
    public void paintComponent(Graphics g){
        this.setOpaque(false);
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(Color.red);
        g2.fillOval(0, 0, 10, 10); 
    }
    @Override
    public  Dimension getPreferredSize(){
        return new Dimension(10, 10);
    }
}

The output gives the following:

enter image description here

OTHER TIPS

  1. You should never add a component to a panel in any painting method. The painting methods are invoked whenever Swing determines a component needs to be painted. Therefore you would be adding the component to the panel multiple times.

  2. When you do custom painting you are responsible for overriding the getPreferredSize() method to give the size of the component. This way the layout managers can position the components properly. If you don't do this then the preferred size is 0, so there is nothing to paint.

Read the section from the Swing tutorial on Custom Painting for more information and examples.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top