我正在NetBeans Framework(RCP)上开发Java应用程序。当应用程序运行并且是Visible时,我想显示一个“Please Wait”对话框,该对话框将禁止用户使用GUI,直到正在运行的线程完成。请看下面的代码。它现在的工作方式,它在应用程序可见之前显示“请等待”对话框。再次,我想在应用程序可见时显示“请等待”对话框,而不是之前。我该怎么做?
public final class MyTopComponent extends TopComponent {
public CoreTopComponent() {
initComponents();
}
@Override
public void componentOpened() {
//Show a Dialog ontop of the application with a Please Wait message so that the user cannot use the application until the following threads
//are complete. The Dialog is supposed to automatically close once the threads are complete.
JOptionPane.showOptionDialog(this, "Please Wait...",
"Please Wait...", JOptionPane.PLAIN_MESSAGE,
JOptionPane.PLAIN_MESSAGE, null, new Object[] {},
null);
//There are 10 threads like the following 2 that perform something and in the end update the GUI
final Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
//Step 1 - Create class that initializes configuration
//Step 2 - Create class that performs something using configuration
//Step 3 - Update GUI on the EDT using SwingUtilities.invokeLater
}
});
t1.start();
final Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
//Step 1 - Create class that initializes configuration
//Step 2 - Create class that performs something using configuration
//Step 3 - Update GUI on the EDT using SwingUtilities.invokeLater
}
});
t2.start();
}
@Override
public void componentClosed() {
}
void writeProperties(java.util.Properties p) {
// better to version settings since initial version as advocated at
// http://wiki.apidesign.org/wiki/PropertyFiles
p.setProperty("version", "1.0");
// TODO store your settings
}
void readProperties(java.util.Properties p) {
String version = p.getProperty("version");
// TODO read your settings according to their version
}
}
我尝试使用以下内容,但仍然会发生同样的情况:
@Override
public void componentShowing() {
JOptionPane.showOptionDialog(this, "Please Wait...",
"Please Wait...", JOptionPane.PLAIN_MESSAGE,
JOptionPane.PLAIN_MESSAGE, null, new Object[]{},
null);
}
答案 0 :(得分:1)
JOptionPane创建模态JDialogs。为了避免这种情况,您可以通过创建线程使其成为非模态:
Thread waitThread = new Thread(new Runnable(){
public void run(){
JOptionPane.showOptionDialog(rootPane, "Please Wait...",
"Please Wait...", JOptionPane.PLAIN_MESSAGE,
JOptionPane.PLAIN_MESSAGE, null, new Object[] {},
null);
}
通过以下方式调用:
waitThread.start();
请注意,我将父组件更改为rootPane
而不是null
,但您可以根据应用程序的需要执行此操作。这将解决您的问题,并允许在对话框启动时运行其余代码。
确保在其他线程之前调用它,以便在此对话框启动时它们可以运行。
这是一个类似的问题:
Showing "JOptionPane.showMessageDialog" without stopping flow of execution
答案 1 :(得分:1)
您可以使用ProgressUtils。showProgressDialogAndRun()系列方法在UI的中心显示一个阻止UI的进度条,直到您的任务完成为止。
实施ProgressRunnable界面可让您的任务访问ProgressHandle。然后,使用showProgressDialogAndRun(ProgressRunnable<T> operation, String displayName, boolean includeDetailLabel)
方法,您可以为需要运行的每个子任务设置详细信息标签。
这是一个片段,展示了您可以采用的不同方式。此方案中的主要任务是“正在运行启动”任务。它驱动所有子任务,将ProgressHandle传递给每个子任务,以便每个子任务都可以设置详细信息标签:
...
final List<ProgressRunnable> tasks = new ArrayList<ProgressRunnable>();
tasks.add(new ProgressRunnable<Object>() {
@Override
public Object run(ProgressHandle ph) {
ph.progress("Work unit 1", 1);
return null;
}
});
tasks.add(new CancellableTask());
ProgressUtils.showProgressDialogAndRun(new ProgressRunnable<Void>() {
@Override
public Void run(ProgressHandle ph) {
// run all tasks passing in the ProgressHandle to each
for (ProgressRunnable task : tasks) {
task.run(ph);
}
return null;
}
}, "Running Startup", true);
...
// will show a Cancel button on the progress UI
private class CancellableTask implements ProgressRunnable<Object>, Cancellable {
@Override
public Object run(ProgressHandle ph) {
ph.progress("Cancellable work unit", 2);
return null;
}
@Override
public boolean cancel() {
// clean up
return true;
}
}