Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Swing加载时更新/绘制JProgressBar构建GUI_Java_Swing_Event Dispatch Thread_Background Thread - Fatal编程技术网

Java 如何在Swing加载时更新/绘制JProgressBar构建GUI

Java 如何在Swing加载时更新/绘制JProgressBar构建GUI,java,swing,event-dispatch-thread,background-thread,Java,Swing,Event Dispatch Thread,Background Thread,我有一个GUI,它在运行它的平台上构建/初始化非常繁重。。因此,我希望在其初始化时更新进度 我有一个小的未修饰的JDialog,其中包含一个JLabel和一个JProgressBar,我想在初始化期间在特定的位置更新它,但是,因为事件调度thead(根据Swing规则)用于构建/初始化GUI,所以在EDT再次空闲(即初始化完成)之前,进度当然不会更新 我已经使用“立即绘制”重新绘制了JProgressBar,但我似乎无法使它在JLabel和对话框本身中正常工作。。是否有任何简单的推荐/证明方法来

我有一个GUI,它在运行它的平台上构建/初始化非常繁重。。因此,我希望在其初始化时更新进度

我有一个小的未修饰的JDialog,其中包含一个JLabel和一个JProgressBar,我想在初始化期间在特定的位置更新它,但是,因为事件调度thead(根据Swing规则)用于构建/初始化GUI,所以在EDT再次空闲(即初始化完成)之前,进度当然不会更新

我已经使用“立即绘制”重新绘制了JProgressBar,但我似乎无法使它在JLabel和对话框本身中正常工作。。是否有任何简单的推荐/证明方法来实现这一点

干杯

编辑:添加一个我正在尝试做的例子;当然是大大简化了

private JLabel progressLabel;
private JProgressBar progressBar;

public static int main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            showProgressDialog();
            progressLabel.setText("construct 1");

            constructSomeHeavyGUI();

            progressLabel.setText("construct 2");
            progressBar.setValue(33);

            constructSomeMoreHeavyGUI();

            progressLabel.setText("construct 3");
            progressBar.setValue(67);

            constructEvenMoreHeavyGUI();

            progressLabel.setText("done");
            progressBar.setValue(100);

            hideProgressDialog();

            showHeavyGUI();

        }
    });
}

调用
progressBar.setValue()
/
progressLabel.setText()导致的重新绘制
当然,只要EDT忙,上面的代码就会排队,并在我们全部完成后重新绘制,而不是一路更新。

将长时间运行的代码移动到单独的线程中,并使用SwingUtilities.invokeAndWait或invokeLater更新GUI。

按照建议使用,或使用

另见:


我建议,通过使用,您可以在EDT上正确更新JProgressBar,而无需任何冻结或isuees

使用
Runnable#thread
还有另一个选项,但是您必须将GUI的所有输出打包到
invokeLater()中

例如:

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;

public class TestProgressBar {

    private static void createAndShowUI() {
        JFrame frame = new JFrame("TestProgressBar");
        frame.getContentPane().add(new TestPBGui().getMainPanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowUI();
            }
        });
    }

    private TestProgressBar() {
    }
}

class TestPBGui {

    private JPanel mainPanel = new JPanel();

    public TestPBGui() {
        JButton yourAttempt = new JButton("WRONG attempt to show Progress Bar");
        JButton myAttempt = new JButton("BETTER attempt to show Progress Bar");
        yourAttempt.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                yourAttemptActionPerformed();
            }
        });
        myAttempt.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                myAttemptActionPerformed();
            }
        });
        mainPanel.add(yourAttempt);
        mainPanel.add(myAttempt);
    }

    private void yourAttemptActionPerformed() {
        Window thisWin = SwingUtilities.getWindowAncestor(mainPanel);
        JDialog progressDialog = new JDialog(thisWin, "Uploading...");
        JPanel contentPane = new JPanel();
        contentPane.setPreferredSize(new Dimension(300, 100));
        JProgressBar bar = new JProgressBar(0, 100);
        bar.setIndeterminate(true);
        contentPane.add(bar);
        progressDialog.setContentPane(contentPane);
        progressDialog.pack();
        progressDialog.setLocationRelativeTo(null);
        Task task = new Task("Your attempt");
        task.execute();
        progressDialog.setVisible(true);
        while (!task.isDone()) {
        }
        progressDialog.dispose();
    }

    private void myAttemptActionPerformed() {
        Window thisWin = SwingUtilities.getWindowAncestor(mainPanel);
        final JDialog progressDialog = new JDialog(thisWin, "Uploading...");
        JPanel contentPane = new JPanel();
        contentPane.setPreferredSize(new Dimension(300, 100));
        final JProgressBar bar = new JProgressBar(0, 100);
        bar.setIndeterminate(true);
        contentPane.add(bar);
        progressDialog.setContentPane(contentPane);
        progressDialog.pack();
        progressDialog.setLocationRelativeTo(null);
        final Task task = new Task("My attempt");
        task.addPropertyChangeListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getPropertyName().equalsIgnoreCase("progress")) {
                    int progress = task.getProgress();
                    if (progress == 0) {
                        bar.setIndeterminate(true);
                    } else {
                        bar.setIndeterminate(false);
                        bar.setValue(progress);
                        progressDialog.dispose();
                    }
                }
            }
        });
        task.execute();
        progressDialog.setVisible(true);
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }
}

class Task extends SwingWorker<Void, Void> {

    private static final long SLEEP_TIME = 4000;
    private String text;

    public Task(String text) {
        this.text = text;
    }

    @Override
    public Void doInBackground() {
        setProgress(0);
        try {
            Thread.sleep(SLEEP_TIME);// imitate a long-running task
        } catch (InterruptedException e) {
        }
        setProgress(100);
        return null;
    }

    @Override
    public void done() {
        System.out.println(text + " is done");
        Toolkit.getDefaultToolkit().beep();
    }
}
导入java.awt.Dimension;
导入java.awt.Toolkit;
导入java.awt.Window;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.beans.PropertyChangeEvent;
导入java.beans.PropertyChangeListener;
导入javax.swing.*;
公共类TestProgressBar{
私有静态void createAndShowUI(){
JFrame frame=新JFrame(“TestProgressBar”);
frame.getContentPane().add(新的TestPBGui().getMainPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
invokeLater(new Runnable()){
@凌驾
公开募捐{
createAndShowUI();
}
});
}
私有TestProgressBar(){
}
}
类TestPBGui{
private JPanel mainPanel=new JPanel();
公共TestPBGui(){
JButton yourtiment=新JButton(“显示进度条的错误尝试”);
JButton mytrunt=新JButton(“更好地尝试显示进度条”);
addActionListener(新建ActionListener()){
@凌驾
已执行的公共无效操作(操作事件e){
yourAttemptActionPerformed();
}
});
mytrunt.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
myAttemptActionPerformed();
}
});
添加(您的尝试);
mainPanel.add(我的尝试);
}
private void yourAttemptActionPerformed(){
windowthiswin=SwingUtilities.getWindowSenator(主面板);
JDialog progressDialog=新建JDialog(thisWin,“上载…”);
JPanel contentPane=新的JPanel();
setPreferredSize(新维度(300100));
JProgressBar=新的JProgressBar(0100);
bar.setUndeterminate(真);
contentPane.add(条);
progressDialog.setContentPane(contentPane);
progressDialog.pack();
progressDialog.setLocationRelativeTo(空);
任务=新任务(“您的尝试”);
task.execute();
progressDialog.setVisible(true);
而(!task.isDone()){
}
progressDialog.dispose();
}
私有void myAttemptActionPerformed(){
windowthiswin=SwingUtilities.getWindowSenator(主面板);
final JDialog progressDialog=新建JDialog(thisWin,“上载…”);
JPanel contentPane=新的JPanel();
setPreferredSize(新维度(300100));
最终JProgressBar=新的JProgressBar(0,100);
bar.setUndeterminate(真);
contentPane.add(条);
progressDialog.setContentPane(contentPane);
progressDialog.pack();
progressDialog.setLocationRelativeTo(空);
最终任务=新任务(“我的尝试”);
task.addPropertyChangeListener(新的PropertyChangeListener(){
@凌驾
公共作废属性更改(属性更改事件evt){
if(evt.getPropertyName().equalsIgnoreCase(“进度”)){
int progress=task.getProgress();
如果(进度==0){
bar.setUndeterminate(真);
}否则{
bar.setUndeterminate(假);
设置值(进度);
progressDialog.dispose();
}
}
}
});
task.execute();
progressDialog.setVisible(true);
}
公共JPanel getMainPanel(){
返回主面板;
}
}
类任务扩展SwingWorker{
私人静态最终长睡眠时间=4000;
私有字符串文本;
公共任务(字符串文本){
this.text=文本;
}
@凌驾
公共无效doInBackground(){
setProgress(0);
试一试{
Thread.sleep(sleep_TIME);//模拟长时间运行的任务
}捕捉(中断异常e){
}
进度(100);
返回null;
}
@凌驾
公众假期结束(){
System.out.println(text+“已完成”);
getDefaultToolkit().beep();
}
}