在Swing中实现阻塞调用,模拟模态

时间:2015-05-08 06:26:57

标签: java swing modal-dialog

作为问题的后续问题" JavaFX FileChooser in swing",我已经回答了,我想知道是否有可能在Swing中模拟模态阻塞调用优雅的方式。这是相关代码:

// a trick to emulate modality:
final JDialog modalBlocker = new JDialog();
modalBlocker.setModal(true);
modalBlocker.setUndecorated(true);
modalBlocker.setOpacity(0.0f);
final CountDownLatch modalityLatch = new CountDownLatch(1);
final FutureTask<T> task = new FutureTask<T>(() -> {
    // <-- some code checking whether the task is cancelled
    // and notifying that it is started
    try {
        return callable.call();
    } finally {
        // Wait until the Swing thread is blocked in setVisible():
        modalityLatch.await();
        // and unblock it:
        SwingUtilities.invokeLater(()
                -> modalBlocker.setVisible(false));
    }
});
// run the task in the JavaFX thread:
Platform.runLater(task);
// <-- some code waiting until the task is started,
// canceling it if it's not
// A trick to notify the task AFTER we have been blocked
// in setVisible():
SwingUtilities.invokeLater(() -> {
    // notify that we are ready to get the result:
    modalityLatch.countDown();
});
modalBlocker.setVisible(true); // blocks
modalBlocker.dispose(); // release resources
try {
    return task.get();
} catch (ExecutionException ex) {
    // exception handling
}

这里的想法是在阻止用户输入的同时保持Swing更新,重新绘制,移动进度条和执行其他可视任务,直到阻塞调用返回。如果我做了一个简单的return task.get()没有所有这种模态混乱,那么Swing会在任务工作时冻结,这不是灾难性的,但仍然是不可取的。

整个事情似乎完美无缺,至少在Windows 7下,但是&#34;似乎工作得很好&#34;并不完全符合&#34;写一次,到处运行&#34;,是吗?

我试图查看JDialog / Dialog源代码来弄清楚模态是如何在没有完全冻结GUI的情况下阻塞的,但是唉,代码非常复杂,更糟糕的是,使用太多的私有功能会阻止我这样做在我的代码中,即使我弄清楚它是如何工作的。

问题是:也许有一种更优雅的方式来做我错过的事情?我只需要执行一个阻止调用来保持GUI更新,但阻止所有用户输入,直到调用返回。

0 个答案:

没有答案