Results 1 to 15 of 15
Thread: Pausing a Thread
- 05-20-2011, 05:05 AM #1
Member
- Join Date
- Nov 2010
- Posts
- 26
- Rep Power
- 0
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.
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?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(); } }
Thanks.
- 05-20-2011, 05:32 AM #2
Read this:
Java Thread Primitive Deprecation
-
Why not simply show a modal dialog such as a modal JDialog or a JOptionPane?
- 05-20-2011, 05:48 AM #4
Member
- Join Date
- Nov 2010
- Posts
- 26
- Rep Power
- 0
@ 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.
-
Also: Is your game loop as a Swing Timer? If so you could simply call its stop() and restart() methods as desired.
- 05-21-2011, 08:16 PM #6
Member
- Join Date
- Nov 2010
- Posts
- 26
- Rep Power
- 0
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:
and I changed it, when trying out Swing Timer to this:Java Code:while(b){ Thread.sleep(1); animate(); }
Java Code:ActionListener taskPerformer = new ActionListener() { public void actionPerformed(ActionEvent evt) { animate(); } }; t = new Timer(1, taskPerformer); t.start();
-
1 ms is probably too short of a time slice for a Swing Timer (or any Java delay/sleep).
- 05-21-2011, 08:25 PM #8
Member
- Join Date
- Nov 2010
- Posts
- 26
- Rep Power
- 0
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.
- 05-21-2011, 09:07 PM #10
Member
- Join Date
- Nov 2010
- Posts
- 26
- Rep Power
- 0
Consider the two approaches here - one is commented out.
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.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(); } }
-
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.
- 05-21-2011, 09:19 PM #12
Member
- Join Date
- Nov 2010
- Posts
- 26
- Rep Power
- 0
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 09:24 PM. Reason: Clarification
-
Here's your code, but with both loops running concurrently, and with a smaller increment of 0.1:
Also, don't forget to set the JFrame's default close operation.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(); } }
- 05-21-2011, 10:18 PM #14
Member
- Join Date
- Nov 2010
- Posts
- 26
- Rep Power
- 0
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.
-
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
-
Pausing game when user minimizes window
By tecno40 in forum Java AppletsReplies: 1Last Post: 12-29-2010, 05:37 PM -
Difference between Thread.yield() and Thread.sleep() methods
By Nageswara Rao Mothukuri in forum New To JavaReplies: 12Last Post: 07-30-2010, 05:37 PM -
how to reduce the thread sleep time and wake up the thread
By baktha.thalapathy in forum Threads and SynchronizationReplies: 2Last Post: 06-24-2010, 07:36 PM -
If JNI thread call the java object in another thread, it will crash.
By skaterxu in forum Advanced JavaReplies: 0Last Post: 01-28-2008, 07:02 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks