这是我的示例代码:
package javaapplication35;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import static javaapplication35.ProgressBarExample.customProgressBar;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
public class ProgressBarExample {
final static JButton myButton =new JButton("Start");
final static JProgressBar customProgressBar = new JProgressBar();
private static final JPanel myPanel = new JPanel();
public static void main(String[] args) {
customProgressBar.setMaximum(32);
customProgressBar.setStringPainted(true);
myPanel.add(customProgressBar);
myPanel.add(myButton);
myButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e)
{
Thread firstly =new Thread(new Runnable (
) {
@Override
public void run() {
Calculations a = new Calculations();
a.doCaculations();
}
});
Thread secondly =new Thread(new Runnable (
) {
@Override
public void run() {
JOptionPane.showMessageDialog(null,"just finished");
}
});
firstly.start();
try {
firstly.join();
} catch (InterruptedException ex) {
Logger.getLogger(ProgressBarExample.class.getName()).log(Level.SEVERE, null, ex);
}
secondly.start();
}
});
JOptionPane.showMessageDialog(null, myPanel, "Progress bar test", JOptionPane.PLAIN_MESSAGE);
}
}
class Calculations {
public void doCaculations() {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
int value = 0;
while (value < customProgressBar.getMaximum()) {
Thread.sleep(250);
value ++;
customProgressBar.setValue(value);
}
return null;
}
}.execute();
}
private void doOtherStaff(){
//more methods, that don't need to run in seperate threads, exist
}
}
有2个主题。
firstly
线程创建Calculations
类insance,然后在其上运行doCaculations()
方法。
secondly
线程会弹出一条消息。
我的“真实”代码中的doCaculations()
方法会执行一些耗时的数学运算,并且为了模拟我添加Thread.sleep(250);
所花费的时间。我需要告知用户计算的进度,以便我使用进度条,该进度条由doCaculations()
方法更新。
我正在尝试使代码工作,secondly
线程在firstly
线程完成后运行。但我不能让它发挥作用。发生的事情是弹出消息立即弹出(这意味着它的线程在我希望它运行之前运行)。
注意:“刚完成”的消息只是为了测试代码。在我的“真实”程序中,一种方法就在它的位置。我正在做这个说明,因为如果我只想要一条消息来表明我可以将它放在doCaculations()
方法的末尾,那么一切都会正常工作。
我知道我必须在线程处理方面做错,但我找不到它。有什么想法吗?
PS:一个想法:实际上doCaculations()
方法有自己的主题。所以它在“线程内的SwingWorker”中运行。让firstly.join();
正常工作。但是在调用doCaculations()
方法之后,fistrly
线程被认为已完成,这就是为什么代码继续使用secondly
线程,而不知道doCaculations()
线程仍然存在做某事。
答案 0 :(得分:2)
尝试
a.doCaculations();
a.join();
修改强>
由于您使用的是SwingWorker,我之前的回答是不正确的,但是,正如在您的评论中,您已经扩展了Thread,以下内容对您有用:
Thread a = new Calculations();
a.start();
a.join();
不要忘记,您必须在计算类中覆盖run
方法,例如:
class Calculations extends Thread {
@Override
public void run() {
//your code here
}
}
答案 1 :(得分:2)
在java中你可以使用swingworker并在done()方法中调用你的Dialog
在android中你可以使用AsyncTask来调用新线程,在OnPostExecute方法中,调用show message dialog。
答案 2 :(得分:1)
您的Calculations类必须扩展SwingWorker。您可以在doInBackground()
public class Calculations extends SwingWorker<Void, Void>{
@Override
protected Void doInBackground() throws Exception {
System.out.println("Calculating.");
Thread.sleep(3000);
return null;
}
}
在你的actionPerformed()
中,你使用像这样的计算。
public void actionPerformed(ActionEvent e)
{
//FISRT run method
Calculations a = new Calculations();
a.execute(); // Start calculations
try {
a.get(); // Wait for calculations to finish
} catch (InterruptedException | ExecutionException e1) {
e1.printStackTrace();
}
//THEN inform that just finished
JOptionPane.showMessageDialog(null,"just finished");
}
编辑:如果您希望在SwingWorker中运行多种方法,则可以使代码保持原样。但只添加这些行。
public class Calculations{
protected void calculate() {
SwingWorker sw = new SwingWorker(){
@Override
protected Object doInBackground() throws Exception {
System.out.println("Calculating.");
Thread.sleep(3000);
return null;
}
};
sw.execute(); //Start
try {
sw.get(); //Wait
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
在Calculations
的每种方法中,您就像创建一个新的SwingWorker
一样,并通过调用SwingWorker.get();