1

请看下面的代码

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 中。这是为什么?请帮忙!

4

1 回答 1

4
  • 您的代码中有一些问题Concurency in Swing

  • 请我不能以某种方式发表评论,

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

  • 用于生产代码Runnable#Thread而不是SwingWorker(我的观点,不同意 API 中实现的黑洞)

  • Runnable#Thread到 Swing GUI 的输出需要使用invokeLater, for thread_safe( setText, append... ,特别是与 Java6 相比,Java7 中也有更改) 方法

  • 使用util.Timerfor 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();
            }
        });
    }
}
于 2013-03-23T08:13:08.780 回答