当我的JButton忙时,是否可以显示正在加载的JLabel?

时间:2018-06-20 07:13:29

标签: java swing jpanel event-dispatch-thread

我已经上传了代码的特定部分,希望这足以理解我的问题。我在具有多个按钮的框架中使用p6面板,并且其中一个按钮显示了该面板。

此面板p6有两个按钮。只需单击check_api,该程序就需要花费一些时间来执行,并且对于用户而言,似乎该应用程序已挂起。因此,我尝试添加一种在按钮繁忙时显示等待消息的方法。但是这样做时,我的面板将失去其用户定义的大小。

是否可以在不影响面板尺寸的情况下显示等待消息?

public static void prepare_url(JPanel p6, JPanel content, int count) {
    InnerOperations.removeexcept(6, content);
    if (count != 1) {
        p6.removeAll();
        p6.revalidate();
        System.out.println("Count is greater than 1");
    }
    JPanel p_back = new JPanel();
    JTextField field = new JTextField(" Enter url(s) with delimiter ';'");
    JButton check_list = new JButton(" CHECK URL LIST STATUS");
    JButton check_api = new JButton(" CHECK  PREDEFINED API LIST");
    p_back.add(check_list);
    p_back.add(field);
    p_back.add(l_check);
    p_back.add(check_api);
    check_api.setBounds(200, 130, 400, 30);
    l_check.setBounds(50, 300, 600, 20);
    field.setBounds(200, 50, 400, 30);
    check_list.setBounds(200, 90, 400, 30);
    p6.add(p_back);
    p_back.setBounds(0, 0, 800, 600);
    check_list.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {

            String url_pref 
            String list[] = url_pref.split(";");
            int i = 0;
            while (i < list.length) {
                try {
                    // thread1.start();
                    prepareurl(p6, p_back, list, list.length);
                    // thread1.stop();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                i++;

            }
        }
    });
    check_api.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            // thread2.start();
            // p_back.removeAll();
            //check_api.setText("Will load in a while");
            prepare_api(p6, content, p_back);
            // thread2.stop();

        }
    });

}
public static void userwait(JPanel ppanel)
{
    JLabel waiting = new JLabel();
    ppanel.add(waiting);
    waiting.setText("Please Wait......");
    waiting.setBounds(200, 200, 400, 30);
}   

2 个答案:

答案 0 :(得分:0)

在EDT中执行长时间运行的任务通常不是一个好主意-改为使用SwingWorker,请参见示例Improve Application Performance With SwingWorker。 您可以在启动辅助线程之前显示一些文本,并禁用按钮以防止用户再次单击:

public class SwingworkerExample extends JFrame {

    private JButton startBtn = new JButton("Start");
    private JProgressBar progressBar = new JProgressBar(0, 100);
    private JLabel progressLbl = new JLabel("");
    private JLabel statusLbl = new JLabel("");

    public static void main(String... args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                SwingworkerExample swe = new SwingworkerExample("SwingWorker: progress");
                swe.setVisible(true);
            }
        });
    }

    public SwingworkerExample(String title) {
        super(title);
        setupUI();
        startBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                startWorkerThread();
            }
        });
    }

    private void startWorkerThread() {
        // Disable JButton:
        startBtn.setEnabled(false);
        // Show info
        statusLbl.setText("running...");
        progressLbl.setText("...");

        /*
         * Create SwingWorker<Boolean, Integer> where
         * Boolean : type for thread result, use "Void" if no return value
         * Integer : type for published values
         */
        SwingWorker<Boolean, Integer> swingWorker = new SwingWorker<Boolean, Integer>() {

            @Override
            protected Boolean doInBackground() throws Exception {
                // WARN: do not update the GUI from within doInBackground(), use process() / done()!

                // Do something ... 
                // prepareurl(p6, p_back, list, list.length);
                // 
                for (int i = 0; i <= 100; i++) {
                    Thread.sleep((int) (Math.random() * 60));
                    // Use publish to send progress information to this.process() [optional]
                    publish(i);
                }
                return true;
            }

            @Override
            protected void process(List<Integer> chunks) {
                // handle published progress informations / update UI
                StringBuilder sb = new StringBuilder();
                chunks.forEach(val -> sb.append(" ").append(val));
                progressLbl.setText(String.format("processing: %s%n", sb));
                int progress = chunks.get(chunks.size() - 1);
                progressBar.setValue(progress);
            }

            @Override
            protected void done() {
                // Swingworker finished - update UI / handle result
                try {
                    Boolean result = get();
                    statusLbl.setText("DONE. Result= " + result);
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                    statusLbl.setText("Error: " + e.getMessage());
                }
                // Enable JButton
                startBtn.setEnabled(true);
            }
        };
        swingWorker.execute();
    } // end: startWorkerThread

    private void setupUI() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(240, 160);
        setLayout(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();
        gc.fill = GridBagConstraints.BOTH;
        gc.weightx = 1;
        gc.weighty = 1;
        gc.gridx = 0;
        gc.weighty = 1;

        gc.gridy = 0;
        add(startBtn, gc);

        gc.gridy = 1;
        add(progressBar, gc);

        gc.gridy = 2;
        add(statusLbl, gc);

        gc.gridy = 3;
        add(progressLbl, gc);
    }
}

答案 1 :(得分:0)

几个选项:

  1. 您可以使用不确定的JProgressBar。有关更多信息和工作示例,请参见How to Use Progress Bars上Swing教程中的部分。

  2. 您可以使用GlassPane在面板顶部显示消息。有关此方法的示例,请参见Disabled Glass Pane