Search code examples
javaswingjframepaintcomponentjcomponent

add different jcomponents to jframe in java


I want to draw some different JComponents in one JPanel. I create some JComponents with different paint methods. Then create the objects in the main and put them to the JFrame. My problem is, that only the last Object is painted in the Window.

How can I put different JComponents in the window, without remove or repaint the old ones?

(Model2 works like Model1, but the paintComponent is a little bit different)

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GuiModel{  
    public static void main(String[] args){         
        JFrame frame = new JFrame();        
        frame.setSize(600, 600);
        frame.setLocation(150, 150);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);                 

        frame.getContentPane().add(new Model1(0,0));
        frame.getContentPane().add(new Model2(25,37,true));             

    }
}
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;    
public class Model1 extends JComponent {
    private int xPos, yPos;


    Model1 (int x, int y){
        this.xPos = x;
        this.yPos = y;
    }

    @Override
    protected void paintComponent(Graphics g) {     
        g.setColor(Color.BLACK);
        g.drawOval(xPos, yPos, 5, 5);                   
    }
}

Solution

  • When doing custom painting:

    1. You need to override the getPreferredSize() method of your component to return the size of the component so a layout manager can display the component. Right now the size of your components are (0, 0) so there is nothing to paint.

    2. The painting of a component is done from (0, 0), not (x, y). Then if you position the component at a specific point on the panel you use setLocation(x, y) to tell Swing where to painting the component.

    3. If you want to paint the component at a random position then you also need to use a null layout on the panel and you must also set the size of the component. To set the size of the component you would use setSize( getPreferredSize()) in your constructor.

    So your Model1 class would look something like:

    public class Model1 extends JComponent {
        //private int xPos, yPos;
    
        Model1 (int x, int y){
            //this.xPos = x;
            //this.yPos = y;
            setLocation(x, y);
            setSize( getPreferredSize() );
        }
    
        @Override
        public Dimension getPreferredSize()
        {
            return new Dimension(5, 5);
        }
        @Override
        protected void paintComponent(Graphics g) {     
            g.setColor(Color.BLACK);
            //g.drawOval(xPos, yPos, 5, 5);                   
            g.drawOval(0, 0, 5, 5);                   
        }
    }