簡體   English   中英

Java - JProgressBar 不會改變值,而 JLabel 不會改變文本

[英]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-codeloadingTextLoaded = 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

這就是loadingBarloadingText變量並聲明的內容

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM