Reputation: 23035
Please have a look at the following code
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();
}
}
}
Thread is started outside the above class
new Thread(new EmergencyAlertNotifier()).start();
I am trying to update the JLabel with the changing numbers inside the thread. But instead, the JLabel is not coming to the GUI. Why is that? Please help!
Upvotes: 1
Views: 1288
Reputation: 109823
there are a few issue in your code, with Concurency in Swing
,
please I can't comment that somehow,
untill SwingWorker
will implemented in official API, Runnable#Thread
was standard workaround for Workers Thread
,
for production code to use Runnable#Thread
instead of SwingWorker
(my view, disagree with black hole implemented in API)
output from Runnable#Thread
to the Swing GUI required usage of invokeLater
, for thread_safe
(setText
, append
... , especially there were chnages in Java7 in compare with Java6) methods too
use util.Timer
for count_down
, instead of Thread.sleep()
modified code, works as expected
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();
}
});
}
}
Upvotes: 4