简体   繁体   中英

Updating a GUI panel, Java

I'm a Java GUI beginner and am having some trouble getting my panels to update the way I want them to. Basically, when a user clicks one of the buttons in my GUI the shape currently on screen should change to whatever shape corresponds to the button press. My code is below. The problem that the updated shape is being overwritten by the original shape before it can be displayed.

I'm pretty sure the problem has to do with my ButtonListeners. I added in print statements to see when the different paint methods are being called, and this is the result after one button click:

RECT RECT RECT ddd OVAL RECT

Clearly the update is happening, but is then being overwritten by the original shape! Can someone tell me why this final overwrite happening?!

I've included the FigurePanel class I use for reference.

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class miniCADFrame extends JPanel {

    private ButtonPanel buttons = new ButtonPanel();
    private CanvasPanel canvas = new CanvasPanel();

    public miniCADFrame() {
         //Constructor, creates the mother panel
         this.setLayout(new BorderLayout());
         this.add (canvas,BorderLayout.CENTER);
    }
    //******** BUTTONLISTENER************************
    private class ButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent event) {    //Paint the figure associated with the button click
                canvas.add(new FigurePanel(FigurePanel.OVAL), BorderLayout.CENTER);
                canvas.revalidate();
                canvas.repaint();
                System.out.println("ddd");

            }
    }

    private class ButtonPanel extends JPanel {

        private JButton[] Jbuttons = new JButton[11];
        //Constructor
        ButtonPanel() {

            setLayout(new GridLayout(4, 4)); 

            // Create buttons to attach to the buttons panel
            Jbuttons[0] = new JButton("Change Colour");
            Jbuttons[1] = new JButton("Up");
            Jbuttons[2] = new JButton("Text");
            Jbuttons[3] = new JButton("Left");
            Jbuttons[4] = new JButton("Enlarge");
            Jbuttons[5] = new JButton("Right");
            Jbuttons[6] = new JButton("Rectangle");
            Jbuttons[7] = new JButton("Down");
            Jbuttons[8] = new JButton("Circle");
            Jbuttons[9] = new JButton("Save");
            Jbuttons[10] = new JButton("Load");

            //Add the buttons to the buttons panel
            for (int i=0; i<11; i++) {
                Jbuttons[i].addActionListener(new ButtonListener());
                add(Jbuttons[i]);
            }
    }
    }

class CanvasPanel extends JPanel {

        //Constructor
        CanvasPanel() {
            // Create "canvas" to hold a label for the buttons panel along with the button panel itself
             this.setLayout(new BorderLayout());
             this.add(new JLabel("CONTROL PANEL"),BorderLayout.NORTH);
             this.add(buttons, BorderLayout.WEST); //add the button panel to the canvas panel

             //test
             this.add(new FigurePanel(FigurePanel.RECTANGLE), BorderLayout.CENTER);
        }
}
}

The FigurePanel class:

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

public class FigurePanel extends JPanel {

    // Define constants
     public static final int LINE = 1;
     public static final int RECTANGLE = 2;
     public static final int OVAL = 4;

     private int type;

     /** Construct a default FigurePanel */
     public FigurePanel() {
     }

     /** Construct a FigurePanel with the specified type */
     public FigurePanel(int type) {
     this.type = type;
     }

     /** Draw a figure on the panel */
     protected void paintComponent(Graphics g) {
         //Create blank canvas
         super.paintComponent(g);

         // Get the appropriate size for the figure
         int width = getWidth();//width of the component
         int height = getHeight();//height of the component

        switch (type) {
         case LINE: // Display a single line
             g.drawLine(10, 10, width - 10, height - 10);
             break;
         case RECTANGLE: // Display a rectangle
             g.drawRect((int)(0.1 * width), (int)(0.1 * height),
             (int)(0.8 * width), (int)(0.8 * height));
             break;
         case OVAL: // Display an oval
          g.drawOval((int)(0.1 * width), (int)(0.1 * height),
          (int)(0.8 * width), (int)(0.8 * height));
         }
 }
      /** Set a new figure type */
      public void setType(int type) {
      this.type = type;
      }

      /** Return figure type */
      public int getType() {
      return type;
      }

      /** Specify preferred size */
      public Dimension getPreferredSize() {
          return new Dimension(80, 80);
      }
}

Finally, here is my frame class:

import java.awt.*;

import javax.swing.*;

public class miniCAD extends JFrame {
    //Constructor for our extended frame class

    public miniCAD() { 

    //Initialize our custom frame
    miniCADFrame frame = new miniCADFrame();    

    add(frame, BorderLayout.CENTER);

    }

     /** Main method */
     public static void main(String[] args) {
     miniCAD frame = new miniCAD();
     frame.setTitle("minCAD");
     frame.setSize(1000, 1000);
     frame.setLocationRelativeTo(null); // Center the frame
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     frame.setVisible(true);
     }
 }

Thanks for the help!

I can suggest two possible reasons.

  1. Call canvas.revalidate(); before canvas.repaint(); to update layout.
  2. Check what color is used to draw the panel's content.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM