可以运行的Swing Worker线程的数量是上限还是内存支持的?这也是可配置的吗?
SwingWorker 用于以下目的:
done()方法在任务结束时使用长时间运行的任务生成的结果更新GUI .publish()和process()方法生成和发布的中间结果不时更新GUI .SwingUtilities.invokeLater() 可以执行以下任务:
SwingWorker.execute()我们可以执行,而不是从EDT 执行方法,ExecutorService.submit(new MyRunnable())因为它还将创建另一个可以执行长时间运行任务的线程.done()case1的方法编写)SwingUtilites.invokeLater(new RunnableToExecuteDoneMethodCode()).process()case1的方法编写)SwingUtilites.invokeLater(new RunnableToExecuteProcessMethodCode())放在我们publish()在case1中调用方法的地方.我问这个问题是因为Java-SwingWorker中指定的问题- 我们可以从其他SwingWorker调用一个SwingWorker而不是EDT可以通过SwingUtilities.invokeLater()但是无法解决SwingWorker
我希望能够SwingWorker多次使用子类.这可能吗?
我在java doc中读过:
SwingWorker仅设计为执行一次.执行SwingWorker多次不会导致doInBackground两次调用该方法.
我正在为我的设计使用MVC模式,当用户按下搜索按钮时,我在模型中调用搜索,但我还想更新从该模型返回的信息的进度条.
我尝试过使用swingworker,但进度条没有更新.我怀疑我的线程出错了.
我在控制器中定义的按钮是:
class SearchBtnListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
_view.displayProgress();
}
}
Run Code Online (Sandbox Code Playgroud)
这将调用模型中的搜索,并在视图中进行以下调用:
public void displayProgress() {
TwoWorker task = new TwoWorker();
task.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
if ("progress".equals(e.getPropertyName())) {
_progressBar.setValue((Integer) e.getNewValue());
}
}
});
task.execute();
}
private class TwoWorker extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() throws Exception {
_model.startSearch(getTerm()); // time intensive code
File file = new File("lock");
while (file.exists()){
setProgress(_model.getStatus());
System.out.println(_model.getStatus()); // never called
}
return null;
} …Run Code Online (Sandbox Code Playgroud) 我一直在努力解决SwingWorker的可用性问题,吃掉后台任务中抛出的任何异常,例如,在这个SO线程中描述的.该线程给出了一个很好的问题描述,但没有讨论恢复原始异常.
我已被传递的applet需要向上传播异常.但我甚至无法抓住它.我正在使用此博客条目中的SimpleSwingWorker包装类来尝试解决此问题.这是一个相当小的课程,但我会在这里重新发布它仅供参考.
调用代码看起来很像
try {
// lots of code here to prepare data, finishing with
SpecialDataHelper helper = new SpecialDataHelper(...stuff...);
helper.execute(); // this will call get+done on the actual worker
} catch (Throwable e) {
// used "Throwable" here in desperation to try and get
// anything at all to match, including unchecked exceptions
//
// no luck, this code is never ever used :-(
}
Run Code Online (Sandbox Code Playgroud)
包装纸:
class SpecialDataHelper extends SimpleSwingWorker {
public SpecialDataHelper (SpecialData sd) …Run Code Online (Sandbox Code Playgroud) 我用Java创建了我的第一个游戏.这场比赛是垄断.我正在努力设计游戏以模拟其回合制结构(管理玩家转弯).我想允许单个人控和一个或多个AI控制的玩家玩游戏.
我的具体问题是我不知道是否实现游戏循环,这意味着可以管理玩家的循环以及与大富翁游戏直接相关的变量,(想想诸如提示每个玩家轮到他们的事情,将转弯增加到下一个玩家,或者依次从每个玩家获得骰子.我并不是指"游戏循环"这个术语的更低级含义,它更多地涉及屏幕上的绘图框架,更新物理或以特定的时间更新AI.
我的理解是,我尝试实现我需要的选择是:
当我第一次尝试解决这个问题时,我遇到了我的UI冻结的问题,因为我的游戏循环永无止境,并且完全消耗了它运行的线程(我只是做了一个非常简单的while循环来说明这一点) .所以我开始创建一个SwingWorker封装我的游戏循环的努力.这解决了UI冻结的问题,但仍然让我想知道我是否走错了路.
作为一般规则,我发现网上的大多数建议似乎都支持任何事件驱动的方法,因此我目前使用a的实现SwingWorker可能是朝错误方向迈出的一步.但是我无法完全理解如何为这个特定任务实现一个完全事件驱动的系统(意味着没有游戏循环存在).在我看来,一个循环必须存在于某个地方,以管理玩家转弯.
以下是我的具体问题:
SwingWorker)以避免冻结UI?我的情况是特定于Java的,但我想我也会对非Java特定情况的答案感兴趣.目前,我使用MVC模式组织了我的代码.我的控制器是我的游戏循环(实际SwingWorker线程)所在的位置.它远非完整,但它有助于说明我如何管理玩家转向我称之为"游戏循环".
SwingWorker 控制器的代码:
swingWorker = new SwingWorker<Void, Model>() {
@Override
protected Void doInBackground() throws InterruptedException {
gameLoopRunning = true;
while (gameLoopRunning) {
//to do: use a timer instead of thread.sleep
Thread.sleep(1000);
//user turn prompt
if (model.getActivePlayer().isUserControlled()) {
boolean userRolled = false;
while(!userRolled) {
System.out.println("Roll the dice please...");
Thread.sleep(3000);
}
}
//bot turn prompt
else {
//insert code for …Run Code Online (Sandbox Code Playgroud) SwingWorker#setProgressIllegalArgumentException如果参数不是从0到100 ,则抛出一个.我认为该setProgress方法的主要目的是更新a JProgressBar(就像在本教程中一样).如果是这种情况,为什么SwingWorker当JProgressBar进度不受限制时,将进度限制为[0,100] ?
我有一个在后台计算的swing工作者,同时在JFrame中更新progressBar.
如何让我的主线程等待doInBackground()完成?
我知道我可以把东西放在done()方法中,但我想知道是否有办法让程序实际等待(该线程是正确的).
类似于模态JDialog的东西.
所以...
SwingWorker a = new SwingWorker();
a.execute
doOtherStuff();
Run Code Online (Sandbox Code Playgroud)
doOtherStuff仅在doInBackground完成后运行,但不将该方法放在SwingWorker的done()方法中.
我想尝试使用一些想法,SwingWorker因为我没有太多使用它.相反,我遇到了一个问题,我无法弄清楚出了什么问题.
这是一个简短的SSCCE来演示这个问题(我知道这里的人像SSCCE一样):
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class SwingWorkerTest
{
public static void main (String[] args)
{
SwingUtilities.invokeLater (new Runnable ()
{
@Override
public void run ()
{
new MySwingWorker (500).execute ();
new MySwingWorker (900).execute ();
new MySwingWorker (1200).execute ();
}
});
}
}
class MySwingWorker extends SwingWorker<Void, Void>
{
private int ms;
public MySwingWorker (int ms)
{
this.ms = ms;
}
@Override
protected Void doInBackground()
{
Thread t = Thread.currentThread ();
for (int i = …Run Code Online (Sandbox Code Playgroud) 我一直在阅读很多关于Swing,线程,invokeLater(),SwingWorker等的内容,但我似乎无法理解这一切,所以我试图创建一个非常简单的程序来说明.我看了很多例子,但似乎没有一个例子表明我正在尝试做什么.
这是我在我的例子中想要做的事情.我有一个按钮和一个标签,当我单击按钮时,我希望程序暂停3秒钟,然后在标签文本中添加句点.在这3秒钟内,我希望GUI正常显示并继续响应额外的点击.这是我写的:
import javax.swing.SwingWorker;
public class NewJFrame extends javax.swing.JFrame
{
private javax.swing.JButton jButton1;
private javax.swing.JLabel jLabel1;
public NewJFrame()
{
initComponents();
}
private void initComponents()
{
jButton1 = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("Button");
jButton1.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
jButton1ActionPerformed(evt);
}
});
getContentPane().add(jButton1, java.awt.BorderLayout.CENTER);
jLabel1.setText("Text");
getContentPane().add(jLabel1, java.awt.BorderLayout.PAGE_END);
pack();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
SwingWorker worker=new SwingWorker()
{
protected Object doInBackground()
{
try{Thread.sleep(3000);}
catch (InterruptedException ex){}
return null;
}
};
worker.execute();
jLabel1.setText(jLabel1.getText()+".");
}
public static void …Run Code Online (Sandbox Code Playgroud)