Java repaint() 在 jPanel 类中不起作用


每次

调用名为change()的方法时,我都想重新绘制我的jPanel。在这种方法中,我只是更改我的布尔变量draw并调用this.repaint().在面板上绘画是有效的,但如果我单击按钮,线条仍然存在,但线条应该消失了。拨打repaint()后,我无法联系到paintComponent()方法。为什么该方法repaint()无法正常工作?

这是我在面板类中的代码:

import java.awt.Graphics;
public class testPanel extends javax.swing.JPanel {
    public boolean draw = true;
    public testPanel() {
        initComponents();
    }
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 603, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 299, Short.MAX_VALUE)
        );
    }// </editor-fold>                        
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (draw == true) {
            g.drawLine(0, 0, 20, 35);
        }
    }
    public void change() {
        draw = !draw;
        this.repaint();
    }
}

编辑,这是我访问方法change()的方式:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    testPanel testPanel = new testPanel();
    testPanel.change();
}       

编辑,如何将 jPanel 添加到我的 jFrame:

private void initComponents() {
    jPanel1 = new testPanel();
    jButton1 = new javax.swing.JButton();
...

作品:

    public static void main(String[] args){

    TestPanel panel = new TestPanel();
    JButton button = new JButton();
    ActionListener al = new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e) {
         panel.change();
        }
    };
    button.addActionListener(al);
    JFrame frame = new JFrame();
    frame.add(panel);
    frame.add(button);
    frame.setVisible(true);
    frame.setLayout(new GridLayout(2, 1));
    frame.setSize(420, 360);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

或者笑脸的更有趣的例子:

    /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package repaintquestions;
/**
 *
 * @author peter
 */
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class TestPanel extends javax.swing.JPanel {
    public boolean draw = true;
    public TestPanel() {
        initComponents();
    }
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 603, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 299, Short.MAX_VALUE)
        );
    }// </editor-fold>                        
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (draw == true) {
            // g.drawLine(0, 0, 20, 35);
        }
        paintSmile(g, draw);
    }
    public void change() {
        draw = !draw;
        this.repaint();
    }
    public void paintSmile(Graphics g, boolean smile) {
        g.setColor(Color.black);
        g.fillRect(0, 0, 400, 400);
        g.setColor(Color.yellow);
        g.fillOval(0, 0, 400, 400);
        g.setColor(Color.black);
        g.fillOval(100, 100, 50, 50);
        g.fillOval(250, 100, 50, 50);
        g.drawArc(150, 250, 100, 100, 180, 180);
        if (smile) {
            g.drawArc(150, 250, 100, 100, 180, 180);
        } else {
            g.drawArc(150, 250, 100, 100, 0, 180);
        }
      //  repaint();
    }
    public static void main(String[] args) {
        TestPanel panel = new TestPanel();
        JButton button = new JButton();
        ActionListener al = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                panel.change();
            }
        };
        button.addActionListener(al);
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.add(button);
        frame.setVisible(true);
        frame.setLayout(new GridLayout(2, 1));
        frame.setSize(800, 800);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

从给定的编辑中:

在您的jButton1ActionPerformed方法中。与其在每次单击按钮时创建新testPanel,不如使用该变量并在JFrame中实际显示的testPanel实例上调用更改。

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 
    jPanel1.change();
}

下面是它如何工作的示例:

public class TestFrame extends JFrame{
    private testPanel panel = new testPanel(); // This is the pane with the line and that is actually visible to you.
    private JPanel underlayingPanel = new JPanel(); // This is the underlaying pane.
    public TestFrame() {
        underlayingPanel.setLayout(new BorderLayout());
        underlayingPanel.add(panel, BorderLayout.CENTER);
        //
        JButton button = new JButton("Press me");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // This is what you did initially
                //     testPanel panel = new testPanel();
                //     panel.change();
                // The method change is getting executed on the instance of testPanel that is stored inside the variable panel.
                // but the Panel that did get added onto your underlaying panel wont notice this change since it represents another instance
                // of testPanel. In order to make this panel notice the change invoke it on this specific instance
                panel.change();
            }
        });
        underlayingPanel.add(button, BorderLayout.NORTH);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(800, 800);
        this.setContentPane(underlayingPanel);
        this.setVisible(true);
    }
    public static void main(String[] args) {
        new TestFrame();
    }
} 

最新更新