Java 我应该在动作中创建Swing组件吗?

Java 我应该在动作中创建Swing组件吗?,java,swing,user-interface,Java,Swing,User Interface,我正在为Swing组件创建操作,但是,它们通常需要生成一个确认JDialog。我应该在动作本身中创建这个JDialog吗?我应该将它传递给动作吗?还是有其他方法 范例 public static class Create extends AbstractAction { @Override public void actionPerformed(ActionEvent event) { int selection = JOptionPane.showConfirm

我正在为Swing组件创建操作,但是,它们通常需要生成一个确认JDialog。我应该在动作本身中创建这个JDialog吗?我应该将它传递给动作吗?还是有其他方法

范例

public static class Create extends AbstractAction {
    @Override
    public void actionPerformed(ActionEvent event) {
        int selection = JOptionPane.showConfirmDialog(...);
        // ... processing
    }        
}
这个例子很难进行单元测试,因为它涉及到自动选择JDialog(感觉像是代码味道)

解决方案?

public static class Create extends AbstractAction {

    private JDialog dialog = null;

    public Create(JDialog dialog) {
        this.dialog = dialog;
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        dialog.display();
        // ... processing
    }        
}

大致如下:

class Dialogs {
    public static Dialogs INSTANCE = new Dialogs();

    public int confirm(String message) {
        return JOptionPane.showConfirmDialog(null, message);
    }
}

然后调用对话框.INSTANCE.confirm(),无论您在哪里调用
JOptionPane.showConfirmDialog()
。对于测试,将Dialogs.INSTANCE设置为模拟值。

我将保持对话框创建的操作执行,并将以下处理逻辑移动到单独的方法中,然后仅对该方法进行单元测试。对话框创建工作正常,不需要对其进行单元测试。

就我个人而言,只要需求始终相同,我会在操作中创建对话框。这使得动作是独立的。这就提出了一个问题:您是否应该将引用传递给父组件。答案是,这要看情况而定……但在测试我的控制器时,这会杀死我……怎么会呢?操作的目的是将可恢复的代码隔离到单个包中,但是单元测试Swing GUI是很困难的-如果GUI进入我的控制器(操作),那么我在测试所有控制器时会遇到问题。这不是操作的问题,而是单元测试的限制。是的,单元测试UI是困难的,但是有一些基于JUnit的项目可以测试Swing应用程序,它们有一个Google。您的单元测试不应该决定您的应用程序设计,因为它提供的好处(和更多的全局访问问题)似乎比简单地传入一个JDialog对象要少。在现实世界中,我会让实例仅通过getter访问,并使用反射或仅测试API来设置它。我只是想给出一个解决方案的概要。传入
对话框
会使您失去
JOptionPane
方法的简单性。