无法在线程内更新JDialog GUI

时间:2013-03-23 06:01:25

标签: java swing user-interface jdialog

请查看以下代码

private class EmergencyAlertNotifier implements Runnable, ActionListener
    {
        JDialog dialog = new JDialog();
        int number=0;

        JLabel message;
        JButton yes,no;

        String messageStr;

        public EmergencyAlertNotifier()
        {
            dialog.setLayout(new BorderLayout());

            //The JLabel which will display the number of seconds left
            //before alerting emergency services
            message = new JLabel();


             messageStr="number";

            yes = new JButton("OK");
            yes.addActionListener(this);
            no = new JButton("Cancel");
            no.addActionListener(this);

            JPanel btnPanel = new JPanel();
            btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
            btnPanel.add(yes);
            btnPanel.add(no);

            dialog.add(message,"Center");
            dialog.add(btnPanel,"South");

            dialog.setTitle("Ready To Notify Emergency Fire Services");
            dialog.setVisible(true);
            dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        }

        @Override
        public void run() 
        {
            for(int i=10;i>0;i--)
            {
                message.setText(messageStr+i+" Sec.");


                try
                {
                    Thread.sleep(1000);
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }


        }

        @Override
        public void actionPerformed(ActionEvent e) 
        {
            if(e.getSource()==yes)
            {

            }
            else
            {
                dialog.dispose();
            }
        }

    }

线程在上面的类

之外启动
 new Thread(new EmergencyAlertNotifier()).start();

我正在尝试使用线程内更改的数字更新JLabel。但相反,JLabel并未进入GUI。这是为什么?请帮忙!

1 个答案:

答案 0 :(得分:4)

  • 您的代码中存在一些问题,Concurency in Swing

  • 请不要以某种方式评论,

  • 直到SwingWorker将在官方API中实施,Runnable#ThreadWorkers Thread的标准解决方法,

  • 生产代码使用Runnable#Thread代替SwingWorker(我的观点,不同意API中实施的黑洞)

  • Runnable#Thread输出到Swing GUI需要使用invokeLaterthread_safesetTextappend ...,特别是Java7中的chnages与Java6)方法相比也是

  • 使用util.Timer代替count_down代替Thread.sleep()

修改后的代码,按预期工作

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class EmergencyAlertNotifier implements Runnable, ActionListener {

    private JDialog dialog = new JDialog();
    private int number = 0;
    private JLabel message;
    private JButton yes, no;
    private String messageStr;
    private boolean runProcess = true;

    public EmergencyAlertNotifier() {
        dialog.setLayout(new GridLayout());
        //The JLabel which will display the number of seconds left
        //before alerting emergency services
        message = new JLabel();
        messageStr = "number";
        yes = new JButton("OK");
        yes.addActionListener(this);
        no = new JButton("Cancel");
        no.addActionListener(this);
        JPanel btnPanel = new JPanel();
        btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
        btnPanel.add(yes);
        btnPanel.add(no);
        dialog.add(message, "Center");
        dialog.add(btnPanel, "South");
        dialog.setTitle("Ready To Notify Emergency Fire Services");
        dialog.pack();
        dialog.setVisible(true);
        dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        new Thread(this).start();
    }

    @Override
    public void run() {
        while (runProcess) {
            for (int i = 10; i > 0; i--) {
                message.setText(messageStr + " " + i + " Sec.");
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            runProcess = false;
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == yes) {
        } else {
            dialog.dispose();
        }
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                EmergencyAlertNotifier ean = new EmergencyAlertNotifier();
            }
        });
    }
}