Java 使用框架状态变量更新JFrame中的JPanel内容

Java 使用框架状态变量更新JFrame中的JPanel内容,java,swing,jframe,jpanel,components,Java,Swing,Jframe,Jpanel,Components,我试图找到一种方法,在更改状态变量后如何更新面板内容 具体地说,在下面的示例中,JFrame中有一个简单的JPanel,它有两个按钮。当应用程序启动时,其状态变量(“窗口”)等于“主页”,因此主页按钮应不可见。单击页面按钮后,状态变量会发生变化,因此在重新绘制框架后,两个按钮的可见性都会发生变化。(即页面按钮应消失,主页按钮应出现) 在这种情况下,只需对按钮使用setVisibility()方法,就可以在不使用状态变量的情况下解决该问题。但是在我的应用程序中,我希望有更多的jcomponens连

我试图找到一种方法,在更改状态变量后如何更新面板内容

具体地说,在下面的示例中,JFrame中有一个简单的JPanel,它有两个按钮。当应用程序启动时,其状态变量(“窗口”)等于“主页”,因此主页按钮应不可见。单击页面按钮后,状态变量会发生变化,因此在重新绘制框架后,两个按钮的可见性都会发生变化。(即页面按钮应消失,主页按钮应出现)

在这种情况下,只需对按钮使用setVisibility()方法,就可以在不使用状态变量的情况下解决该问题。但是在我的应用程序中,我希望有更多的jcomponens连接到state变量。有办法吗

    import java.awt.EventQueue;

    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import java.awt.BorderLayout;
    import javax.swing.JButton;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;

    public class JPanelUpdateTest {

        private JFrame frame;
        private String window = "home";

        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        JPanelUpdateTest window = new JPanelUpdateTest();
                        window.frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }


        public JPanelUpdateTest() {
            initialize();
        }


        private void initialize() {
            frame = new JFrame("JPanelUpdateTest");
            frame.setBounds(100, 100, 450, 300);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            JPanel panel = new JPanel();
            frame.getContentPane().add(panel, BorderLayout.CENTER);

            JButton btnHome = new JButton("home");
            btnHome.setVisible(window == "home" ? false : true);
            btnHome.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                    window = "page";
                    panel.revalidate();
                    frame.repaint();
                }
            });
            panel.add(btnHome);

            JButton btnPage = new JButton("page");
            btnPage.setVisible(window == "page" ? false : true);
            btnPage.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    window = "home";
                    panel.revalidate();
                    frame.repaint();
                }
            });
            panel.add(btnPage);
        }

    }

问题是initialize在对象创建时只被调用一次,它应该只被调用一次,因此,
setVisible(…)
代码没有从ActionListeners调用。相反,您需要将更改视图的机制放在ActionListeners本身中,而不仅仅是更改状态,除非您使用的是“绑定属性”和PropertyChangeListeners

我个人建议使用CardLayout来帮助您交换,而不是直接更改字符串,调用类的公共方法——计划何时以及是否从view类中删除ActionListener(控制器)代码

此外,关于:

btnPage.setVisible(window == "page" ? false : true);
不要使用
==
比较字符串=。请改用
equals(…)
equalsIgnoreCase(…)
方法。了解
==
检查两个对象引用是否相同,这不是您感兴趣的。另一方面,这些方法检查两个字符串是否具有相同顺序的相同字符,这就是这里的问题所在


此外,如果您只想更改JButton正在执行的文本和行为,那么您可以通过使用
setText(…)
仅更改文本来轻松更改此操作,如果要进行更深入的更改,请调用
setAction(Action Action)
更改文本和状态。

谢谢您的回答。现在我明白了。。。因此,如果我将组件设置为类常量,以便通过方法对其进行编辑,它将起作用。这意味着有很多常量,所以我将尝试CardLayout。也谢谢你的支持。我真的很感激。