Results 1 to 15 of 15
  1. #1
    Join Date
    Nov 2010
    Posts
    26
    Rep Power
    0

    Default Pausing a Thread

    I'm trying to make a simple game (Pong).
    In the course I need to pause the main thread (running Pong) and show a GUI, and then resume when the button on the GUI is clicked. Here's my code - I'm deeply confused.


    Java Code:
            if(e.getKeyChar() == 'i'){
                try {
                   Thread t = Thread.currentThread();
                   Thread test = new Thread(new Dialog(t, new JFrame()));               
    
                } catch (Exception ex) {
                    Logger.getLogger(NewPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
    // From keyListener in Pong
    
    // And here's Dialog
    
    public Dialog(Thread current, JFrame j){
            this.j = j;
            t = current;
            JButton b = new JButton("Resume");
            b.addActionListener(this);
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            j.setTitle("Instructions");
         
            add(new JLabel("Press 'f'/'s' to increase or decrease game speed\n"));
            add(new JLabel("Press 'r' to reset and 't' to toggle computer\n"));
            add(new JLabel("Press 'c' to change colors."));
            add(new JLabel("Use the arrow keys and 'a'/'d' to move.\n"));
            add(b);
            j.add(this);
            j.pack();
            j.setVisible(true);
        }
    
        public void run() {
            try {
                t.suspend();
            } catch (InterruptedException ex) {
                Logger.getLogger(Dialog.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    
        public void actionPerformed(ActionEvent e) {
            j.dispose();
            t.resume();
        }
    }
    Unrelated question I have a working keyListener, but if I press a button then it stops working. I know for sure that the offending code isn't in the Action Listeners themselves; everything works fine when the listeners are called with a null actionEvent and all the buttons stop it from working. Do I need to call setFocusable(true) again somewhere specific?

    Thanks.

  2. #2
    Junky's Avatar
    Junky is offline Grand Poobah
    Join Date
    Jan 2011
    Location
    Dystopia
    Posts
    3,800
    Rep Power
    7

  3. #3
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

  4. #4
    Join Date
    Nov 2010
    Posts
    26
    Rep Power
    0

    Default

    @ Fubarable - ignorance on my part - thanks.
    Something for next time, I guess. JOptionPane especially seems to have a bunch of quick and easy dialogs.

    @ Junky - thanks for the link.
    I'll play around with what the link suggested in the morning and get back if I need more help - it's getting late here.

  5. #5
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Also: Is your game loop as a Swing Timer? If so you could simply call its stop() and restart() methods as desired.

  6. #6
    Join Date
    Nov 2010
    Posts
    26
    Rep Power
    0

    Default

    I got it working, just enclosed the method that animates in a simple boolean to only execute when true - in hindsight it almost seems silly to have not thought of that before. Thanks.

    @ Fubarable - I changed my program to run with a Swing Timer but for some reason even when I set delay to 1 it was running much slower than I think it should have. My old code was essentially this:

    Java Code:
    while(b){
       Thread.sleep(1);
       animate();
    }
    and I changed it, when trying out Swing Timer to this:

    Java Code:
       ActionListener taskPerformer = new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
             animate();
          }
       };
       t = new Timer(1, taskPerformer);
       t.start();

  7. #7
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

  8. #8
    Join Date
    Nov 2010
    Posts
    26
    Rep Power
    0

    Default

    What do you mean? It worked with the Thread.sleep solution.
    Also, shouldn't the two code blocks above accomplish almost the same thing?

  9. #9
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by Lord Voldemort View Post
    What do you mean? It worked with the Thread.sleep solution.
    Also, shouldn't the two code blocks above accomplish almost the same thing?
    They should except the second won't pause the main Swing thread, the EDT and will guarantee to call the animate method on the EDT. If still in doubt, consider testing it by creating an SSCCE that illustrates your problem.

  10. #10
    Join Date
    Nov 2010
    Posts
    26
    Rep Power
    0

    Default

    Consider the two approaches here - one is commented out.
    Java Code:
    package pong;
    
    import java.awt.Graphics;
    import java.awt.Point;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class Example extends JPanel{
    
        Point p = new Point(100, 100);
        int dx = 1;
        int dy = 1;
    
        public Example(){}
    
        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.drawOval(p.x, p.y, 10, 10);
        }
    
        public void animate(){
            p.setLocation(p.x + dx, p.y + dy);
            repaint();
        }
    
        public static void createAndShowGUI(){
            final Example ex = new Example();
            JFrame frame = new JFrame();
            frame.setSize(300, 300);
            frame.setVisible(true);
            frame.add(ex);
    
           // boolean b = true;
           // while(b){
           //     try {
           //         ex.animate();
           //         Thread.sleep(1);
           //     } catch (Exception e) {}
           // }
    
            ActionListener taskPerformer = new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    ex.animate();
                }
            };
            Timer t = new Timer(1, taskPerformer);
            t.start();
        }
    
        public static void main(String[] args){
            createAndShowGUI();
        }
    }
    I don't understand why the solution with the Swing timer is slower. If it fired an ActionEvent every 1 millisecond, then every millisecond animate should be called and the ball should move 1 unit to the right and down. If you comment the Timer solution and try the Thread.sleep(1) way, then it calls animate(), then doesn't do anything for 1 millisecond, and then calls animate again. Thus it seems like they should show that ball moving at the same speed.

  11. #11
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Yikes, they're both too fast for me to see anything more than the briefest shadow of an oval zipping across and off of the JPanel. An aside: I think that in most animations, regardless of the loop speed, the position of the sprite will depend on calculating where it should be based on the elapsed system time.

  12. #12
    Join Date
    Nov 2010
    Posts
    26
    Rep Power
    0

    Default

    Hmm... that is strange. When I run it as the Timer approach the oval is visible for a good three seconds, though I see the same thing (same as you, I mean) when using Thread.sleep.
    About the aside: well, this was originally for Pong, a game, so a timer wouldn't really work since it can last arbitrarily long. I just took out all the non-essentials like the ball 'bouncing' off the sides for the purposes of the example.
    Last edited by Lord Voldemort; 05-21-2011 at 10:24 PM. Reason: Clarification

  13. #13
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Here's your code, but with both loops running concurrently, and with a smaller increment of 0.1:

    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    @SuppressWarnings({"unused", "serial"})
    public class Example extends JPanel {
    
       private static final Color WHILE_LOOP_COLOR = Color.green;
       private static final Color SWING_LOOP_COLOR = Color.blue;
       double wlX = 10.0;
       double wlY = 10.0;
       double stX = 15.0;
       double stY = 10.0;
       double dx = 0.1;
       double dy = 0.1;
    
       public Example() {
       }
    
       @Override
       public void paintComponent(Graphics g) {
          super.paintComponent(g);
          g.setColor(WHILE_LOOP_COLOR);
          g.drawOval((int)wlX, (int)wlY, 10, 10);
          g.setColor(SWING_LOOP_COLOR);
          g.drawOval((int)stX, (int)stY, 10, 10);
       }
    
       public void wlAnimate() {
          wlX += dx;
          wlY += dy;
          repaint();
       }
       
       public void stAnimate() {
          stX += dx;
          stY += dy;
          repaint();
       }
    
       public static void createAndShowGUI() {
          final Example ex = new Example();
          JFrame frame = new JFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // don't forget this
          frame.setSize(300, 300);
          frame.setVisible(true);
          frame.add(ex);
    
          swingTimerLoop(ex);
          whileLoop(ex);
       }
    
       private static void swingTimerLoop(final Example ex) {
          ActionListener taskPerformer = new ActionListener() {
             public void actionPerformed(ActionEvent evt) {
                ex.stAnimate();
             }
          };
          Timer t = new Timer(1, taskPerformer);
          t.start();
       }
    
       private static void whileLoop(final Example ex) {
          boolean b = true;
          while (b) {
             try {
                ex.wlAnimate();
                Thread.sleep(1);
             } catch (Exception e) {
             }
          }
       }
    
       public static void main(String[] args) {
          createAndShowGUI();
       }
    }
    Also, don't forget to set the JFrame's default close operation.

  14. #14
    Join Date
    Nov 2010
    Posts
    26
    Rep Power
    0

    Default

    Thanks. One more quick (random) question, if you don't mind - I didn't want to start a whole new topic - is there any way to accept two keyboard inputs at the same time?I'm trying to allow for a two player functionality if one player presses a key and another presses down a key then nothing will happen to the first player's paddle is there any way to get around this? I was thinking trying to somehow add the keyListener to act on the commands for the 2nd player on a different thread.

  15. #15
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    New questions should probably be in a new thread, but I've used key binding and a Swing Timer to allow multiple key presses. A Timer can be actuated on key press and stopped on key release. Don't try different threads for this as it would violate Swing's single thread rule.

Similar Threads

  1. Pausing game when user minimizes window
    By tecno40 in forum Java Applets
    Replies: 1
    Last Post: 12-29-2010, 06:37 PM
  2. Difference between Thread.yield() and Thread.sleep() methods
    By Nageswara Rao Mothukuri in forum New To Java
    Replies: 12
    Last Post: 07-30-2010, 06:37 PM
  3. how to reduce the thread sleep time and wake up the thread
    By baktha.thalapathy in forum Threads and Synchronization
    Replies: 2
    Last Post: 06-24-2010, 08:36 PM
  4. Replies: 0
    Last Post: 01-28-2008, 08:02 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •