请查看以下代码
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。这是为什么?请帮忙!
答案 0 :(得分:4)
您的代码中存在一些问题,Concurency in Swing
,
请不要以某种方式评论,
直到SwingWorker
将在官方API中实施,Runnable#Thread
是Workers Thread
的标准解决方法,
生产代码使用Runnable#Thread
代替SwingWorker
(我的观点,不同意API中实施的黑洞)
从Runnable#Thread
输出到Swing GUI需要使用invokeLater
,thread_safe
(setText
,append
...,特别是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();
}
});
}
}