有没有办法以编程方式从 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() 中有组件,方法是检查该组件的实例。
上下文在这里是单元测试:在测试结束时,在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() 中有组件,方法是检查该组件的实例。