在JFrame中将JPanel替换为JPanel

8
我有一个继承JFrame的类,并且它有一个BorderLayout。它有两个私有实例变量,类型为JPanel。它们表示按钮面板,并被称为flipButton和confidenceButtons。当你点击按钮时,按钮面板会被另一个按钮面板替换。也就是说,如果你在flipButton中点击一个按钮,flipButton会被confidenceButtons替换。我尝试这样做:
  private class FlipListener implements ActionListener{
    public void actionPerformed(ActionEvent e){
      remove(flipButton); 
      add(confidenceButtons,BorderLayout.SOUTH);
      validate();
      ...
    }
  } 
  private class ColorListener implements ActionListener{
    ...
    public void actionPerformed(ActionEvent e){
      ...
      remove(confidenceButtons); 
      add(flipButton,BorderLayout.SOUTH);
      validate();
    }
  }
flipButton中的按钮具有FlipListeners,而confidenceButtons中的按钮具有ColorListeners。当程序运行时,点击按钮会删除面板,但是没有添加任何内容来替换它。我做错了什么?
编辑
CardLayout证明是一个简单易用的解决方案。事实证明,上述代码确实可以工作;问题出在我代码的另一部分中的拼写错误。> . <然而,我一直难以使用这些方法,而CardLayout则使我觉得简化了。谢谢。
3个回答

8
请使用CardLayout,如此处所示链接。以下是游戏视图和高分数视图:

Game view High Scores view


也是我的第一想法。CardLayout 是为这种情况设计的,因此它是最好维护的选择。 - extraneon

5
revalidate() + repaint() 应该是一个技巧,例如这里的示例。
编辑:
感觉你对此有问题,这里有一些示例:这里这里,还有trashgod的示例,请随意根据代码构建你的问题。
另一种方法是查看Andrew Thompson添加的优秀示例 :-) +1

我看了这个例子,但不太理解。既然我没有使用Graphics,为什么需要repaint呢?我应该在confidenceButtons上调用所有三个方法吗?这个例子看起来非常具体,我不知道如何将其适应到我的代码中。 - Shelley
+1 另请参阅此示例 - trashgod
@Shelley的例子是关于重新验证+验证+重绘的具体内容,回到关于repaint()的问题,在大多数情况下GUI可以正常工作,不需要repaint(); 嗯,也没有任何Swing教程或详细描述 :-) - mKorbel
@mKorbel 我尝试了这个: all.remove(flipButton); all.add(confidenceButtons,BorderLayout.SOUTH); all.validate(); all.revalidate(); all.repaint();其中all是一个包含所有内容的边框布局的JPanel。我知道有些地方不对...但是我应该输入什么才能让它正确? - Shelley
@Shelley,你能把你的问题转化为代码吗?像trashgod发布的链接一样是最好的基础,然后只需编辑你的问题即可。 - mKorbel
@mKorbel,您能否给我提供一小段代码片段,以便我可以在我的程序中尝试?我不知道应该调用哪些方法以及在哪里调用。 - Shelley

1
尝试使用getContentPane()调用remove(),add()等方法。
getContentPane().remove(flipButton); 
getContentPane().add(confidenceButtons,BorderLayout.SOUTH);   
getContentPane().revalidate();
getContentPane().repaint();

编辑:

下面的代码对我有效:

import java.awt.BorderLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Frame extends JFrame {
JPanel flipButton =new JPanel();
JPanel confidenceButtons =new JPanel();



    public Frame() throws HeadlessException {
    super();
    this.setLayout(new BorderLayout());
    JButton b1=new JButton("flip");
    b1.addActionListener(new FlipListener());
    flipButton.add(b1);

    JButton b2=new JButton("color");
    b2.addActionListener(new ColorListener());
    confidenceButtons.add(b2);
    this.getContentPane().add(flipButton,BorderLayout.SOUTH);
    this.setSize(250,250);
    this.pack();
    this.setVisible(true);

}
    private class FlipListener implements ActionListener{
        public void actionPerformed(ActionEvent e){
          remove(flipButton); 
          add(confidenceButtons,BorderLayout.SOUTH);
          validate();
          repaint();

        }
      } 
      private class ColorListener implements ActionListener{

        public void actionPerformed(ActionEvent e){

          remove(confidenceButtons); 
          add(flipButton,BorderLayout.SOUTH);
          validate();
          repaint();
        }
      }
    /**
     * @param args
     */
    public static void main(String[] args) {
        new Frame();

    }

}

如果您能发布完整的JFrame类代码,我可以尝试修复它。也许尝试使用其他布局而不是Borederlayout。因为BorderLayout有时会导致一些奇怪的行为。 - othman
我认为这并不重要。我已经阅读过,当单独调用add、remove等方法时,它们会自动添加到内容面板中,因此getContentPane()是不必要的。 - Shelley
我尝试使用CardLayout,现在它完美地工作了(原来CardLayout是一个简单的解决方案)。谢谢你的帮助。 - Shelley
我已经在我的答案中加入了一个代码段,我写过并且测试过,能够正常工作。这就是您需要的吗? - othman
我刚刚发现了我的代码中一个错别字,这可能是之前导致问题的原因。修复后,现在它可以正常工作了。谢谢! - Shelley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接