Can't make new game until thread stops - java

I am building a game and I am trying to create "New game" button.
In the game I have thread that delays computer's move so I can see it step by step by using thread.sleep.
My problem is that I can't make a New Game until this thread is over.
If I manually stop it, I will get InterruptedException.
What can I do in order to do it?
My game is placed on JPanel which is placed on JFrame.
I tought that if I dispose the JFrame and create a new one, it will destroy the JPanel and all it's content and create a new one all over. but it's not working either.
Any suggestions??
Thanks in advanced,
Ron.

For stopping a Thread, see: https://stackoverflow.com/a/8581317/1178781
The InterruptedException is thrown if you stop a thread while it is sleeping. Just wrap the sleep call in a try...catch (with the catch doing nothing) if you do not want to handle this exception.
See the Java API: http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#sleep(long)
Also see: How to programmatically close a JFrame

Related

Java - How can I pause code without pausing a GIF animation in my GUI?

Currently I have a start menu for a game with a button which transform my menu background image from a PNG into a GIF after a button press. Now, I want my code to wait until the GIF animation is over. After that, it should continue normally (by opening a new JFrame with the actual game).
I've read some stuff about a swing timer, although I'm unsure of how to implement this as I am a Java beginner.
private ImageIcon a = new ImageIcon("a.png");
private ImageIcon b = new ImageIcon("b.gif");
class AddInterestListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
bgLabel.setIcon(b); //replace PNG with GIF
//This here is where I want my delay to happen without freezing the GUI
JFrame game = new JFrame(); //Actual game frame starting etc.
}
}
Any suggestions?
You can't use blocking methods like Thread.sleep() or Thread.join() in Swing EDT. This will freeze the UI as Swing EDT handles all the UI refresh events.
You must implement this with events, first event blocks the UI second unblocks it. If you know the GIF animation length you can use SwingUtils.invokeLater() to run an async thread with that will fire the event after a fixed delay.
[Edit] apparently there was already an answer and I don't know if that answer , or my answer for that matter, fits in your software. One thing I can say for sure is that my method allows you to use custom scaling algorithms etc instead of the built-in one (but you probably don't need that either).
Afaik it is not possible to monitor the progress of a GIF displayed using SWING. You'll have to make your own GIF decoder/animator in order for you to 'detect' when the GIF is about to loop or end (yes animated GIFs can end).
For that I used a 3rd party loader from https://github.com/DhyanB/Open-Imaging to obtain the individual frames and timing information. No guarantee that this is still the best library out there as I found this little over a year ago.
From there on you'll need to write your own animator using javax.swing.Timer or similar.

How to completely close JPanel without closing the whole program?

I want to close/terminate/throw away a JPanel that was created by a line of code (so it's completely terminated, not just hidden and running in the background as setVisible(False); does) and without closing the whole program as System.exit(0); does.
How can I do that ?
I want to close/terminate/throw away a JPanel that was created by a line of code (so it's completely terminated, not just hidden and running in the background as setVisible(False); does) and without closing the whole program as System.exit(0); does.
There's nothing wrong with simply calling setVisible(false) on the JPanel, or better, swapping it for another via CardLayout.
It appears that you're looking for some micro-optimization, but you're not going to get much by chasing this. Make it non-visible and move on..... unless of course there are more details about your code and your problem that we're currently not aware of, and if so, then please let us know.

When I dispose and reopen a JFrame, it doesn't show anything

I have a fairly simple Java Application I created with JFrames. There is more than one JFrame in my program. I have a menu launching at the beginning of the program. After going through the menu, I have the menu JFrame disposed.
The main JFrame has a menu button that should launch the exact same menu at a later time. However, when you launch the menu from inside of the ActionListener (when you press the menu button), the JFrame doesn't launch properly. None of the components show up and colors are off.
However, when the menu is launched from outside of the ActionListener, the JFrame shows up perfectly. I have tried multiple methods to fix this, but none of them have worked.
My full program code is available by clicking here.
The main class is "LetsMultiply5.java". This class also sets up the ActionListener.
The JFrame causing the problem is "MenuWindow.java".
"LetsMultiply5.java" calls the "Booter.java" class, which then calls the "MenuWindow.java".
"MainWindow.java" is the JFrame that has the "Menu" button.
For proof, "SpeedModer.java" calls the menu window after it has been disposed, and works.
================================EDIT================================
Also, I'd like to let you know that I realize my code is a little bit messy. I am not sure how else to write the code for this program.
I am forced to use Thread.sleep(x); because the Swing timers aren't what I am looking for. The Swing timers activate an ActionListener when the timer goes off. I need a system that will wait a second before continuing on with the code.
I realize that the while (repeater==0) loop with ActionListeners inside of it seems crazy, but that was the only way I could get it to work. If I put a single ActionListener and just had the while loop do no code inside of it, nothing happens when I press the button.
I would, as MadProgrammer mentioned:
Advice: Scrap your current approach and start again.
However, the way that I have my program currently coded is the only way that I know how to get what I need to do done. I read the tutorials, but still don't know how to improve the code in the way that you told me.
I thank everyone for trying to tell me to improve my bad "Java grammar", but as far as I am concerned, I am not going to continue this program for the next 20 years and make my millions off of it.
I have looked at the Swing timers before and I understand the whole new Timer(speed, this); concept, but I don't understand how this would make my code any better.
If anyone would like to show me how to fix my ActionListeners or Thread.sleep(x); lines, please tell me. Thank you.
You're blocking the Event Dispatching Thread with Thread.sleep(3000); - Don't do this, it will prevent the UI from been painted
See Concurrency in Swing for more details about the problem and How to use Swing Timers for a possible solution
You may also want to consider having a look at The Use of Multiple JFrames, Good/Bad Practice? and consider using CardLayout or JTabbedPane
If you need to block the user temporarily (to display a error message or gather important details), consider using a modal JDialog. See How to Make Dialogs for more details

Is it possible to stop a certain thread from running?

I've been coding a simulation that has a JFrame GUI for parameter input, and a separate JFrame that runs an animation of the simulation.
I update the animation together with the simulation, so the call to repaint comes from the function runsimulation()
I have added an EXIT_ON_CLOSE for my main GUI frame, and while the animation is running I can close the frame and it doesn't pop up again, but I want to know if it is possible to shut down the simulation thread when I close the animation frame.
Because currently when I close the frame the simulation keeps on running in the background and finishes properly, but I'd like the close event on the animation frame to be a "cancel simulation" as well.
You have two choices here. One option is to make the running thread into a "Daemon" thread. This means that the thread will not keep the program running, so if you close the JFrame and exit the application it will terminate immediately.
Be aware that the long running thread could potentially get terminated abruptly and in the middle of processing things though.
The (probably better) way is to call interrupt() on the thread and have the thread check isInterrupted() at regular intervals and exit cleanly if the flag is set.

JButtons don't imediatly change on mouse event

I'm using the java swing library to develop a board game called DAO.
The problem is that after the human player makes its move, by clicking on the JButton with the piece image that he wants to play, I call the computer AI routine but inside the mouse event function. By doing this only when the function returns, the computer ends its turn, do the JButtons refresh their Images (setIcon comes in).
I'd like to know how can I force the JButtons to change their image at the moment they are clicked and not only when the mouse event function ends (as I need to handle data inside it).
I've tried all of this
myButtons[i][j].setIcon(xIcon);
myButtons[i][j].revalidate();
myButtons[i][j].repaint();
myButtons[i][j].validate();
None worked.
Thx in advance
You may want to try putting the action performed upon clicking the JButton into a Swing worker. This will allow the task to go on in the background, while the user can still click other buttons, etc.
See http://java.sun.com/docs/books/tutorial/uiswing/concurrency/simple.html.
There is a single thread used for all Swing activity.
Here's the process.
One event appears on the event queue
it is pulled from the queue and executed by The AWT Thread
Any new events created while this is executing are placed on the queue to be held until the currently running AWT event returns.
The event executing returns and the next event on the queue is dequeued and executed.
This means that if you need to do anything that takes more than, say 1/100 of a second or so, you shouldn't do it any thread started from a swing event. Instead, spawn your own thread and return the swing thread to the system so the GUI can be updated.
Now, your thread MUST NOT update any GUI objects! If you need to update a GUI object, use invokeLater to place your code back on the AWT thread.
New Java programmers not conforming to this rule and executing tasks on the AWT thread is almost certainly the biggest reason people think Java is slow.

Categories