在其他操作完成之前,图形文本不会更新
Graphics text won't update until other operations are done
我有一个 JButton,它在单击时执行一个操作。在 actionPerformed 中,我想在调用包含大量计算的 NotifyObserver 之前更新按钮文本。问题是在 NotifyObserver 调用的所有操作完成之前,按钮文本不会更新。这是 JButton 操作代码:
//Action for sinoButton
sinoButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
sinoButton.setText("Loading Sinogram"); //Set text while loading sinogram
NotifyObserversSinogram(); //Notify observer and start sinogram calculation
}
});
如您所见,按钮文本应该在通知观察者之前更新。关于如何解决这个问题有什么想法吗?
编辑
由于 Swing 不是线程安全的,因此您必须使用 Swingutilities:
JButton b = new JButton("Run query");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Thread queryThread = new Thread() {
public void run() {
runQueries();
}
};
queryThread.start();
}
});
// Called from non-UI thread
private void runQueries() {
for (int i = 0; i < noQueries; i++) {
runDatabaseQuery(i);
updateProgress(i);
}
}
private void updateProgress(final int queryNo) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
// event dispatch thread
statusLabel.setText("Query: " + queryNo);
}
});
}
这里有一些关于它如何工作的更完整的信息:Threading with swing
如果NotifyObserversSinogram()
不做特定于Swing的计算,就把它放在另一个线程中:
public void actionPerformed(ActionEvent e) {
sinoButton.setText("Loading Sinogram");
new Thread() {
public void run(){
NotifyObserversSinogram();
}
}.start();
}
如果是,请参阅 SwingWorker
。
JButton sinoButton = new JButton();
//Action for sinoButton
sinoButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
((JButton)e.getSource()).setText("Loading Sinogram"); //Set text while loading sinogram
/*Since this is time consuming operation running on EDT its causing the issue.
* To fix it run the time consuming operation in a thread other than EDT
* */
new Thread(){
public void run() {
NotifyObserversSinogram();
};
}.start();
}
});
Swing 是一个单线程框架,ActionListener
在事件调度线程的上下文中执行,这将阻止 UI 在 actionPerformed
方法存在之前被更新
现在,您可以使用另一个线程来 运行 您的计算,但 Swing 也不是线程安全的。
一个简单的解决方案是使用 SwingWorker
,它可以让您安全地更新 UI,提供进度更新,并在工作人员 done
时收到通知]
有关详细信息,请参阅 Concurrency in Swing and Worker Threads and SwingWorker
我有一个 JButton,它在单击时执行一个操作。在 actionPerformed 中,我想在调用包含大量计算的 NotifyObserver 之前更新按钮文本。问题是在 NotifyObserver 调用的所有操作完成之前,按钮文本不会更新。这是 JButton 操作代码:
//Action for sinoButton
sinoButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
sinoButton.setText("Loading Sinogram"); //Set text while loading sinogram
NotifyObserversSinogram(); //Notify observer and start sinogram calculation
}
});
如您所见,按钮文本应该在通知观察者之前更新。关于如何解决这个问题有什么想法吗?
编辑 由于 Swing 不是线程安全的,因此您必须使用 Swingutilities:
JButton b = new JButton("Run query");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Thread queryThread = new Thread() {
public void run() {
runQueries();
}
};
queryThread.start();
}
});
// Called from non-UI thread
private void runQueries() {
for (int i = 0; i < noQueries; i++) {
runDatabaseQuery(i);
updateProgress(i);
}
}
private void updateProgress(final int queryNo) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
// event dispatch thread
statusLabel.setText("Query: " + queryNo);
}
});
}
这里有一些关于它如何工作的更完整的信息:Threading with swing
如果NotifyObserversSinogram()
不做特定于Swing的计算,就把它放在另一个线程中:
public void actionPerformed(ActionEvent e) {
sinoButton.setText("Loading Sinogram");
new Thread() {
public void run(){
NotifyObserversSinogram();
}
}.start();
}
如果是,请参阅 SwingWorker
。
JButton sinoButton = new JButton();
//Action for sinoButton
sinoButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
((JButton)e.getSource()).setText("Loading Sinogram"); //Set text while loading sinogram
/*Since this is time consuming operation running on EDT its causing the issue.
* To fix it run the time consuming operation in a thread other than EDT
* */
new Thread(){
public void run() {
NotifyObserversSinogram();
};
}.start();
}
});
Swing 是一个单线程框架,ActionListener
在事件调度线程的上下文中执行,这将阻止 UI 在 actionPerformed
方法存在之前被更新
现在,您可以使用另一个线程来 运行 您的计算,但 Swing 也不是线程安全的。
一个简单的解决方案是使用 SwingWorker
,它可以让您安全地更新 UI,提供进度更新,并在工作人员 done
时收到通知]
有关详细信息,请参阅 Concurrency in Swing and Worker Threads and SwingWorker