Search code examples
javaswing3dawtgraphics2d

Swing Java repaint not working using 2 jpanels


As you can see from the code I am expecting to see a rectangle on DrawingPanel but I am not sure why repaint() method is not working. Any help will be much appreciated. I also tried revalidate method but that is not working either.

Here are my Classes:

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

public class Designer extends JFrame {

static JFrame f = new Designer();

JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
DrawingPanel drawingPanel = new DrawingPanel();
PropertyPanel propertyPanel = new PropertyPanel();

 public Designer(){

    Rectangle bounds = GraphicsEnvironment
            .getLocalGraphicsEnvironment()
            .getMaximumWindowBounds();

    splitPane.setTopComponent(propertyPanel);
    splitPane.setBottomComponent(drawingPanel);

    add(splitPane, BorderLayout.CENTER);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(bounds);
    setVisible(true);

 }

 public static void main(String[] args) {
    System.out.println("App started...");
 }
}

Class for first Jpanel: PropertyPanel.Java

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

public class PropertyPanel extends JPanel {

  private DrawingPanel drawingPanel = new DrawingPanel();

  public PropertyPanel(){

    JButton addShapesBtn = new JButton("Add");

    addShapesBtn.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            drawingPanel.addRectangle();
        }
    });
    add(addShapesBtn);
  }

}

Class for second Jpanel: DrawingPanel.Java

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

public class DrawingPanel extends JPanel{

  private List<Rectangle> squares = new ArrayList<Rectangle>();


 @Override
 protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D g2 = (Graphics2D) g;

    System.out.println("painting");

    for (Rectangle rect : squares) {
        g2.draw(rect);
    }

}


  public void addRectangle() {

    Rectangle rectx = new Rectangle(10, 10, 100, 100);
    squares.add(rectx);
    repaint(); <-- this is not working
  }
}

Solution

  • Your repaint works fine. Your problem is that you're calling addRectangle() to the wrong DrawingPanel instance, not the one that is currently displayed in the GUI. To solve this, pass a reference from the displayed one to the code that needs to call the method.

    To see that this is correct, simply search this page for new DrawingPanel(). You should see this only once in your own code (and your code posted). You see it twice meaning you've created two instances of this.

    e.g., change this:

    public class PropertyPanel extends JPanel {   
        private DrawingPanel drawingPanel = new DrawingPanel();
    
        public PropertyPanel(){
    

    to this:

    public class PropertyPanel extends JPanel {    
        private DrawingPanel drawingPanel;  // don't create new
    
        public PropertyPanel(DrawingPanel drawingPanel){
            this.drawingPanel = drawingPanel;
    

    and then pass in the true DrawingPanel into this object on creation:

    DrawingPanel drawingPanel = new DrawingPanel();
    PropertyPanel propertyPanel = new PropertyPanel(drawingPanel);
    

    Better still: structure your code in a M-V-C way, and use dependency injection to make connections -- but this may be overkill for your simple GUI.