如何在同一位置替换一个JPanel为另一个JPanel?

3

我有一个包含四个面板的JFrame。在执行某个动作后,我希望将其中一个面板替换为另一个相同位置的面板。我的面板切换方法如下(this对象是一个扩展了JFrame类的类):

 public void switchPanel(){
    mainPanel.remove(introPanel);
    mainPanel.add(questionPanel);
    this.repaint();
 }

窗口的初始创建如下所示:
 mainPanel.add(titlePanel);
 mainPanel.add(sidePanel);
 mainPanel.add(introPanel);
2个回答

7
你问:
如何在同一位置替换一个JPanel为另一个JPanel?
非常简单:使用CardLayout,因为这个工具就是为这种情况而建立的。
如果你有以下常量:
public static final String INTRO_PANEL = "intro panel";
public static final String QUESTION_PANEL = "question panel";

并且像这样添加您的 JPanel:
mainPanel.setLayout(cardLayout);
mainPanel.add(introPanel, INTRO_PANEL);
mainPanel.add(questionPanel, QUESTION_PANEL);

cardLayout.show(mainPanel, INTRO_PANEL);

那么您可以使用以下方法交换JPanels:

cardLayout.show(mainPanel, QUESTION_PANEL);

假设QUESTION_PANEL是一个字符串常量,用于将questionPanel添加到mainPanel,并且mainPanel使用CardLayout,则只需执行上述操作即可显示交换。例如:
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.*;

public class SwapPanels extends JPanel {
   public static final String INTRO_PANEL = "intro panel";
   public static final String QUESTION_PANEL = "question panel";
   private static final int PREF_W = 500;
   private static final int PREF_H = 400;
   private CardLayout cardLayout = new CardLayout();
   private JPanel introPanel;
   private JPanel questionPanel;
   private Random random = new Random();

   public SwapPanels() {
      introPanel = createPanel("Introduction");
      questionPanel = createPanel("Question");
      setLayout(cardLayout);
      add(introPanel, INTRO_PANEL);
      add(questionPanel, QUESTION_PANEL);

      int delay = 3 * 1000; // show intro for 3 seconds
      new Timer(delay, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            cardLayout.show(SwapPanels.this, QUESTION_PANEL);
            ((Timer) e.getSource()).stop();
         }
      }).start();
   }

   private JPanel createPanel(String title) {
      int rgb = random.nextInt();
      Color color = new Color(rgb);
      JPanel panel = new JPanel(new GridBagLayout());
      panel.setBorder(BorderFactory.createLineBorder(color, 60));
      panel.add(new JLabel(title));
      return panel;
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      SwapPanels mainPanel = new SwapPanels();

      JFrame frame = new JFrame("SwapPanels");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

这非常有趣,我已经测试过了,它确实有效。我的唯一问题是,我之前使用了MiG布局,在主面板中删除该布局以测试此功能,但我必须重新设计我之前完成的大量布局。我是否可以将我想要交换的面板包装到“CardLayout”中,然后添加使用MiG的自定义面板? - eignhpants
@eignhpants:使用MigLayout没有任何问题,一点也不。嵌套JPanels并且每个都使用自己的布局是很常见的。你只需要在某个地方使用CardLayout的JPanel来容纳交换的组件就可以了。 - Hovercraft Full Of Eels

0

在使用remove方法后,您需要运行validate方法,就这样。代码将如下所示:

public void switchPanel(){
    mainPanel.remove(introPanel);
    mainPanel.add(questionPanel);
    mainPanel.validate();
}

希望这有所帮助。Salam


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