Java 重新绘制时复制了JButton?

Java 重新绘制时复制了JButton?,java,swing,jpanel,jbutton,repaint,Java,Swing,Jpanel,Jbutton,Repaint,我有一个JFrame,里面有2个JPanel:一个PaintPanel(使用paint()方法)和一个ButtonPanel(使用按钮)。当我调用PaintPanel的repaint()(但单击按钮)时,ButtonPanel的按钮正在PaintPanel中绘制!它不是可点击的,它就在那里 我尝试重新创建此代码的问题: public class Main { public static void main(String[] args) { JFrame frame =

我有一个
JFrame
,里面有2个
JPanel
:一个
PaintPanel
(使用
paint()
方法)和一个
ButtonPanel
(使用按钮)。当我调用
PaintPanel
repaint()
(但单击按钮)时,
ButtonPanel
的按钮正在
PaintPanel
中绘制!它不是可点击的,它就在那里

我尝试重新创建此代码的问题:

public class Main {

    public static void main(String[] args) {
        JFrame frame = new JFrame("frame");
        frame.setSize(400,400);
        frame.setLayout(new GridLayout(2,1));
        PaintPanel paint = new PaintPanel();
        ButtonPanel buttons = new ButtonPanel(paint);
        frame.add(paint);
        frame.add(buttons);
        frame.setVisible(true);
    }
}

public class PaintPanel extends JPanel{
    public void paint(Graphics g){
        g.drawRect(10, 10, 10, 10);
    }
}

public class ButtonPanel extends JPanel implements ActionListener{

    private PaintPanel paintPanel;

    public ButtonPanel(PaintPanel paintPanel){
        this.paintPanel=paintPanel;
        JButton button = new JButton("button");
        button.addActionListener(this);
        add(button);
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        paintPanel.repaint();           
    }
}
这将重现我的问题(很抱歉,代码标记很奇怪,似乎无法正确处理)


我真的希望你们中有人知道这里发生了什么因为我不

首先,您应该重写
paintComponent()
,而不是
paint()
。这是Swing中进行面板定制的最佳实践的一部分

其次,下面是适合我的代码(我不知道为什么你的代码不适用:S):


通常,您希望使用super.paintComponent(g);作为重写的paintComponent方法中的第一行。它将清除在重新绘制特定调用中没有绘制的所有内容。paintComponent和super.paintComponent的+1@A你必须记住,图形对象是重复使用的,因此如果你不花时间确保你首先清理了它,你最终会得到意外的paint artifacts+1,用于使用
super.paintComponent()
来尊重属性。这样的渲染瑕疵通常是由于没有尊重属性而产生的。此外,“Swing程序应该重写
paintComponent()
,而不是重写
paint()
”。
public class Main {

    public static void main(String[] args) {

        JFrame frame = new JFrame("frame");
        frame.setSize(400, 400);
        // frame.setLayout(new GridLayout(2, 1));
        PaintPanel paint = new PaintPanel();
        ButtonPanel buttons = new ButtonPanel(paint);
        // frame.add(paint);
        // frame.add(buttons);
        frame.setVisible(true);

        JPanel pan = new JPanel(new BorderLayout());
        pan.add(paint);
        pan.add(buttons, BorderLayout.SOUTH);
        frame.add(pan);

    }
}

class PaintPanel extends JPanel {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(new Color(new Random().nextInt()));
        g.drawRect(10, 10, 10, 10);
    }
}

class ButtonPanel extends JPanel implements ActionListener {

    private final PaintPanel paintPanel;

    public ButtonPanel(PaintPanel paintPanel) {

        this.paintPanel = paintPanel;
        JButton button = new JButton("button");
        button.addActionListener(this);
        add(button);
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        if (getParent() != null) {
            getParent().repaint();
        }
    }
}