Java-JProgressBar不会更改值,而JLabel不会更改文本

时间:2019-09-01 17:24:10

标签: java swing jprogressbar

我正在用Java编写程序,我想添加一个加载页面,其中显示一个进度条和一个标签,说明正在加载的内容,以及显示要完成的进度条,我已经设置了所有内容,因此应该工作,但没有成功,我不知道出了什么问题(我是java的新手,请留意)

我尝试过一个布尔值,默认情况下将其设置为false,并且仅在执行“ after-all-set-code”之后(我正在使用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);

    }

我的after-all-set-codeloadingTextLoaded = trueloadingBarLoaded = true取决于完成的事情

应该更新进度条的文本和值,但不是,它将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;

loadingBarLoadedloadingTextLoaded这样声明:

public boolean loadingTextLoaded = false;
public boolean loadingBarLoaded = false;

loadingTextLoadedloadingBarLoaded,并且在运行all-set-code之后所有生成的代码将它们放置在窗口中之后更改为true(我正在使用NetBeans GUI构建器,因此代码是生成)

在loadingPage.java内部,这是布局的方式

主窗口和一个覆盖着整个主窗口的面板,它内部有三样东西,顶部的标签位于中间,它的名称为“ Xtra”,应用程序的名称为{{ 1}}字幕那么小,并在下方显示进度条loadingText

Here is a screen shot of the layout

很抱歉,如果我不遵循未编写的编码规则,那么像一周前一样,我只是从Java入手。

2 个答案:

答案 0 :(得分:1)

了解挥杆的螺纹。您必须使用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事件调度线程中调用此方法。

答案 1 :(得分:0)

我修复了它,当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();

而且似乎可行。