从多帧环境中的组件访问框架属性

时间:2018-01-27 08:46:03

标签: java swing jframe

问题

我有一个多帧环境。每个JFrame都有几个JComponents,彼此嵌套。我需要从一些嵌入式组件中访问框架的全局变量。我不能使用静态因为静态当然适用于所有帧。我无法将框架或具有相关信息的类移交给所有组件(组合框,标签等)。

当前解决方案

我目前的解决方案是使用HierarchyListener,一旦显示方法触发,我就可以使用JFrame访问SwingUtilities.getAncestorOfClass

问题

有没有人知道从组件层次结构内部深入访问JFrame's属性的更好解决方案?基本上是所有JComponents都可以访问的帧上下文,但仅限于父帧。是否有某种方式使用e。 G。那个或其他指标的EventQueue

代码

这是当前状态的MCVE:

  • 2帧
  • 嵌入框架中的面板
  • 面板有标签
  • 标签设置为框架标题

代码:

public class MyFrame extends JFrame {

    /**
     * Panel with a label which accesses the parent frame's attributes
     */
    public class MyPanel extends JPanel {

        public MyPanel() {

            // set layout and add the label
            setLayout(new FlowLayout());
            final JLabel label = new JLabel("Placeholder");
            add(label);

            // JFrame is null here, can't use this:
            //   JFrame frame = (JFrame) SwingUtilities.getAncestorOfClass(JFrame.class, this);
            //   label.setText(frame.getTitle());

            // but frame can be accessed once the panel got added using a HierarchyListener 
            addHierarchyListener(new HierarchyListener() {

                @Override
                public void hierarchyChanged(HierarchyEvent e) {
                    long flags = e.getChangeFlags();
                    if ((flags & HierarchyEvent.SHOWING_CHANGED) == HierarchyEvent.SHOWING_CHANGED) {

                        // get frame, get title and set title in label
                        JFrame frame = (JFrame) SwingUtilities.getAncestorOfClass(JFrame.class, MyPanel.this);
                        label.setText(frame.getTitle());

                    }
                }
            });
        }
    }

    /**
     * Frame with title which will be used as example about how to access
     * the frame's attributes from a child component
     */
    public MyFrame(String title, int x, int y) {

        // create content panel
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(new MyPanel(), BorderLayout.CENTER);

        // frame specific code
        setTitle(title);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setSize(100, 100);
        setLocation(x, y);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                JFrame frame1 = new MyFrame("Frame 1", 100, 100);
                JFrame frame2 = new MyFrame("Frame 2", 300, 100);

            }

        });
    }
}

0 个答案:

没有答案