Search code examples
javaswingpaintcomponentrepaint

My repaint function is not calling my paintComponent


I have read multiple topics about why repaint does not call the paintComponent, yet I have not been able to combine those answers with my code to get it working. I have to do an assignment for school where in a GUI I give the X and Y coordinate for N trucks to be drawn, first one on X and Y and the rest randomly.

public class TruckMaker extends JPanel {
    public int y1;
    public int x1;
    public static Double circle, circle2, circle3;
    public static java.awt.geom.Rectangle2D.Double rectangle, rectangle2;
    Random random = new Random();

    public TruckMaker() {
        circle = new Ellipse2D.Double();
        circle2 = new Ellipse2D.Double();
        circle3 = new Ellipse2D.Double();
        rectangle = new Rectangle2D.Double();
        rectangle2 = new Rectangle2D.Double();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLUE);
        g2.fill(circle);
        g2.fill(rectangle);
        g2.fill(rectangle2);
        g2.fill(circle2);
        g2.fill(circle3);
        System.out.println("Paint component is being called");
    }

    public void getTrucks(int x, int y, int n) {
        boolean firstTimer = true;
        while (n > 0) {
            if (firstTimer) {
                x1 = x;
                y1 = y;
                rectangle = new Rectangle2D.Double(x1, y1, 50, 50);
                circle = new Ellipse2D.Double(x1 + 25, (y1 + 65), 25, 25);
                rectangle2 = new Rectangle2D.Double(x1 + 65, y1 - 25, 150, 75);
                circle2 = new Ellipse2D.Double(x1 + 140, (y1 + 65), 25, 25);
                circle3 = new Ellipse2D.Double(x1 + 175, (y1 + 65), 25, 25);
                n--;
                firstTimer = false;
            } else {
                x1 = (random.nextInt(750) + 1);
                y1 = y;
                rectangle = new Rectangle2D.Double(x1, y1, 50, 50);
                circle = new Ellipse2D.Double(x1 + 25, (y1 + 65), 25, 25);
                rectangle2 = new Rectangle2D.Double(x1 + 65, y1 - 25, 150, 75);
                circle2 = new Ellipse2D.Double(x1 + 140, (y1 + 65), 25, 25);
                circle3 = new Ellipse2D.Double(x1 + 175, (y1 + 65), 25, 25);
                n--;
            }
        }
        repaint();
    }
}

and here is where I call the TruckMaker

public class TruckMain {

    private TruckMaker truck;
    private TruckMain truckmain;
    private final static int FRAME_WIDTH = 750;
    private final static int FRAME_HEIGHT  = 750;
    public final static JButton startButton = new JButton("Start");
    private final static BorderLayout border = new BorderLayout();
    public final static JLabel x = new JLabel("x: ");

    public final static JLabel y = new JLabel("y: ");

    public final static JLabel n = new JLabel("n: ");
    private static JPanel controlPanel = new JPanel();

    private static JTextField textField1 = new JTextField(5);
    private static JTextField textField2 = new JTextField(5);
    private static JTextField textField3 = new JTextField(5);

    public static void main(String[] args){
        TruckMaker truck = new TruckMaker();
        TruckMain truckMain = new TruckMain();
        JFrame frame = new JFrame();
        frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
        frame.add(truck);
        frame.setLayout(border);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        controlPanel.add(x);
        controlPanel.add(textField1);
        controlPanel.add(y);
        controlPanel.add(textField2);
        controlPanel.add(n);
        controlPanel.add(textField3);
        controlPanel.add(startButton);
        startButton.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent event){
                int x1 = Integer.parseInt(textField1.getText());
                int y1 = Integer.parseInt(textField2.getText());
                int n1 = Integer.parseInt(textField3.getText());
                truck.getTrucks(x1,y1,n1);
                }
                });
        frame.add(controlPanel,BorderLayout.SOUTH);
    }
}    

Solution

  • You repaint method seems to work fine; the problem is in your main method and how you construct your frame. It seems like your TruckMaker component is not visible at all, so repaint has nothing to do. Maybe this is just a mistake in your posted code, since I can not even see your controls panel, but instead of adding the components directly to frame, you have to add them to the frame's contentPane:

    frame.getContentPane().add(truck, BorderLayout.CENTER);
    frame.getContentPane().add(controlPanel,BorderLayout.SOUTH);
    

    After this fix, both the control panel and the TruckMaker component are visible and the paintComponent method is being called.


    There's also an (unrelated) issue with the types of circle, circle2, etc. I guess this should be

    public static Ellipse2D.Double circle, circle2, circle3;