简体   繁体   English

如何在JButton单击上将不同的JPanel添加到JFrame

[英]How to add different JPanel to a JFrame on a JButton click

I would like to add different JPanel to my JFrame when the user clicks on a JButton . 当用户单击JButton时,我想向JFrame添加其他JPanel

The Panel must change according to the button clicked by the user. 面板必须根据用户单击的按钮进行更改。 Here is a portion of my code : 这是我的代码的一部分:

addCours.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            panCours.setBounds(215, 2, 480, 400);
            panCours.setBorder(BorderFactory.createTitledBorder("Saisir les données concernant le cours"));
            ConstituerData.this.getContentPane().add(panCours);
            ConstituerData.this.revalidate();
            ConstituerData.this.repaint();
        }
    });

    addLocal.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            panLocal.setBounds(215, 2, 480, 400);
            panLocal.setBorder(BorderFactory.createTitledBorder("Saisir les données concernant le local"));
            ConstituerData.this.getContentPane().add(panLocal);
            ConstituerData.this.revalidate();
            ConstituerData.this.repaint();
        }
    });

How can I fix this ? 我怎样才能解决这个问题 ?

"How can I fix this ?" “我怎样才能解决这个问题 ?”

  1. That region of setBounds(215, 2, 480, 400) where you seem to be trying to add new components, consider using a CardLayout for that region. 您似乎在尝试尝试添加新组件的setBounds(215, 2, 480, 400) CardLayout区域,请考虑对该区域使用CardLayout Just add a JPanel with CardLayout as the main container for that region. 只需添加带有CardLayoutJPanel作为该区域的主要容器即可。 Then you can either: 然后您可以:

    • Create the child panels on the fly, add it the containing panel, then show it, or 快速创建子面板,将其添加到包含面板,然后显示它,或者
    • Create all the inside panels ahead of time, add them to the containing panel, and just use the show method of the CardLayout to show which panel you want to show. 提前创建所有内部面板,将它们添加到包含的面板中,然后使用CardLayoutshow方法显示要显示的面板。
  2. For the future, I would suggest to use layout managers. 对于将来,我建议使用布局管理器。 Null layouts may become difficult to manage and cause many problems, not just for the developer, but for the application. 空布局可能变得难以管理,并且不仅对开发人员而且对应用程序都造成许多问题。 Swing was designed to be used with layout managers, so use them :) Swing旨在与布局管理器一起使用,因此请使用它们:)

See more at How to use Cardlayout and see an example here 在“ 如何使用Cardlayout”中查看更多信息,并在此处查看示例

Also see Laying out Components Within a Container for more on how to use the different layout managers. 另请参阅在容器中布置组件以获取更多有关如何使用不同布局管理器的信息。

First I would like to go on record in saying that peeskillet's solution is more elegant than the one I am about to detail and that you really should be using a proper layoutManager. 首先,我要记录下来,就是说peeskillet的解决方案比我将要详述的解决方案更为优雅,您确实应该使用适当的layoutManager。 CardLayout really is perfect for this particular situation. CardLayout对于这种特殊情况确实很完美。

However , if you want a quick hack to fix your current predicament you can just add the following to the beginning of each of your ActionListener s actionPerformed() overrides. 但是 ,如果您想快速攻克以解决当前的困境,则可以将以下内容添加到每个ActionListener的actionPerformed()覆盖的开头。

For addCours's ActionListener add the following to first line; 对于addCours的ActionListener将以下内容添加到第一行;

ConstituerData.this.remove(panLocal);

For AddLocal's ActionListener add the following to first line; 对于AddLocal的ActionListener将以下内容添加到第一行;

ConstituerData.this.remove(panCours);

Basically, you are not removing the last JPanel when you are putting the new one in, which is why it appears not to change. 基本上,当您放入新的JPanel时,您并没有删除它,这就是为什么它似乎没有变化的原因。

When I replicated your problem and solved it I used a for loop to loop through the frame's contents and remove all JPanels first in each action listener, like so; 当我复制并解决问题时,我使用了for循环遍历框架的内容,并首先在每个动作侦听器中删除了所有JPanels,就像这样;

@Override
public void actionPerformed(ActionEvent e) {
        for(Component c : frame.getContentPane().getComponents()){
            if(c instanceof JPanel){
                frame.remove(c);
            }
        }
        JPanel panel = new JPanel();
        panel.setBackground(Color.RED);
        panel.setBounds(215, 2, 480, 480);
        frame.add(panel);
        frame.revalidate(); 
        frame.repaint(); 

    }

Thanks everybody. 谢谢大家。 I've proceeded by creating a method like this : 我已经开始创建这样的方法了:

public void supprElements(JPanel jP) {
    for(Component c : this.getContentPane().getComponents()) {
        if(c instanceof JPanel) {
            if(!c.equals(jP)) {
                this.getContentPane().remove(c);
            }
        }
    }
}

And I call this method in each ActionListener interface's implementation : 我在每个ActionListener接口的实现中都调用此方法:

addCours.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub
            supprElements(panCours);
            ConstituerData.this.getContentPane().add(panAdd);
            panCours.setBounds(215, 2, 480, 400);
            panCours.setBorder(BorderFactory.createTitledBorder("Saisir les données concernant le cours"));
            ConstituerData.this.getContentPane().add(panCours);
            ConstituerData.this.revalidate();
            ConstituerData.this.repaint();
            current = 1;
        }
    });

And now, it works as expected. 现在,它可以按预期运行。 Hoping to manage correctly my layout soon. 希望能尽快正确管理我的布局。 Thanks again. 再次感谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM