我有一个带有此函数的JFrame类:
o=1;
private String performTest(int i,File file) throws IOException, InterruptedException {
//CRAPPY CODE
while(o<=20) {
Thread.sleep(1000);
progressBar.setValue((o/20)*100);
o++;
}
//CRAPPY CODE
}
因此,进度条应该每秒都以更大的值更新,但是我得到的只是最后一次更新(到100),当函数完成它的工作时; 也许有一些方法可以解决这个问题? 谢谢你。 完整代码。
btnTesteaz.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int i = choice.getSelectedIndex();
File file = fc.getSelectedFile();
StringBuilder builder = new StringBuilder();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
String name = Problems[i];
int o = 1;
try {
String pathToPas = file.getPath();
String pathToExe = pathToPas.replace(".pas", ".exe");
Process process = Runtime.getRuntime().exec("ppc386 "+pathToPas);
Thread.sleep(1000);
process.destroy();
while (new File("Res\\"+Problems[i]+"\\"+"Input"+o+".txt").exists()) {
//FILES WITH INPUTS FROM RES
File in = new File("Res\\"+Problems[i]+"\\"+"Input"+o+".txt");
//FILES FOR .PAS
File inputtxt = new File(file.getParent()+"\\Input.txt");
BufferedReader bf = new BufferedReader(new FileReader(in));
PrintWriter w = new PrintWriter(new FileWriter(inputtxt));
String s = null;
while ((s = bf.readLine())!=null) {
w.println(s);
}
w.close();
bf.close();
Process process1 = Runtime.getRuntime().exec(pathToExe,null, new File(file.getParent()));
Thread.sleep(1000);
process1.destroy();
File outputtxt = new File(file.getParent()+"\\Output.txt");
File out = new File("Res\\"+Problems[i]+"\\"+"Output"+o+".txt");
BufferedReader r1 = new BufferedReader(new FileReader(out));
BufferedReader r2 = new BufferedReader(new FileReader(outputtxt));
StringBuilder ansRes = new StringBuilder();
StringBuilder ansPas = new StringBuilder();
while ( (s=r1.readLine())!=null) ansRes.append(s);
while ( (s=r2.readLine())!=null) ansPas.append(s);
if (ansRes.toString().trim().equals(ansPas.toString().trim())) {
builder.append("<p font color=green>"+(o)+". Test succesful </p> ") ;
}
else builder.append("<p font color=red>"+(o)+". Test failed </p>");
r1.close();
r2.close();
inputtxt.delete();
outputtxt.delete();
final int temp = o;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
model.setValue((int) (((float) temp / 20.0f) * 100));
}
});
o++;
}
File f = new File(pathToExe);
f.delete();
File fa = new File(file.getAbsolutePath().replace(".pas",".o"));
fa.delete();
}
catch (Exception e) {
e.printStackTrace();
}
}
});
t.run();
Result.setText(builder.toString());
}
});
答案 0 :(得分:2)
在Swing中这是一个经典问题。 Swing从其主线程中进行所有图形更新,因此您不应该从那里进行长时间操作(您不会让它重新绘制!)
尝试将您的长时间操作转移到本教程中的另一个线程:
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
这将教你如何在后台进行长时间的任务,同时实时更新你的UI而不会搞乱Swing架构
答案 1 :(得分:0)
添加到Swing UI冻结问题,您还会分配两个整数,这些整数总是向下舍入到最接近的整数,因此您每次都要将进度条设置为0*100
,除了上一次{ {1}},除了使用线程之外,将o == 20
强制转换为o
并通过float
进行转换应该可以解决问题:
20.0f
答案 2 :(得分:-1)
尝试将int更改为double
double o=1;
final double max = 100.00;
final double per = 20.00
private String performTest(int i,File file) throws IOException, InterruptedException {
//HAPPY CODE
while(o<=20) {
Thread.sleep(1000);
progressBar.setValue( (int)((o/per)*max) );
o++;
}
//HAPPY CODE
}