Java 点击按钮后 JPanel 似乎没有重新绘制

Java JPanel seems to not repaint after button click

我正在尝试使用一个按钮从根本上将一个 JPanel 替换为另一个 JPanel。但是,当我 运行 下面的代码并单击 window 中的按钮时,它会显示一个空白屏幕而不是 "Instructions"。正如其他人在其他论坛中所述,我在 removeAll() 方法之后调用了 revalidate()repaint(),以及我对 window 所做的任何操作(即调整大小、最小化等) .) 不起作用。

我确定我错过了一些愚蠢的东西,但我 运行 没有想法。

谢谢。

public class TitlePage extends JPanel{

private static final long serialVersionUID = 0;
private JButton a;
//The code works without me needing to define an extra JPanel instance variable.

public TitlePage(){

    setLayout(null); 
    setBackground(Color.WHITE);

    JLabel title = new JLabel("2009 AP(R) Computer Science A Diagnostic Exam");
    title.setBounds(175,100,650,50);
    title.setFont(new Font("Times New Roman", Font.PLAIN, 30));
    setVisible(true);
    add(title);


    a = new JButton("Start Diagnostic");
    a.setBounds(400, 300, 200, 50);
    a.setForeground(Color.BLUE);
    a.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            removeAll();
            revalidate();
            repaint();
            add(new Instructions());
            revalidate();
            repaint();

        }
    });
    setVisible(true);
    add(a);

    JLabel disclaimer = new JLabel("*AP(R) is a registered trademark of the College Board, which was not involved in the production of, and does not endorse, this product.");
    disclaimer.setBounds(150,650,750,50);
    disclaimer.setFont(new Font("Times New Roman", Font.PLAIN, 12));
    setVisible(true);
    add(disclaimer);

}

}

说明 class 包含一个简单的 JLabel。

public class Instructions extends JPanel {

private static final long serialVersionUID = 0;

public Instructions(){

    JLabel instr = new JLabel("Instructions");
    instr.setBounds(0,0,100,50);
    instr.setForeground(Color.BLACK);
    instr.setFont(new Font("Times New Roman", Font.PLAIN, 30));
    setVisible(true);
    add(instr);

}
}

这取决于您要做什么。在我看来,您有两种选择。 您可以更改 JFrame 中的面板。您可以非常简单地执行以下操作:

jframe.remove(old_panel)
jframe.add(newPanel);
jframe.revalidate();
jframe.repaint();

第二个选项是更改面板中的内容并将第二个面板添加为子面板。 执行以下操作:

JPanel thisPanel = this;
a.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
     for(Component c: thisPanel.getComponents()) {
       thisPanel.remove(c);
     }
     JPanel instruction = new Instruction();
     instruction.setBounds(your_values_here...);
     thisPanel.add(instruction);
     thisPanel.revalidate();
     thisPanel.repaint();
}

这里要注意的重要事情是thisPanel应该是由class设置的变量并且不要在动作监听器中使用'this',因为动作监听器中的'this'指的是动作侦听器对象而不是 JPanel。

您需要使用 for 循环的原因是您不想删除刚添加的子面板。

如果您不设置边界,您将看不到您的说明面板,因为它的大小为 0。

希望对您有所帮助