Tuyen Phan
Tuyen Phan

Reputation: 43

updating gui from thread(another class)

I have a class called Gui. This is where I place all my labels and buttons. It also contains a button.addactionlistener. When the button is pressed it starts another thread(stopwatch). This is when stopwatch enters a loop which keeps updating the ms,sec,min in a while loop.

Stopwatch is another class file. Stopwatch contains the ms,sec,min.

How do I update the gui label with the stopwatch ms,sec,min?

public class Gui {

JFrame swFrame = new JFrame("Stopwatch");
Stopwatch sw = new Stopwatch();
Thread t1 = new Thread(sw);
private JPanel p;
private JButton b1;
private JButton b2;
private JButton b3;
private JLabel l1;
private JLabel l2;


public Gui()
{
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {

            swFrame.setSize(500,400);
            swFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            p = new JPanel();

            b1 = new JButton("StartStop");
            b2 = new JButton("LapTime");
            b3 = new JButton("Reset");

            l1 = new JLabel("bla");
            l2 = new JLabel("blala");

            p.add(b1);
            p.add(b2);
            p.add(b3);
            p.add(l1);
            p.add(l2);

            swFrame.add(p);
            b1.setActionCommand("StartStop");
            b2.setActionCommand("LapTime");
            b3.setActionCommand("Reset");
            b1.addActionListener(new ButtonClickListener());
            b2.addActionListener(new ButtonClickListener());
            b3.addActionListener(new ButtonClickListener());

        }
    });
}

private class ButtonClickListener implements ActionListener
{
      public void actionPerformed(ActionEvent e) 
      {
         String command = e.getActionCommand();  
         if( command.equals( "StartStop" ))
         {
            if(t1.isAlive())
            {
                t1.interrupt();
            }
            else
            {
                t1.start();
                !!!//How to update the jlabel from the moment t1.starts?!!!!
            }
         }
         else if( command.equals( "LapTime" ) )
         {
            l2.setText("Submit Button clicked."); 
         }
         else if(command.equals("Reset"))
         {

         }

      }     
   }

class stopwatch

public class Stopwatch implements Runnable 
{

private int min;
private int sec;
private long ms;
Timer timerSW = new Timer();
JLabel l1;


public void run()
{
    ms = System.currentTimeMillis();



    while(!Thread.currentThread().isInterrupted())
    {
        int seconds = (int) (ms / 1000) % 60 ;
        int minutes = (int) ((ms / (1000*60)) % 60);

    }
}

I also have a program class which contains a main method. This calls the Gui.

public class Program {

public static void main(String[] args) 
{
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {
            Gui gui = new Gui();
            gui.swFrame.setVisible(true);
        }
    });

}

}

Upvotes: 0

Views: 845

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347184

How do I update the gui label with the stopwatch ms,sec,min?

Carefully, Swing is not thread safe and you should not modify it's state outside of the context of the Event Dispatching Thread.

One approach would be to use an Observer Pattern, where by your timer triggers updates to which the UI can respond.

A simpler solution might to use a Swing Timer over a Thread, because a Swing Timer is executes its notifications within the context of the EDT

Consider having a look at Concurrency in Swing and How to use Swing Timers for more details

Upvotes: 2

Related Questions