有没有办法以编程方式从 JFileChooser.showOpenDialog() return?

Is there any way to return from JFileChooser.showOpenDialog() programmatically?

上下文在这里是单元测试:在测试结束时,在tearDown,如果留下JFileChooser "hanging"(即显示),我想强制它的 return 具有 "Cancelled" 值。

问题是,否则,我调用 showOpenDialog(一种阻塞方法)的 actionPerformed() 继续存在...我需要关闭那个 Runnable.

注意 Runnable 运行ning actionPerformed 在 EDT 中当然是 运行ning。但是尽管如此,该框架还是能够启动另一个 "event pump":我的理解是,当您在 EDT 中执行 JFileChooser.showOpenDialog 时,这是非常正常和正确的行为:类似于调用其中一个 JOptionPane.showXXX EDT 中的静态方法。

我也想避免"testing-contrived"解决这个问题:换句话说,应用程序代码必须足够自己使用,而不是使用曲折或不自然的机制,因为它知道它将是运行 通过测试需要提供 "handle".

的代码

PS 我实际上使用的是 Jython,而不是 Java,我使用的是 Python unittest 模块,而不是 Java-基于单元测试框架。但这并没有改变所涉及的原则......

PPS (稍后) 我设计了一个我认为相当 "precarious" 的方法:这涉及深入研究 JFileChooser 以识别具有 getText() == "Cancel" 的 JButton。抱歉,它是用 Jython 编写的,但即使是那些不懂 Python:

的人也应该很容易掌握
def close_main_frame():
    self.main_frame.dispose()
    self.cancel_button = None
    def explore_descendant_comps( container, method, breadth_first = False, depth = 0 ):
        for component in container.components:
            if isinstance( component, java.awt.Container ):
                if breadth_first:
                    method( component, depth )
                explore_descendant_comps( component, method, breadth_first, depth + 1 )
                if not breadth_first:
                    method( component, depth )
    def identify_cancel_button( comp, depth ):
        if isinstance( comp, javax.swing.JButton ) and comp.text == 'Cancel': 
            self.cancel_button = comp
    explore_descendant_comps( self.main_frame.analysis_file_chooser, identify_cancel_button )
    if self.cancel_button:
        self.cancel_button.doClick()
    else:
        raise Exception()

self.edt_despatcher.run_in_edt( close_main_frame, False ) 

这 "precarious" 尤其是因为按钮的 "Cancel" 文本可能会被另一种语言的其他名称替换...

JFileChooser chooser = new JFileChooser();
chooser.addActionListener( new ActionListener() 
{
    public void actionPerformed(ActionEvent e) 
    {
       if( e.getActionCommand().equals("CancelSelection") )
       {
            chooser.cancelSelection();
       }
    }
} );

public void forceCancel()
{
   ActionEvent e = new ActionEvent(chooser, ActionEvent.ACTION_PERFORMED, "CancelSelection");
   fireActionPerformed(e);
}

public void fireActionPerformed( ActionEvent e )
{
   ActionListener[] listeners = chooser.getActionListeners();
  for( ActionListener listener : listeners )
  {
     listener.actionPerformed( e );
  }
}

使用此代码,您可以调用 forceCancel(),它会触发一个动作事件以自动取消 JFileChooser。您可以在单元测试中包含 forceCancel()

(或)

如果您的 Jython 调用 component.cancelSelection() 中有组件,方法是检查该组件的实例。