[英]Java - JProgressBar won't change value, and JLabel won't change text
我正在用 Java 編寫一個程序,我想添加一個加載頁面,它顯示一個進度條和一個標簽,說明正在加載什么,以及顯示距離完成的進度條,我已經設置好了一切,所以它應該可以工作,但它沒有,我不知道出了什么問題(我是 Java 新手,所以請憐憫)
我試過有一個默認設置為 false 的布爾值,只有在“after-all-set-code”執行后才設置為 true(我使用 netbeans 創建 GUI)並且當我調用函數進行更新時文本/進度條,如果布爾值仍設置為 false,它將等待一秒鍾並重試,直到“all-set-code”將其更改為 true,但這似乎不起作用。
這是在我的main
班里
public class Xtra {
public static loadingPage LP = new loadingPage();
public static void main(String[] args) {
// Show loading page
LP.main(args);
// Set loading
LP.setLoading(0, "Fetching Config...");
// Get Config
// Durring the "getConfig" function it calls the function "LP.setLoading()" multiple times to update the loading bar & text
Xtra.getConfig();
// Set loading
LP.setLoading(0, "Loading user data...");
}
}
這是我的setLoading()
的類中loadingPage
:
public void setLoading(int per, String txt) {
if ("".equals(txt)) {
setLoadingValue(per);
} else {
setLoadingText(txt);
setLoadingValue(per);
}
}
這是我的setLoadingValue()
函數:
public void setLoadingValue(int x) {
// This will turn true when the after-all-set code runs
while (!loadingBarLoaded) {
// Try to wait a second,
// Do this so it doesn't take up too much CPU
try {
// Wait a second
TimeUnit.SECONDS.sleep(1);
// Print to console
System.out.println("Loading value not loaded,\nWaiting another second");
// If there is an error waiting
} catch (InterruptedException ex) {
// Alert user
System.out.println("You cannot sleep now, monsters are nearby");
}
}
// After loaded boolean turns true
// Alert user of change
System.out.println("Setting loading value to " + x + "%");
// Change value
loadingBar.setValue(x);
}
這是我的setLoadingText()
函數:
public void setLoadingText(String txt) {
// This will turn true when the after-all-set code runs
while (!loadingTextLoaded) {
// Try to wait a second,
// Do this so it doesn't take up too much CPU
try {
// Wait a second
TimeUnit.SECONDS.sleep(1);
// Print to console
System.out.println("Loading text not loaded,\nWaiting another second");
// If there is an error waiting
} catch (InterruptedException ex) {
// Alert user
System.out.println("You cannot sleep now, monsters are nearby");
}
}
// After loaded boolean turns true
// Alert user of change
System.out.println("Setting loading text to \"" + txt + "\"");
// Change value
loadingText.setText(txt);
}
我的loadingTextLoaded = true
after-all-set-code
是loadingTextLoaded = true
& loadingBarLoaded = true
取決於完成的內容
它應該更新進度條的文本和值,但事實並非如此,它將Settings loading text to "..."
輸出Settings loading text to "..."
到控制台,並將Setting loading value to ...%
到控制台,但不會更改組件的實際值或文本。
我究竟做錯了什么?
極簡問題:(主文件)
// Inside main function
// Show loading page
LP.main(args);
LP.loadingBar.setValue(50);
LP.loadingText.setText("Hello");
// nothing changes. (Both are public so I can call them from different files
這就是loadingBar
和loadingText
變量並聲明的內容
public javax.swing.JProgressBar loadingBar;
public javax.swing.JLabel loadingText;
loadingBarLoaded
& loadingTextLoaded
是這樣聲明的
public boolean loadingTextLoaded = false;
public boolean loadingBarLoaded = false;
loadingTextLoaded
& loadingBarLoaded
並在所有生成的代碼在運行all-set-code
后將它們放置在窗口內后更改為 true(我使用的是 NetBeans GUI 構建器,因此生成了代碼)
在 loadingPage.java 中,這是它的布局方式。
主窗口和一個覆蓋整個主窗口的面板,它里面有三樣東西,頂部有一個標簽,位於中間,它有應用程序名稱“Xtra”,下面是小而loadingText
副標題表示當前正在加載的內容,在其下方是一個進度條loadingBar
。
對不起,如果我沒有遵循不成文的編碼規則,我一周前才開始使用 java。
了解如何在擺動中穿線。 您必須使用SwingWorker並在 doInBackground() 方法中進行加載並在那里返回進度。
import javax.swing.*;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
public class Main {
private JProgressBar prog;
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
SwingUtilities.invokeAndWait(()-> new Main().initGUI());
}
private void initGUI(){
JDialog dialog = new JDialog();
dialog.setTitle("Progress");
prog = new JProgressBar();
prog.setMaximum(100);
dialog.add(prog);
dialog.pack();
dialog.setVisible(true);
BackgroundWorker bw =new BackgroundWorker();
bw.execute();
}
private class BackgroundWorker extends SwingWorker<String, Integer>{
@Override
protected String doInBackground() throws Exception {
try{Thread.sleep(1000);}catch(Exception e){}
publish(10);
try{Thread.sleep(1000);}catch(Exception e){}
publish(20);
try{Thread.sleep(1000);}catch(Exception e){}
publish(30);
try{Thread.sleep(1000);}catch(Exception e){}
publish(70);
try{Thread.sleep(1000);}catch(Exception e){}
publish(100);
return "finished";
}
@Override
protected void process(List<Integer> chunks) {
prog.setValue(chunks.get(chunks.size()-1));
}
}
}
重要的是,您不能從 doInBackground() 方法訪問任何 Swing 組件,因為該方法不是從 Swing 事件調度線程調用的。
我修復了它,當 GUI 構建器創建頁面時,它使用了此代碼
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new loadingPage().setVisible(true);
}
});
我把它改成:
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
LP.setVisible(true);
}
});
在文件的開頭我把這個: public static loadingPage LP = new loadingPage();
它似乎有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.