Forum Stats

  • 3,727,636 Users
  • 2,245,428 Discussions
  • 7,852,905 Comments

Discussions

What should I use instead of thread.sleep on a swing applet?

Dynami
Dynami Member Posts: 9
edited August 2017 in New To Java

Hello.

I was trying to make a Timer, where you set the time with a jComboBox, you press a toggle button and it starts.

But, when I made a nested for loop with a 1 sec delay on each loop, thread.sleep froze the aplication.

Then I tried the swing timer. But I can't use it because the Timer needs to be in a text box, and jTextBox does not implement the ActionListener Interface.

What should I do?

And, I feel like I am asking questions too frequently. Should I go back to the basics?

Thanks in advance.

Code at the moment :

    private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {                                           

        String temp1 =(String) jComboBox3.getSelectedItem();

        String temp2 =(String) jComboBox2.getSelectedItem();

        String temp3 = (String) jComboBox1.getSelectedItem();

        int hour =Integer.parseInt(temp1);

        int min = Integer.parseInt(temp2);

        int sec = Integer.parseInt(temp3);

               

        int startHour = hour;

        int startMin = min;

        int startSec = sec;

      if("Timer is OFF".equals(jToggleButton1.getText())){

       

    } else{ {

          for (hour = startHour; hour >= 0; hour--){

                  startMin = 59;

              for (min = startMin; min >= 0; min--){

                  startSec = 59;

                  for(sec = startSec; sec >= 0; sec--){                   

                      try {

                          TimeUnit.SECONDS.sleep(1);

                      } catch (InterruptedException ex) {

                        

                      }

                    jTextField1.setText(hour + ":" + min + ":" + sec); 

                  }

              }

          }

           

    }}

      

    } 

(Might update if needed.)

Tagged:

Answers

  • mNem
    mNem Member Posts: 1,380 Gold Trophy
    edited August 2017

    https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html

    https://docs.oracle.com/javase/tutorial/uiswing/concurrency/interim.html

    The second link has an example similar to yours.

    Some code for you to play around ...

    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;public class Test
    {
      JTextField jTextField1 = null;
      Timer timer = null;
      int hour = 0;
      int min = 0;
      int sec = 0;  public Test()
      {
          //shifted the initialization code to the constructor      JFrame f = new JFrame("Timer Test");
          ActionListener updateListener = new MyUpdateListener();      //somewhat an alternative to thread.sleep()
          //1000 is the 1 sec period for update
          timer = new Timer(1000, updateListener);      jTextField1 = new JTextField();
          jTextField1.setBounds(50, 50, 150, 20);
          JButton b = new JButton("Start");
          b.setBounds(50, 100, 95, 30);
          b.addActionListener(new MyButtonListener());
          f.add(b);
          f.add(jTextField1);
          f.setSize(400, 400);
          f.setLayout(null);
          f.setVisible(true);
      }  private void updateTextbox(String str)  {      System.out.println(str);      jTextField1.setText(str);  }  class MyButtonListener implements ActionListener
      {
          public void actionPerformed(ActionEvent event)
          {
            System.out.println("Entered start button event handler");        // your code for reading the values from combos
            // then set the member variables hour, min and sec        hour = 0;
            min = 0;
            sec = 5;        timer.start();
          }
      }   class MyUpdateListener implements ActionListener
      {
          public void actionPerformed(ActionEvent event)
          {
            if (hour == 0 && min == 0 && sec == 0)
            {
                updateTextbox("The time is up!");
                timer.stop();
            }
            else
            {
                //display - tweak needed for leading zeros
                updateTextbox(hour + ":" + min + ":" + sec);            //reduce by 1 sec
                sec--;            if (sec == -1 && min == 0 && hour > 0)
                {
                  hour--;
                  min = 59;
                  sec = 59;
                }
                else if (sec == -1 && min > 0)
                {
                  min--;
                  sec = 59;
                }
            }
          }
      }  public static void main(String[] args)
      {
          //for further reading: https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
          SwingUtilities.invokeLater(
            new Runnable()
            {
                @Override
                public void run()
                {
                  new Test();
                }
            }
          );
      }
    }
  • Dynami
    Dynami Member Posts: 9
    edited August 2017

    Sorry, but I just got more confused when I noticed jTextField1 doesn't have a ActionPerformed method.

    The code itself works but I have no idea of how to implement that code on my applet.

    Could you explain me?

    And, NetBeans IDE Doesn't let me modify the generated codes.

    Does it have anything to do with my problem?

  • mNem
    mNem Member Posts: 1,380 Gold Trophy
    edited August 2017
    void actionPerformed(ActionEvent e);

    https://docs.oracle.com/javase/7/docs/api/java/awt/event/ActionListener.html#actionPerformed(java.awt.event.ActionEvent)

    Since you are starting the timer display by clicking the Start button, and not interacting with the textbox, the action listener is attached to the button.

    Here, the action is triggered by clicking on the button. So, the actionlistener (ie., MyButtonListener) is set to observe the actions on button click.

          JButton b = new JButton("Start");
          b.setBounds(50, 100, 95, 30);
          b.addActionListener(new MyButtonListener());

    Within the button click event handler, you need to read the values from your combo boxes and set them to hour/min/sec member variables.

    class MyButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
          System.out.println("Entered start button event handler");      // your code for reading the values from combos
          // then set the member variables hour, min and sec      hour = 0;
          min = 0;
          sec = 5;      timer.start();
        }
    }

    And then lastly, the timer starts. This is the equivalent of your TimeUnit.SECONDS.sleep(1); call.

    Since the timer is initialized to

          //somewhat an alternative to thread.sleep()
          //1000 is the 1 sec period for update
          timer = new Timer(1000, updateListener);

    The timer takes care of invoking the actionPerformed() method of the updateListener at defined interval in this case every 1 sec (1000 ms).

       class MyUpdateListener implements ActionListener   {      public void actionPerformed(ActionEvent event)      {         ...

    and that contains the logic to update the textbox and when to stop the timer.

    I am not sure about the generated code as I don't use Netbeans. The post contains a working class. You just needed to add your combo boxes and read the values and set them to the variables.

  • mNem
    mNem Member Posts: 1,380 Gold Trophy
    edited August 2017

    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    public class Test extends JApplet
    {
       JTextField jTextField1 = null;
       Timer timer = null;
       int hour = 0;
       int min = 0;
       int sec = 0;

       private void setup()
       {
          //shifted the initialization code to the constructor

          ActionListener updateListener = new MyUpdateListener();

          //1000 is the 1 sec period for update
          timer = new Timer(1000, updateListener);

          jTextField1 = new JTextField();
          jTextField1.setBounds(50, 50, 150, 20);
          JButton b = new JButton("Start");
          b.setBounds(50, 100, 95, 30);
          b.addActionListener(new MyButtonListener());

          add(b);
          add(jTextField1);
          setLayout(null);
          setSize(400, 400);
          setVisible(true);
       }

       class MyButtonListener implements ActionListener
       {
          public void actionPerformed(ActionEvent event)
          {
             System.out.println("Entered start button event handler");

             // your code for reading the values from combos
             // then set the member variables hour, min and sec

             hour = 0;
             min = 0;
             sec = 5;

             timer.start();
          }
       }

       private void updateTextbox(String str)
       {
          System.out.println(str);
          jTextField1.setText(str);
       }

       class MyUpdateListener implements ActionListener
       {
          public void actionPerformed(ActionEvent event)
          {
             if (hour == 0 && min == 0 && sec == 0)
             {
                updateTextbox("The time is up!");
                timer.stop();
             }
             else
             {
                //display - tweak needed for leading zeros
                updateTextbox(hour + ":" + min + ":" + sec);

                //reduce by 1 sec
                sec--;

                if (sec == -1 && min == 0 && hour > 0)
                {
                   hour--;
                   min = 59;
                   sec = 59;
                }
                else if (sec == -1 && min > 0)
                {
                   min--;
                   sec = 59;
                }
             }
          }
       }

       public void init()
       {
          SwingUtilities.invokeLater(new Runnable()
          {
             @Override
             public void run()
             {
                setup();
             }
          });
       }

       public static void main(String[] args)
       {
          JApplet applet = new Test();
          applet.init();

          //for testing purposes only
          JFrame frame = new JFrame("Applet in Frame");
          frame.setSize(400, 400);
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.add(applet);
          frame.setVisible(true);

          applet.start();
       }
    }

This discussion has been closed.