加载消息在进程启动时不更新

The loading message is not updated when the process starts

我想在进程启动时显示 "loading message",我想在进程完成时更改消息。我尝试在启动进程的线程之前和之后从 JLabel 更新文本,但问题是框架上只出现最后一次更新。

这是我的代码:

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class MyClass extends JFrame {
    private JLabel loading;
    private JButton jButton;
    private JPanel jPanel;

    public static void main(String[] args) {
        new MyClass();
    }

    MyClass() {
        jPanel = new JPanel();
        setLayout(new GridLayout(0, 1));
        loading = new JLabel("");
        loading.setVisible(true);

        jButton = new JButton("Click me!");
        addActionToJButon();

        setSize(300, 300);
        jPanel.add(jButton);
        jPanel.add(loading);

        add(jPanel);

        setVisible(true);
    }

    private void addActionToJButon() {
        jButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
            loading.setText("Loading....");
            new Thread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    for (int i = 0; i <= 1000000; i++) {
                        System.out.println(i);
                    }
                }
            }).start();
            loading.setText("Done!");
            }   
        });
    }
}

我原以为进程启动后会出现标签 "Loading...",进程完成后会出现消息 "Done",但我无法找出框架上出现标签的原因消息 "Done!".

因为您是在线程内执行 "loading",并且在线程外设置加载文本,所以在开始加载时立即将加载设置为 "Done!"。你想要做的是在你的 运行() 函数中设置加载,如下所示:

private void addActionToJButon() {
    jButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub

        new Thread(new Runnable() {

            @Override
            public void run() {
                loading.setText("Loading....");
                // TODO Auto-generated method stub
                for (int i = 0; i <= 1000000; i++) {
                    System.out.println(i);
                }
                loading.setText("Done!");
            }
        }).start();
        }   
    });
}

感谢 JB Nizet 的建议,我使用了 SwingWorker,代码现在可以正常工作了。

正确代码如下:

package view;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.ExecutionException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;

public class MyClass extends JFrame {
    private JLabel loading;
    private JButton jButton;
    private JPanel jPanel;

    public static void main(String[] args) {
        new MyClass();
    }

    MyClass() {
        jPanel = new JPanel();
        setLayout(new GridLayout(0, 1));
        loading = new JLabel("");
        loading.setVisible(true);

        jButton = new JButton("Click me!");
        addActionToJButon();

        setSize(300, 300);
        jPanel.add(jButton);
        jPanel.add(loading);

        add(jPanel);

        setVisible(true);
    }

    private void addActionToJButon() {
        jButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                loading.setText("Loading....");

                swingWorker();
            }
        });
    }

    private void swingWorker() {
        SwingWorker worker = new SwingWorker<String, String>() {

            @Override
            protected String doInBackground() throws Exception {
                // TODO Auto-generated method stub
                for (int i = 0; i <= 1000000; i++) {
                    System.out.println(i);
                }
                return "Done";
            }

            protected void done() {
                try {
                    String finished =  get();
                    loading.setText(finished);
                } catch (InterruptedException | ExecutionException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        worker.execute();
    }
}