如何避免嵌套的ActionListeners?

Wab*_*age 5 java user-interface swing

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

  1. 选择/打开一个数据库(如Access)自己
  2. 从数据库中选择一个表
  3. 从表中选择列

在我的代码中,我有一个类,它做这样的事情:

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 }
Run Code Online (Sandbox Code Playgroud)

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

Hov*_*els 10

解决方案是重构:

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

请看一下这个类似但更完整的问题和答案:如何才能最好地避免编写臃肿的GUI代码?.答案是最好的,我希望我可以向他们投票数十亿次.

例如,您的上述代码可能非常简单:

mntmOpenDatabase.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        control.openDatabase();
    }
}
Run Code Online (Sandbox Code Playgroud)