如何避免嵌套的ActionListeners?

时间:2015-10-30 21:12:35

标签: java swing user-interface

在我的程序中,我希望用户:

  1. 选择/打开自己的数据库(如Access)
  2. 从数据库中选择一个表
  3. 从表中选择列
  4. 在我的代码中,我有一个类似这样的类:

    mntmOpenDatabase.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            //open the database
            //display tables as buttons
            tableButton.addActionListener(new ActionListener() { // select a table
                public void actionPerformed(ActionEvent e) {
                    //display the columns of the table selected as buttons
                        colButton.addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {// add to the list of columns to be exported }
    

    这导致了一个非常大的代码块。有更清洁,更简单的方法吗?

2 个答案:

答案 0 :(得分:10)

解决方案是重构:

  • 为打开数据库的代码创建一个单独且可单独测试的类。
  • 用于显示此数据的单独且可单独测试的类。
  • 在ActionListener中,创建这些类的实例,或者与它们进行交互(如果它们已经存在)。
  • 了解M-V-C(模型 - 视图 - 控制)设计模式的基本原理,并使用它们。你不必对他们是奴隶,而且领主知道有很多变种,但他们的整体指导原则至少应该得到尊重。
  • 努力使您的GUI或视图尽可能愚蠢。它知道如何显示其数据,它具有允许控件更新其显示的功能,并且知道如何在用户与之交互时通知控件,这就是它。
  • 侧面建议1:确保所有数据库交互都在后台线程中完成。
  • 侧面建议2:确保几乎所有Swing交互都在Swing EDT(事件派发线程)中完成。

请查看这个类似但更完整的问答:How can one best avoid writing bloated GUI code?。答案非常好,我希望我可以多次投票给他们。

例如,上面的代码可以简单如下:

mntmOpenDatabase.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        control.openDatabase();
    }
}

答案 1 :(得分:1)

In your example you will instantiate and add new listener on each ActionEvent. Really you should configure it once. Something like this:

public class OpenDataBaseListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e){
               //your event handling here
        }
}

public class TableButtonListener implements  ActionListener{
        @Override
        public void actionPerformed(ActionEvent e){
            //your logic   
        }
}

etc...

And when you create your listeners you should register them once:

mntmOpenDatabase.addActionListener(new OpenDataBaseListener());
tableButton.addActionListener(new TableButtonListener());
colButton.addActionListener(new ColButtonListener());
相关问题