[英]JProgressBar is invisible but progress is updating correctly
我在此類中執行任務,對話框彈出為白色框。 print語句正在打印出我期望的進度值,但是直到操作完成后,對話框上才會顯示任何內容。 在對話框最后關閉之前,我可以看到進度條閃爍了毫秒。 絕對不知道發生了什么事:\\
public class ProgressDialog extends JDialog {
private JProgressBar pb;
private SwingWorker<Boolean, Void> task;
public SwingWorker<Boolean, Void> getTask(){
return task;
}
public ProgressDialog(final String call){
setTitle("Working...");
setLayout(new BorderLayout());
setBounds(300,300,300,100);
pb = new JProgressBar(0, 100);
pb.setValue(0);
pb.setVisible(true);
pb.setStringPainted(true);
add(pb, BorderLayout.CENTER);
setVisible(true);
task = new SwingWorker<Boolean, Void>(){
public Boolean doInBackground(){
switch(call){
case "Category": pb.setValue(Category.getProgress());
while(pb.getValue()<99){
try{
Thread.sleep(500);
} catch (InterruptedException e){
Thread.currentThread().interrupt();
}
pb.setValue(Category.getProgress());
System.out.println(pb.getValue());
repaint();
revalidate();
}
break;
}
return true;
}
public void done(){
dispose();
}
};
}
}
編輯:嘗試此更改。 沒有骰子。 為什么我什至沒有獲得0%的進度條? 只有在達到100%時才會顯示
public class ProgressDialog extends JDialog {
private JProgressBar pb;
private SwingWorker<Boolean, Integer> task;
public SwingWorker<Boolean, Integer> getTask(){
return task;
}
public ProgressDialog(final String call){
setTitle("Working...");
setLayout(new BorderLayout());
setBounds(300,300,300,100);
pb = new JProgressBar(0, 100);
pb.setValue(0);
pb.setStringPainted(true);
add(pb, BorderLayout.CENTER);
setVisible(true);
task = new SwingWorker<Boolean, Integer>(){
public Boolean doInBackground(){
switch(call){
case "Category": setProgress(Category.getProgress());
while(pb.getValue()<99){
try{
Thread.sleep(500);
} catch (InterruptedException e){
Thread.currentThread().interrupt();
}
setProgress(Category.getProgress());
}
break;
}
return true;
}
public void done(){
//dispose();
}
};
task.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
System.out.println((Integer)evt.getNewValue());
pb.setValue((Integer)evt.getNewValue());
pb.revalidate();
pb.repaint();
}
}
});
}
}
您正在嘗試通過SwingWorker的doInBackground方法中的后台線程設置進度條的狀態-這沒有任何意義。 使用SwingWorker的全部原因是允許您在Swing GUI中執行后台進程,因此您不會從后台線程進行Swing調用,也不會將Swing線程與長線程捆綁在一起。運行代碼。
您不應從此后台進程進行Swing調用。 而是使用publish / process方法,因為這些教程將向您展示。 或許更好的方法是,設置SwingWorker的progress字段,並在SwingWorker上使用PropertyChangeListener來允許進度欄對其做出反應。
無論如何,最重要的是:
setBounds(...)
或null布局。 作為一個寫過數百個Swing程序的人,請相信我,這個程序最終會咬住您的。 這是一個SSCCE,以演示如何更新JProgressBar
。 復制/粘貼並運行它。
注意,我們如何通過調用publish(i)
來更新進度條,該publish(i)
將整數發送到process()
方法。 SwingWorker
將結果以塊的形式發送到process()
方法,但是我們僅使用Integer
來更新JProgressBar
因此我們只關心LAST塊。 在此SSCCE中,我們從1-1000開始。 如果您檢查控制台,您會發現跳過了1-1000之間的許多數字,因為我們更新得太快了, SwingWorker
無法趕上(但是沒關系。這就是為什么它將結果成塊發送的原因)。
注意: process()
方法最初是為程序員設計的,可以從他們長期運行的過程中返回實時結果並更新GUI。 因此,如果要進行數據庫訪JTable
,則可以使用返回的結果更新JTable
。 不過,我討厭那樣做。 因此,在99%的時間中,我只使用“不確定” JProgressBar
並等待直到done()
方法發布我的結果。 但是,有時候,我將使用“確定的” JProgressBar
並像在本SSCCE中一樣進行更新。 我從來沒有使用過process()
返回和發布實際數據。 :)但是,這就是它最初設計的目的。
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
/**
*
* @author Ryan
*/
public class Test {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
go();
}
});
}
public static void go() {
JFrame frame = new JFrame();
JProgressBar jpb = new JProgressBar();
jpb.setIndeterminate(false);
int max = 1000;
jpb.setMaximum(max);
frame.add(jpb);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
new Task(jpb, max).execute();
}
static class Task extends SwingWorker<Void, Integer> {
JProgressBar jpb;
int max;
public Task(JProgressBar jpb, int max) {
this.jpb = jpb;
this.max = max;
}
@Override
protected void process(List<Integer> chunks) {
jpb.setValue(chunks.get(chunks.size()-1)); // The last value in this array is all we care about.
System.out.println(chunks.get(chunks.size()-1));
}
@Override
protected Void doInBackground() throws Exception {
for(int i = 0; i < max; i++) {
Thread.sleep(10); // Sleep for 1/10th of a second
publish(i);
}
return null;
}
@Override
protected void done() {
try {
get();
JOptionPane.showMessageDialog(jpb.getParent(), "Success", "Success", JOptionPane.INFORMATION_MESSAGE);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
}
}
編輯:我創建了一個圖,該圖應該是處理SwingWorker
時的有用參考,以便您知道將代碼放置在何處。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.