简体   繁体   中英

Java repaint() is not working in jPanel class

I want to repaint my jPanel everytime I call the method called change() . In this method I'm just changing my boolean variable draw and I call this.repaint() . To paint on panel works but if I click the button the line is still there but the line should be gone. After I call repaint() I can't reach the paintComponent() method. Why is the method repaint() not working properly?

Here is my code from the panel class:

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();

    }

}

Edit, this is how I access the method change() :

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

    testPanel testPanel = new testPanel();
    testPanel.change();

}       

Edit, how I add the jPanel to my jFrame:

private void initComponents() {

    jPanel1 = new testPanel();
    jButton1 = new javax.swing.JButton();
...

From the given edits:

in your jButton1ActionPerformed method. Instead of creating a new testPanel each time you click the button rather make use of the variable and invoke change on the instance of testPanel that is actually shown in your JFrame .

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

here is an example how it would work:

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();
    }
} 

Works:

    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);



}

Or the funnier example with smiley face:

    /*
 * 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);

    }

}

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