实现细节:我正在开发一个学校项目,我必须模拟一些队列。在随机间隔内,客户端应该被生成,客户端选择一个队列(我可以有多个队列)进入,并被添加到该队列数据结构中。每个队列都有自己的操作员,它将客户从其所连接的队列中移除。SwingWorker publish()/ process()的行为像done()
问题:客户端生成器在单独的线程中运行。队列图形表示是JButton的ArrayList,它显示在GridLayout面板上,只有1列。当我尝试向面板添加一个客户端(JButton)时,我想使用SwingWorker的publish()发布一个新的JButton,将其添加到列表中。然而,在经历了许多头痛之后,System.out.println找出了发生了什么,我观察到process()方法中的System.out.println()只有在doBackground()方法完成后才会调用。
代码这里:
//run method of the ClientGenerator thread
public void run()
{
System.out.println("Into thread Generator");
SwingWorker<Void,JButton> worker=new SwingWorker<Void, JButton>()
{
int sleepTime;
@Override
protected Void doInBackground() throws Exception
{
while(checkTime())
{
try
{
sleepTime=minInterval+r.nextInt(maxInterval - minInterval);
System.out.println("Sleeping - "+sleepTime+" milis");
Thread.sleep(sleepTime);
System.out.println("Woke up,"+sleepTime+" milis elapsed");
} catch (InterruptedException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
System.out.println("Generating client...");
newClient=new Client(clientMinService,clientMaxService,log);
System.out.println("Locking lock...");
operationsOnTheQueueLock.lock();
selectedQueueOperator=selectQueueOperator();
System.out.println("Adding new client to queue...");
selectedQueueOperator.getQueue().enqueue(newClient);
System.out.println("Publishing new JButton...");
publish(new JButton("C"+selectedQueueOperator.getClientIndicator()));
//}
// else
// {
// queueHolder.add(selectedQueueOperator.getQueueClients().get(0);
// }
System.out.println("Unlocking lock...");
operationsOnTheQueueLock.unlock();
System.out.println("Lock unlocked! Should enter while again and sleep");
}
return null;
}
@Override
public void process(List<JButton> chunks)
{
newClientButton=chunks.get(chunks.size()-1);
System.out.println("Process runs.Jbutton index="+newClientButton.getText());
newClientButton.setFont(new Font("Arial", Font.PLAIN, 10));
newClientButton.setBackground(Color.lightGray);
newClientButton.setVisible(true);
newClientButton.setEnabled(false);
clients=selectedQueueOperator.getQueueClients();
clients.add(newClientButton);
selectedQueueOperator.setQueueClients(clients);
// if(selectedQueueOperator.getQueueClients().size()>0)
// {
queueHolder=selectedQueueOperator.getQueueHolder();
queueHolder.add(clients.get(clients.size()-1));
selectedQueueOperator.setQueueHolder(queueHolder);
}
// return null; //To change body of implemented methods use File | Settings | File Templates.
};
worker.execute();
try {
worker.get();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (ExecutionException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
输出:
Sleeping - 1260 milis
Woke up,1260 milis elapsed
Generating client...
Locking lock...
Adding new client to queue...
Publishing new JButton... ///here I should see "Process runs.Jbutton index=C0"
Unlocking lock...
Lock unlocked! Should enter while again and sleep
Sleeping - 1901 milis
Woke up,1901 milis elapsed
Generating client...
Locking lock...
Adding new client to queue...
Publishing new JButton...///here I should see "Process runs.Jbutton index=C1
Unlocking lock...
Lock unlocked! Should enter while again and sleep
Process runs.Jbutton index=C0 //instead, Process runs only in the end.
这仅仅是一个基本的例子,对于2次迭代。客户应该不时生成,所以一开始我会睡一段时间。然后我生成客户端对象,然后我想在process()方法中生成按钮并将其添加到我的JPanel组件中。
这最后一部分显然没有发生。任何ideeas为什么?我摆脱的事情尝试,关于SwingWorker ...
在此先感谢!
后来编辑:“锁”被定义为:
Lock lock = new ReentrantLock();
和从管理我的ClientsGenerator(这)类,和我的类中删除客户端从队列中类参数传递。在对ArrayList &显示执行操作时,它用于同步两者。
为什么要补充Jbutton将作为发布的一部分()?定义JList,并将项目添加到DefaultListModel以发布()并从DefaultListModel中删除项目以处理()。 –
只是为了强调:在doInBackground中创建一个JButton是_wrong_(真的真的很糟糕) – kleopatra
@kleopatra好吧,我在发布之前尝试了很多东西。在流程方法中创建jbutton对象,并将字符串传递到发布也不起作用。通过发布传递一个新的jbutton实例是我在发布之前尝试的最后一件事情:s – cjurjiu