Java 无法在线程内更新JDialog GUI
请看一下下面的代码Java 无法在线程内更新JDialog GUI,java,swing,user-interface,jdialog,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 Emerge
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中。为什么呢?请帮忙 - 您的代码中存在一些问题,Swing中的
一致性
- 求求你,我无法对此发表评论
- 直到
将在官方API中实现之前,SwingWorker
是Runnable#Thread
的标准解决方案Workers Thread
- 生产代码使用
而不是Runnable#Thread
(我不同意API中实现的黑洞)SwingWorker
- 从
到Swing GUI的输出需要使用Runnable#Thread
,对于invokeLater
(Thread\u-safe
,setText
,尤其是Java7与Java6相比也有一些变化)方法append
- 使用
进行util.Timer
,而不是倒计时
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();
}
});
}
}
- 您的代码中存在一些问题,Swing中的
一致性
- 求求你,我无法对此发表评论
- 直到
将在官方API中实现之前,SwingWorker
是Runnable#Thread
的标准解决方案Workers Thread
- 生产代码使用
而不是Runnable#Thread
(我不同意API中实现的黑洞)SwingWorker
- 从
到Swing GUI的输出需要使用Runnable#Thread
,对于invokeLater
(Thread\u-safe
,setText
,尤其是Java7与Java6相比也有一些变化)方法append
- 使用
进行util.Timer
,而不是倒计时
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();
}
});
}
}
首先,永远不要从任何线程(事件调度线程除外)创建、修改或与任何UI组件交互,查看更多详细信息。其次,我看不到在哪里启动线程,因此您已经在EDT上下文中执行,这意味着您正在阻止它,阻止更新线程UI@MadProgrammer:谢谢你的回复。请看一下编辑好的,我设法解决了这个问题。谢谢大家的回复:)我建议你使用类似SwingWorker的东西。我能问一下你是怎么做到的吗?这正是我害怕的。你的线程违反了Swing的单线程规则。您应该只从事件调度线程创建/修改/与UI组件交互首先,永远不要从事件调度线程以外的任何线程创建、修改或与UI组件交互,查看更多详细信息。其次,我看不到在哪里启动线程,因此您已经在EDT上下文中执行,这意味着您正在阻止它,阻止更新线程UI@MadProgrammer:谢谢你的回复。请看一下编辑好的,我设法解决了这个问题。谢谢大家的回复:)我建议你使用类似SwingWorker的东西。我能问一下你是怎么做到的吗?这正是我害怕的。你的线程违反了Swing的单线程规则。您应该只从事件调度线程创建/修改UI组件,并与之交互。显示了使用
javax.swing.Timer的替代方法。感谢您的回复:)。我想你是对的。我的线程没有关闭,甚至GUI也没有了!啊,啊,啊!我正在使用TimerTanks获取建议mKorbel:)显示了使用javax.swing.Timer
的替代方法。感谢您的回复:)。我想你是对的。我的线程没有关闭,甚至GUI也没有了!啊,啊,啊!我正和时间一起移动,希望得到建议(mKorbel:)