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

Posted

技术标签:

【中文标题】使用框架状态变量更新 JFrame 中的 JPanel 内容【英文标题】:Updating JPanel content in JFrame by using a frame state variable 【发布时间】:2016-11-12 14:54:32 【问题描述】:

我正在尝试找到一种在更改状态变量后如何更新面板内容的方法。

具体在下面的示例中,JFrame 内部有一个简单的 JPanel,带有两个按钮。当应用程序启动时,它的状态变量(“window”)等于“home”,所以主页按钮应该是不可见的。单击页面按钮后,状态变量会发生变化,因此两个按钮的可见性都应该在帧重绘后发生变化。 (即页面按钮应该消失,主页按钮应该出现)。

在这种情况下,可以在没有状态变量的情况下解决它,只需对按钮使用 setVisibility() 方法。但是在我的应用程序中,我希望有更多的 JComponetns 连接到状态变量。有什么办法吗?

    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);
        

    

【问题讨论】:

【参考方案1】:

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

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

另外,关于:

btnPage.setVisible(window == "page" ? false : true);

不要使用==!= 比较字符串。请改用equals(...)equalsIgnoreCase(...) 方法。了解== 检查两个 对象引用 是否相同,这不是您感兴趣的。另一方面,这些方法检查两个字符串是否以相同的顺序具有相同的字符,这就是这里的重点。

此外,如果您只想更改 JButton 正在执行的文本和行为,那么您可以使用 setText(...) 仅更改文本来轻松更改此设置,如果需要更深入的更改,请致电 setAction(Action action)更改文本和状态。

【讨论】:

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

以上是关于使用框架状态变量更新 JFrame 中的 JPanel 内容的主要内容,如果未能解决你的问题,请参考以下文章

Java - 来自 JFrame 控件的变量

如何在WindowClosing事件期间更新JFrame对象?

调整JFrame大小后更新JFreeChart / JPanel

更新 JFrame 并使用 Thread.sleep() [重复]

如何更新线程中的JFrame标签? - Java

从子 React Reactive Form 更新父状态变量