2016-01-05 2 views
0

Я хочу перерисовать мою jPanel каждый раз, когда я вызываю метод с именем change(). В этом методе я просто меняю свою логическую переменную draw, и я звоню this.repaint(). Чтобы рисовать на панели работает, но если я нажму кнопку, линия все еще там, но линия должна исчезнуть. После того, как я позвоню repaint(), я не могу достичь метода paintComponent(). Почему метод repaint() работает неправильно?Java repaint() не работает в классе jPanel

Вот мой код из класса панели:

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, это как я доступ к этому методу change():

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

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

}  

Edit, как я добавить JPanel к моей JFrame:

private void initComponents() { 

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

Additionaly использование 'перепроверить '. – SomeJavaGuy

+0

Я до сих пор не могу найти метод 'paintComponent()'. –

+0

Где вы добавляете кнопку? Вы добавили к кнопке actionListener? – SomeJavaGuy

ответ

1

Работа:

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

    } 

} 
1

Из приведенных правок:

в вашем jButton1ActionPerformed метод. Вместо того, чтобы создавать новый testPanel каждый раз, когда вы нажимаете кнопку, скорее используйте переменную и вызовите изменение в экземпляре testPanel, которое фактически показано в вашем JFrame.

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

Вы имеете в виду 'testPanel.change();'? 'jPanel1' - это просто панель, которая находится под панелью с линией на ней. –

+0

Если я пытаюсь использовать 'testPanel.change();' Я получаю сообщение об ошибке: 'нестатический метод change() не может ссылаться на статический контекст'. –

+0

@PascalAckermann, поэтому у вас есть 'testPanel' на' testPanel' на 'JFrame'?Да, это невозможно, так как «change» не является статичным, что означает, что его можно вызвать только в экземпляре 'testPanel'. Поскольку ваш edid предлагает, что 'jPanel1' является экземпляром' testPanel', это должно быть возможно (в том числе, что переменная 'jPanel1' также объявлена ​​как' testPanel'). Вам просто нужно сохранить экземпляр 'testPanel', который представляет панель с линией в переменной, и как только вы нажимаете кнопку, вы вызываете метод' change' этой переменной. – SomeJavaGuy