2

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

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

4 回答 4

1

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

不要觉得需要让模型层中的合成层次与显示完全匹配。然后只需从 中获取文本Document并执行相关操作即可。

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

于 2008-11-26T11:30:53.153 回答
1

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

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

然后是该主对象中的一个单独的 actionlistener(我称它为中介者,见中介者模式)

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

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

你可以看看这个问题中的代码: 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.
    }
}

可以在此处检索完整且正在运行的代码:

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

于 2008-11-28T08:26:54.973 回答
0

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

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

一旦你有了父面板,到子组件并让他们做任何事情真的是一团糟。

于 2008-11-26T12:13:22.787 回答
0

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

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

链接文本

于 2008-11-26T14:49:20.617 回答