我试图通过不在主线程(EDT)上执行长任务来遵循Java最佳实践。因此,我计划将“
swingWorker”与“模态对话框”一起使用。这样,模式对话框会阻止用户执行任何操作,直到该任务完成为止,并且我可以在过程进行时更新对话框上的状态。
现在的问题是,使用模式对话框,它不仅会阻止用户,而且在调用setVisible之后也不会阻止用户
所以如果我这样做
dialog.setVisible(true);
new SwingWorkerTask().execute(); //This does not get called
如果我愿意
new SwingWorkerTask().execute();
dialog.setVisible(true); // Well what the point of setting visible after the fact.
那么,如何在执行任务时阻止用户操作并显示对话框?
谢谢
如果您这样做的话,那只是鸡/蛋。您可以在EDT上构造所有Swing对象,然后SwingWorker
通过指示EDT通过执行它们来让您(或任何其他线程)管理所有更新SwingUtilities.invokeLater(Runnable)
。
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class RudeProgressBar extends JFrame {
private JButton button;
public RudeProgressBar() {
setTitle("Rude Progress Bar");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
button = new JButton("Do teh work");
add(button, BorderLayout.SOUTH);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JDialog dialog = new JDialog(RudeProgressBar.this, true);
dialog.setTitle("Doing teh work");
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
final JProgressBar progressBar = new JProgressBar(0, 100);
dialog.setLayout(new BorderLayout());
dialog.add(progressBar);
dialog.setSize(100, 100);
dialog.setLocationRelativeTo(RudeProgressBar.this);
MyTask task = new MyTask(dialog);
task.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});
task.execute();
}
});
setSize(200, 200);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new RudeProgressBar().setVisible(true);
}
});
}
private class MyTask extends SwingWorker<Void, Void> {
private final JDialog dialog;
public MyTask(JDialog dialog) {
this.dialog = dialog;
}
@Override
protected Void doInBackground() throws Exception {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
dialog.setVisible(true);
}
});
int progress = 0;
for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
setProgress(progress += 20);
}
return null;
}
@Override
protected void done() {
dialog.setVisible(false);
dialog.dispose();
}
}
}
如果您担心invokeLater
实现(内部SwingWorker.doInBackground
)在执行之后会被执行SwingWorker.done
,只需将代码done
放入另一个invokeLater
。通过这样做,您可以将Runnable
实现排入队列以让EDT以特定顺序执行它们。即使从EDT本身调用此方法,也会发生排队。
请注意,如果您看一下SwingWorker
实现,您会看到它依赖于javax.swing.Timer
执行done()
和Timer
本身调用invokeLater
,因此done
再次在内部调用它无济于事。但是,如果这样做,不会有任何问题。
在Netbeans中,我创建了一个GUI项目,该项目使用框架前端,我可以添加组件并双击以编辑其事件。我指的是有“源”、“设计”和“历史”选项卡的窗口。 以下是组件和关系: 1-打开文件选择器的按钮。 2-显示文件选择器结果的文本区域。如果用户选择一个文件,它将在文本区域显示文件名;否则它会写“被用户取消”。 3-同时,如果用户选择了一个文件,我想打开一个“please wait”(请等待)对话框,
对话画面 在上一教程里已经讲到了如何设定图片和调整坐标。 这些操作对于标题画面的按钮和对话框上的按钮都是一样的。 因此这篇将主要说一下不同的部分。 进入游戏之后,通常就进入到了对话画面。 一个普通的AVG游戏通常会有一个对话框,用来显示人物的交谈,上面则有一些可以操作的按钮,例如保存、读取、快进、查看对话记录等等。 有一些游戏会有主角或其他人的表情图像,也有些游戏则会有对话专用和叙述专用的对话框。
问题内容: 使用代替或的优点是什么? 问题答案: Thread和Runnable是Java 1.0的一部分;他们和当时一样出色。 从那时起,新的并发类将提炼出关于多线程的所有知识(感谢您,Doug Lea和其他人)。编写多线程代码非常困难。包括SwingWorker在内的新的并发类都试图使其变得更容易。 首先请注意用于强类型键入的泛型。有内置的机制可以发布和处理最终结果和中间结果。 可以使用Thr
问题内容: 是否有与Java SwingWorker类等效的JavaFX? 我知道JavaFX Task,但是有了它,您只能发布String消息或进度。我只想在GUI线程中调用方法,就像使用SwingWorker一样(通过发布任意类型的消息)。 这是我的意思的一个例子: 解 非常感谢您的回答。我正在寻找的解决方案是使用Platform.runLater(Runnable guiUpdater) 。
我想创建一个底部工作表对话框。看起来像下面的图像在这里输入图像描述 我尝试过许多方法,如SharedPreferences。但它不起作用
问题内容: 我想使我的网站一次只允许一个会话。例如,假设用户已经登录到我在firefox上的网站,如果该用户再次登录到另一台浏览器(例如同一台计算机或另一台计算机上的Opera),则Firefox上的会话将被破坏。但是,如果仍为一届会议,则有关Firefox的会议仍将保留。我可以知道该怎么做吗?我正在使用php和apache。谢谢。 问候。本杰明 问题答案: 我建议您做这样的事情: 假设用户“ A