Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java,大型GUI类,具有许多ActionListener;组织听众的最佳方式是什么?_Java_Swing_Actionlistener - Fatal编程技术网

Java,大型GUI类,具有许多ActionListener;组织听众的最佳方式是什么?

Java,大型GUI类,具有许多ActionListener;组织听众的最佳方式是什么?,java,swing,actionlistener,Java,Swing,Actionlistener,我已经开发java程序1年半了。我目前正在做一个暑期项目,涉及到一个相当大的图形用户界面 我的GUI由几个选项卡式窗格组成。每个窗格都有自己的类。每个窗格都有几个JButton 现在,我已经到了一个地步,在我的选项卡式窗格类中有这么多匿名内部类(针对ActionListeners),我确信一定有更好的方法;如果不是为了效率,那么是为了可维护性——它变得相当混乱 我的问题是:当每堂课都有很多听众时,有没有更好的方法来组织听众?我考虑过将侦听器聚集在相关类中,如下面的示例代码: public cla

我已经开发java程序1年半了。我目前正在做一个暑期项目,涉及到一个相当大的图形用户界面

我的GUI由几个选项卡式窗格组成。每个窗格都有自己的类。每个窗格都有几个JButton

现在,我已经到了一个地步,在我的选项卡式窗格类中有这么多匿名内部类(针对ActionListeners),我确信一定有更好的方法;如果不是为了效率,那么是为了可维护性——它变得相当混乱

我的问题是:当每堂课都有很多听众时,有没有更好的方法来组织听众?我考虑过将侦听器聚集在相关类中,如下面的示例代码:

public class SomeListeners implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e){
        String command = e.getActionCommand();
        switch(command){
            case "This button":
                doThis();
                break;
            case "That button":
                doThat();
                break;                          
        }
    }     
}
或者有更好的方法吗


提前感谢:)

我建议使用类型中的单个类

例如:

Action leftAction=new leftAction()//LeftAction代码将在后面显示
...
按钮=新的JButton(leftAction)
...
menuItem=新的JMenuItem(leftAction);
leftAction=新的leftAction(“向左”,anIcon,
“这是左边的按钮。”,
新整数(KeyEvent.VK_L));
。。。


在某种程度上,匿名内部类从“方便”变成了邪恶的混乱。你已经通过了那一点

像蒂姆一样,我建议你使用抽象动作。但是,要展开,请创建自己的抽象子类,该子类可以从配置文件中读取其名称、图标、描述(用于工具提示)等。通过这种方式,您可以将代码国际化,而其他人(营销人员)可以轻松地将按钮从“保存”更改为“SuperSomethingTM”或其他任何内容。图形艺术家可以轻松地修改图标。为实际实现扩展此类

AbstractAction的另一个优点是可以禁用它们。因此,如果没有要保存的更改,您可以轻松禁用保存菜单、保存按钮和工具栏中的保存图标

存储和读取此配置信息有多种方法。一个是资源包


(在我的Nook上键入,因此这是短边,其他人可以自由扩展)

您可以尝试以下方法:

使用真实类而不是匿名类。每个ListenerClass只实现一个用例/功能。类名应该描述用例。然后,您可以将类组织到一个或多个包中,按照适合包中侦听器实现的用例的类别对它们进行集群

这意味着,您创建了一个抽象层次结构,它像树结构一样组织功能

如果某一天以后有人必须维护侦听器,他/她可以通过首先查找适合用例的包,然后查找用例本身来找到侦听器。由于包比类少,因此查找侦听器将更容易、更快


另一种思考方式是:如果你在一个标签上有这么多的事件,你会得到
在代码中组织它们时遇到问题,如何在选项卡上直观地组织它们?你能为用户以符合人体工程学的方式处理这个问题吗?也许解决方案是在多个选项卡上拆分功能?但是,由于我不了解您的UI,我不能说太多,JSR296旨在为您正在做的事情和这里提到的许多其他事情(i18n、操作等)提供一个框架。最活跃的实现是BSAF。可以找到一篇关于如何使用JSR296实现的好文章。

Per duffymo:使用依赖项注入并传入侦听器。这将使您有机会随意重用和更改它们


根据我(气垫船):它不一定是春天,因为Guice会工作得很好。这将很好地配合treeno和Tim Herold的建议(对他们两人来说都是1+)。这一切都是为了尽可能地放松耦合和收紧内聚力。

类似于此代码

public class SomeListeners implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e){
        String command = e.getActionCommand();
        switch(command){
            case "This button":
                doThis();
                break;
            case "That button":
                doThat();
                break;                          
        }
    }     
}
  • 说到这里,您可以比较标准ActionListener所需的字符

  • EventHandler的输出应仅为Swing操作,override setEnabled作为EventHandler中的另一个参数


我觉得你的评论很有教育意义。谢谢你善良的先生:)是的,好主意。我的答案中仍然有AbstractAction子类,但这是一种很好的组织方式。@Daniel:很高兴:-)@user949300:是的,我同意这样可以组合在一起。谢谢!谢谢你的回复!BSAF似乎没有得到积极维护。我确实在我自己的一个项目中使用了它,当JSR296看起来将成为Java的标准部分时,它就开始开发了。如果我开始一个新项目,我可能不会使用BSAF。我喜欢@duffymo关于使用依赖注入的建议,不知道他为什么删除了它。它不必是Spring,因为Guice可以很好地工作。这将很好地配合treeno和Tim Herold的建议(对他们两人来说都是1+)。这一切都是为了尽可能地放松耦合和加强内聚。我复制了duffymo的答案,并将其发布为社区wiki答案,因为这应该是一个成熟的答案。我认为通过XML“编程”连接复杂的侦听器代码是一个非常糟糕的主意。但在我听到更多的回应之前,我不会投反对票。但是,如果某些操作根据动态状态(例如,您正在编辑的文档)启用或更改,则很难想象使用Spring等工具会有好的结果。曾几何时,我也在考虑这个想法(使用Spring框架开发swing应用程序),但我放弃了认为这是一种过火的想法。还是这样?我希望看到这个问题得到改进,我想让我错了我仍然不认为这是过分的。监听器实际上是控制器的一部分——它们是由视图事件触发的动作。我更喜欢将视图构造为纯显示并保持
public class SomeListeners implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e){
        String command = e.getActionCommand();
        switch(command){
            case "This button":
                doThis();
                break;
            case "That button":
                doThat();
                break;                          
        }
    }     
}