【问题标题】:How to replace JPanel with another JPanel如何用另一个 JPanel 替换 JPanel
【发布时间】:2023-03-11 13:39:01
【问题描述】:

我想用 JFrame 中的另一个 Jpanel 替换一个 Jpanel 我已经搜索并尝试了我的代码,但没有任何反应 这是我的代码:

public class Frame extends JFrame {

    private Container contain;
    private JPanel reChange,reChange2;
    private JButton reChangeButton;

    public Frame() {
        super("Change a panel");
        setSize(350, 350);
        setLayout(null);
        setLocationRelativeTo(null);
        setResizable(false);

        reChange = new JPanel(null);
        reChange.setBackground(Color.red);
        reChange.setSize(240, 225);
        reChange.setBounds(50, 50, 240, 225);
        add(reChange);

        reChangeButton = new JButton("Change It");
        reChangeButton.setBounds(20, 20, 100, 20);
        add(reChangeButton);

        reChangeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //System.out.println("in");
                contain = getContentPane();
                contain.removeAll();
                //System.out.println("in2");

                reChange2 = new JPanel(null);
                reChange2.setBackground(Color.white);
                reChange2.setSize(240, 225);
                reChange2.setBounds(50, 50, 240, 225);
                //System.out.println("in3");

                contain.add(reChange2);
                validate();
                //System.out.println("in4");
                setVisible(true);
                //System.out.println("in5");
            }
        });

    }

    public static void main(String[] args) {
        Frame frame = new Frame();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

有人可以帮助我吗?非常感谢

【问题讨论】:

    标签: java swing layout jframe jpanel


    【解决方案1】:

    试试这个, 以下代码会将第二个 jPanel (NewOrder) 加载到第一个 jPanel(jpMain)

    NewOrder no = new NewOrder(); //This is the object of Second JPanel
    
    // jpMain - This is the First JPanel
    jpMain.setLayout(new java.awt.BorderLayout());
    jpMain.removeAll();
    jpMain.add(no);
    jpMain.revalidate();
    

    【讨论】:

    • revalidate() 是线索。
    【解决方案2】:

    假设您有一个函数 generatePanel(),它返回一个 JPanel,您保存在 JPanel 类型的实例变量中:

    private JPanel panelWithDynamicContent;
    

    假设您已经将该 JPanel 放入一个容器中,可能位于另一个容器内的特定索引处,并且希望保留该容器内组件的顺序。与其使用 removeAll() 来销毁所有内容,我更喜欢只替换需要替换的组件的更精确的方法:

    private void replacePanel(){
       Container parent = this.panelWithDynamicContent.getParent();
       int index = parent.getComponentZOrder(this.panelWithDynamicContent);
       // remove the old edition of the panel
       parent.remove(this.panelWithDynamicContent);
       // generate the replacement panel
       this.panelWithDynamicContent = generatePanel();
       // place the replacement panel in the same relative location as the one it is replacing
       parent.add(this.panelWithDynamicContent, index);
    
       // must call both of these, in the correct order
       parent.validate();
       parent.repaint();
    }
    

    【讨论】:

      【解决方案3】:

      您的代码存在几个问题。这是固定版本:

      public class Frame extends JFrame {
      
          private Container contain;
          private JPanel reChange,reChange2;
          private JButton reChangeButton;
      
          public Frame() {
              super("Change a panel");
              setSize(350, 350);
              getContentPane().setLayout(null); // Changed here
              setLocationRelativeTo(null);
              setResizable(false);
      
              reChange = new JPanel(null);
              reChange.setBackground(Color.red);
              reChange.setSize(240, 225);
              reChange.setBounds(50, 50, 240, 225);
              getContentPane().add(reChange); // Changed here
      
              reChangeButton = new JButton("Change It");
              reChangeButton.setBounds(20, 20, 100, 20);
              getContentPane().add(reChangeButton); // Changed here
      
              reChangeButton.addActionListener(new ActionListener() {
                  @Override
                  public void actionPerformed(ActionEvent e) {
                      contain = getContentPane();
                      contain.removeAll();
      
                      reChange2 = new JPanel(null);
                      reChange2.setBackground(Color.white);
                      reChange2.setSize(240, 225);
                      reChange2.setBounds(50, 50, 240, 225);
      
                      contain.add(reChange2);
                      invalidate(); // Changed here
                      repaint(); // Changed here
                  }
              });
          }
      
          public static void main(String[] args) {
              Frame frame = new Frame();
              frame.setVisible(true);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          }
      }
      

      【讨论】:

        【解决方案4】:

        你需要这样做:

             public void actionPerformed(ActionEvent e) {
                //System.out.println("in");
                contain = getContentPane();
                contain.removeAll();
                //System.out.println("in2");
        
                reChange2 = new JPanel(null);
                reChange2.setBackground(Color.white);
                reChange2.setSize(240, 225);
                reChange2.setBounds(50, 50, 240, 225);
                //System.out.println("in3");
        
                contain.add(reChange2);
                validate();
                repaint();
                //System.out.println("in4");
                setVisible(true);
                //System.out.println("in5");
            }
        });
        

        【讨论】:

          【解决方案5】:
          1. 不要使用AbsoluteLayout

          2. actionPerformed 中的validate(); 更改为contain.validate();,然后使用contain.repaint();

          3. 将类名(保留的 Java 字或方法名)Frame (java.awt.Frame) 重命名为 MyFrame(例如)

          4. 使用CardLayout 而不是删除,然后在运行时添加一个新的JPanel

          【讨论】:

          • +1 用于卡片布局和建议,但我会推荐 revalidate() 而不是 validate()。 @ArdyYonathan 有关 CardLayout 的示例,请参阅 here
          • @David Kroukamp 并非对所有 Java 用户都有效,他们中的大多数人仍然使用 Java6 和次要版本(错过了 Windows 操作系统的大部分限制)
          • +1 true .. 哈哈,但也许我们的代码会强制他们获取 java 7(或最新版本):)
          • aaaach :-) 这是直升机管理员用户在 Windows 中访问的错误,例如简单用户(windows built_in 访问)永远不会更新 JRE,等等(大多数更新,当然可以很容易配置,但为什么要为此烦恼,点)....
          【解决方案6】:

          在执行删除和添加操作后,您必须在包含面板上调用validate(),然后调用repaint()

          contain.validate();
          contain.repaint();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-22
            相关资源
            最近更新 更多