简体   繁体   English

如何避免嵌套的ActionListeners?

[英]How to avoid nested ActionListeners?

In my program, I want the user to: 在我的程序中,我希望用户:

  1. pick/open a database (like Access) on their own 选择/打开一个数据库(如Access)自己
  2. pick a table from the database 从数据库中选择一个表
  3. select column(s) from the table 从表中选择列

In my code, I have a class that does something like this: 在我的代码中,我有一个类,它做了这样的事情:

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 }

And this results to a very big block of code. 这导致了一个非常大的代码块。 Is there a cleaner, simpler way to do this? 有更清洁,更简单的方法吗?

The solution is to refactor: 解决方案是重构:

  • Create a separate and separately testable class for the code to open the database. 为代码创建一个单独且可单独测试的类来打开数据库。
  • And a separate and separately testable class for the display of this data. 还有一个单独的可单独测试的类,用于显示此数据。
  • In the ActionListener, either create instances of these classes, or interact with them, if they already exist. 在ActionListener中,要么创建这些类的实例,要么与它们进行交互(如果它们已经存在)。
  • Learn the basic principles of the MVC (Model-View-Control) design pattern, and use them. 学习MVC(模型 - 视图 - 控制)设计模式的基本原理,并使用它们。 You don't have to be slavish to them, and lord-knows there are many variants, but their overall guiding principles should be at least respected. 你不必对他们是奴隶,而且主 - 知道有很多变种,但他们的总体指导原则至少应该得到尊重。
  • Strive to make your GUI or view as dumb as possible . 努力使您的GUI或视图尽可能愚蠢 It knows how to display its data, it has facilities to allow the control to update its display, and it knows how to notify the control when the user interacts with it, and that's about it. 它知道如何显示其数据,它具有允许控件更新其显示的功能,并且它知道如何在用户与其交互时通知控件,这就是它。
  • Side recommendation 1: be sure that all database interaction is done in a background thread. 侧面建议1:确保所有数据库交互都在后台线程中完成。
  • Side recommendation 2: be sure that almost all Swing interaction is done in on the Swing EDT (the event-dispatch thread). 侧面建议2:确保几乎所有Swing交互都在Swing EDT(事件派发线程)上完成。

Please look at this similar but more complete question and answer: How can one best avoid writing bloated GUI code? 请看一下这个类似但更完整的问题和答案: 如何才能最好地避免编写臃肿的GUI代码? . The answers are as good as it gets, and I wish that I could up-vote them a gazillion times. 答案是最好的,我希望我可以向他们投票数十亿次。

For example, your code above could be as simple as: 例如,您的上述代码可能非常简单:

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

In your example you will instantiate and add new listener on each ActionEvent. 在您的示例中,您将在每个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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM