问题描述
我正在创建一个秋千应用程序。它包括调用一些耗时的代码的函数。
问题是耗时的代码,它在Label的文本设置之前被调用。我想让标签在进入下一行之前设置。
为什么会发生这种情况?
myFunction()
{
myLabel.setText入门);
//创建另一个类的对象的耗时代码
}
注意:在启动整个应用程序时,我使用java.awt.EventQueue.invokeLater
它将会让您了解 SwingWorker
,这使您在线程化方面具有极大的灵活性。这里是简短而简单的:
所有GUI操作都应该在事件调度线程
(简称EDT)上。所有耗时的任务应该在后台线程上。 SwingWorker允许您控制正在运行代码的线程。
首先,在EDT上运行任何内容,您可以使用以下代码:
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
jLabel1.setText Yay我在EDT);
}
});
但是,如果你想运行一个耗时的任务,那不会做你所需要的。相反,您将需要像这样的SwingWorker:
类任务扩展SwingWorker< Void,Void> {
public Task(){
/ *
*此处放置的代码将在EDT上执行。
* /
jLabel1.setText(Yay I'm on the EDT);
execute();
}
@Override
protected Void doInBackground()throws异常{
/ *
*此处运行的代码将在后台执行,worker 线程不会中断你的EDT
*事件。在这里运行耗时的工作。
*
*注意:请勿在此处运行任何Swing(GUI)代码! Swing不是线程安全的!造成问题,相信我。
* /
返回null;
}
@Override
protected void done(){
/ *
*此方法中运行的所有代码都在EDT上完成,因此请保留你的代码在这里短而甜,即不是
*耗时。
* /
if(!isCancelled()){
boolean error = false;
try {
get(); / *所有的错误都会被这个方法抛出,所以你一定需要它。如果您使用Swing
* worker返回值,则返回此处。
*(我从来没有从SwingWorkers返回值,所以我只是用它来进行错误检查)。
* /
} catch(ExecutionException | InterruptedException e){
//处理你的错误...
error = true;
}
如果(!error){
/ *
*将您的成功代码放在这里,无论是什么。
* /
}
}
}
}
然后,您需要使用以下方式启动SwingWorker:
new Task();
有关更多信息,请查看Oracle的文档:
I am creating a swing application.It consists of calling a function with some time consuming code.
The problem is the "time consuming code" , it is called before the Label's text is set. I want the label to be set before it goes onto the next line.Why does this occour ?
myFunction()
{
myLabel.setText("Started");
//time consuming code which creates object of another class
}
Note: I did use java.awt.EventQueue.invokeLater when starting the entire application
It would behoove you to learn about SwingWorker
which gives you ultimate flexibility when it comes to threading. Here's the short and skinny:
All GUI actions should be on the Event Dispatch Thread
(EDT for short). All time-consuming tasks should be on background threads. SwingWorker allows you to control which thread you're running code on.
First, to run anything on the EDT, you use this code:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
jLabel1.setText("Yay I'm on the EDT.");
}
});
But if you want to run a time-consuming task, that won't do what you need. Instead, you'll need a SwingWorker like this:
class Task extends SwingWorker<Void, Void> {
public Task() {
/*
* Code placed here will be executed on the EDT.
*/
jLabel1.setText("Yay I'm on the EDT.");
execute();
}
@Override
protected Void doInBackground() throws Exception {
/*
* Code run here will be executed on a background, "worker" thread that will not interrupt your EDT
* events. Run your time consuming tasks here.
*
* NOTE: DO NOT run ANY Swing (GUI) code here! Swing is not thread-safe! It causes problems, believe me.
*/
return null;
}
@Override
protected void done() {
/*
* All code run in this method is done on the EDT, so keep your code here "short and sweet," i.e., not
* time-consuming.
*/
if (!isCancelled()) {
boolean error = false;
try {
get(); /* All errors will be thrown by this method, so you definitely need it. If you use the Swing
* worker to return a value, it's returned here.
* (I never return values from SwingWorkers, so I just use it for error checking).
*/
} catch (ExecutionException | InterruptedException e) {
// Handle your error...
error = true;
}
if (!error) {
/*
* Place your "success" code here, whatever it is.
*/
}
}
}
}
Then you need to launch your SwingWorker with this:
new Task();
For more info, check out Oracle's documentation: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
这篇关于按顺序执行两个动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!