【问题标题】:How to access multiple JPanels inside JFrame?如何访问 JFrame 中的多个 JPanel?
【发布时间】:2008-11-26 10:08:01
【问题描述】:

我有一个JFrame,其中包含一个“显示”JPanel 和一个JTextField 和一个“控件”JPanel,其中的按钮应该可以访问显示JPanel 的内容。我认为我的问题与如何使用观察者模式有关,原则上我理解。您需要放置侦听器并更新消息,但我不知道将这些放在哪里,如何从一个面板访问另一个面板,并且可能在必要时引入“数据模型”类。例如,我想从控制面板访问JTextField 的内容,我使用匿名动作监听器如下:

JButton openfile = new JButton("Convert file");
openfile.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
        openButtonPressed();
    }           
});

【问题讨论】:

    标签: java design-patterns swing controller jpanel


    【解决方案1】:

    你需要减少这些对象之间的耦合。

    您可以拥有一个主对象,它拥有所有文本字段和按钮(面板无关)

    然后是那个主对象中的一个单独的动作监听器(我称之为调解器,参见调解器模式)

    该动作侦听器在中介上执行一个方法,该方法反过来从文本字段中获取值并可能创建一个传输对象。

    这样可以减少面板、文本字段等之间的耦合,并将控件放在一个地方(中介),也就是说,您不会让它们彼此认识。

    你可以看看这个问题中的代码: https://stackoverflow.com/questions/324554/#324559

    它在运行代码中显示了这些概念。

    顺便说一句,观察者模式已经在 J​​TextField、JButton、ActionListener 等中实现了。你只需要添加钩子。

    我希望这会有所帮助。

    编辑将两个答案合二为一。

    这是代码。

    class App { // this is the mediator
    
        // GUI components.
        private JFrame frame;
        private JTextField name;
        private JTextField count;
        private JTextField date;
        // Result is displayed here.
        private JTextArea textArea;
    
        // Fired by this button.
        private JButton   go;
    
        private ActionListener actionListener;
    
    
        public App(){
            actionListener = new ActionListener(){
                public void actionPerformed( ActionEvent e ){
                    okButtonPressed();
                }
            };
        }
    
        private void okButtonPressed(){
             // template is an object irrelevant to this code.
             template.setData( getData() );
             textArea.setText( template.getTransformedData() );
        }
    
    
        public void initialize(){
    
            frame     = new JFrame("Code challenge v0.1");
            frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    
            name     = new JTextField();
            count    = new JTextField();
            date     = new JTextField();
            textArea = new JTextArea();
            go       = new JButton("Go");
            go.addActionListener( actionListener ); // prepare the button.
    
            layoutComponents(); // a lot of panels are created here. Irrelevant.
        }
    }
    

    完整的运行代码可以检索here:

    在可能的情况下,优先考虑组合而不是继承是很重要的。

    【讨论】:

      【解决方案2】:

      如果您在一层中创建模型并在上面添加一两层来创建组件和布局,它确实会使代码更清晰。当然不要扩展JFrameJPanel之类的东西。

      感觉不需要让模型层中的合成层次与显示完全匹配。那么就只需要从Document中取出文本并进行相关操作即可。

      好吧,也许没那么简单。摇摆模型有点乱。尤其是ButtonModel脑残,控制器区的代码可能不完全纯。

      【讨论】:

        【解决方案3】:

        我们有所谓的构建器,它将用子面板构建父面板。在此构建器中,您将可以访问您需要收听的所有子组件,因此可以在那里实现任何逻辑。

        最后,构建器将返回包含完整逻辑的父面板。

        一旦你有了父面板,就真的很麻烦,要让子组件做任何事情。

        【讨论】:

          【解决方案4】:

          谢谢。我添加了一个数据模型层,它以某种方式处理面板之间的通信。

          我还在 JTextField 上的 Listeners 上发现此链接很有用:

          link text

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-03
            • 1970-01-01
            • 1970-01-01
            • 2021-03-12
            • 1970-01-01
            • 2014-10-28
            相关资源
            最近更新 更多