【发布时间】:2016-01-21 15:57:29
【问题描述】:
这是在单元测试的上下文中(当它发生时)。
在测试结束时,无论结果如何,我都希望代码检查JFileChooser 对话框的存在(可见性)...如果可见,则将其关闭。
当然,消除对话有不同的方式,但为了模仿人类行为(并在此举一个我关心的问题的例子),我选择使用java.awt.Robot。后者的方法应该在非 EDT 线程中运行。
实际上我已经扩展了 Robot 以包含一个名为type_input 的便捷方法,所以
robot.type_input( KeyEvent.VK_F4, KeyEvent.VK_ALT )
先按 Alt,然后 F4,然后释放 F4,然后 Alt:就像人类关闭窗口/对话框一样。
我使用invokeAndWait 提交Runnable,因为我不希望代码在此对话框被关闭之前运行到下一个测试。我必须在 EDT 中测试可见性和焦点。但正如我所说,Robot 方法必须在非 EDT 中运行。
在 EDT 中像这样使用 get() 是否有任何潜在问题?它是否可能导致 GUI 无响应?问题是,我听说该框架能够在某些条件下“启动一个新的 EDT 泵”。我不得不承认,这是我觉得自己最不了解的与 EDT 相关的问题之一......
import java.awt.EventQueue;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
class MainFrame extends JFrame {
JFileChooser update_target_file_chooser;
JDialog file_chooser_dlg;
// ... rest of class
}
public class ThreadWithinThread {
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
final ExecutorService thread_pool_exec_serv = Executors.newFixedThreadPool( 5 );
class DismissDlg implements Runnable {
MainFrame main_frame;
Robot robot;
@Override
public void run() {
boolean focus_on_dlg = main_frame.file_chooser_dlg.hasFocus();
if( main_frame.file_chooser_dlg.isVisible() ){
if( ! focus_on_dlg ){
main_frame.file_chooser_dlg.requestFocus();
}
class AltF4 implements Callable<Void>{
public Void call(){
return robot.type_input( KeyEvent.VK_F4, KeyEvent.VK_ALT );
}
}
Future<Void> future_result = thread_pool_exec_serv.submit( new AltF4() );
try {
// this is the line I'm worried about
future_result.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
EventQueue.invokeAndWait( new DismissDlg() );
}
}
稍后
正如我在回复中所说,这不是针对手头的案例提供一个特别实用的解决方案:我真的想了解另一个 EDT“事件泵”是否以及何时以 Future.get() 阻止 EDT 启动.
正如我所说,我发现这整个方面很难理解。我使用JOptionPane 的静态方法(必须在 EDT 中运行,请参阅 SO ad 上的帖子)向我证明,这些方法(确实会阻止 EDT!)实际上似乎并没有阻止 GUI功能正常(注意不要与这些 JOptionPanes 或它们的 JDialogs 是模态的还是非模态的混淆)。
我的理解是,这是因为“框架”随后启动了另一个“事件泵”。那么这里可以吗?
【问题讨论】:
-
获取对 JFileChooser 的引用并调用 isVisible,然后调用 setVisible(false) 有多难?
-
@Bill 谢谢 - 事实上,我主要关心的是使用 Future.get() 是否会导致另一个“事件泵”在另一个 EDT 事件发生时开始。这并不是说我在寻找“一些解决方案”时遇到了实际困难。
-
只是一个想法。可能是您无法访问该对话框,但可能是您可以。有时我们会陷入更复杂的答案,以至于忘记了简单的东西。
标签: java swing concurrency edt