Interactive background - java

I'm designing a game where you get to the edge of the screen the screen will shift to a new panel of the same map similar the first Zelda game. Which method would be more efficient and or effective, having a thread running using repaint() or would using javax.swing.Timer and calling super.paintComponet work better?

Usually for simple animations, you can use javax.swing.Timer But it looks like you are into a more complex game. If you continue to use swing.Timer and if your execution of the codes are not fast enough, it may affect the painting of your components causing your UI to be irresponsive.
You can construct a game loop and render according to the frame rate you wanted by invoking Thread.sleep(delay) via a worker thread remember do not run it in the Event Dispatch Thread, else your UI will also become irresponsive.

Related

Correct concurrency approach to swing animation?

I am about to write an animation in which a character on a JPanel moves left/right when the user presses (and holds) the appropriate keys.
Now, since I am new to concurrency I want to ask : should the code handling the animation (namely the method that will move and repaint the character as long as the key is held) be executed on a worker thread or the event dispatch thread ?
I read the tutorials on concurrency in swing, and it seems that stuff that changes the components (in this case it's painting JPanel) should be on the event handling thread, but on the other hand that would freeze all the other events as long as a key would be held right ?
For example a user won't be able to pause the game while he's holding the go-left key, if I understand this correctly. So which approach is correct and why? Or maybe there is totally different way to make such an animation ?
Thank you in advance!
All the Drawings Paintings need to be done on EDT thread. Never on any other Thread . Use
SwingUtilities.invokeLater() .. for your painting. You can do calculations like what will be the next postion of your character on Worker Thread. You won't have any unresponsiveness if you are doing creating and using Swing Classes on EDT. just Make sure that your computation is not too long. For Animation whenever you find the next positon of your Character just call
SwingUtilties.invokeLater to update changes on UI

Breakdown of Threads used by a JApplet

I've been spending a great deal of time trying to understand this. I created a JApplet that used Thread.sleep() in a loop to animate the applet. But when I tried to run the Applet the screen stayed blank. When I draw the animations in a separate thread and call repaint, the applet works perfectly. I've seen many explanations of why this happens but none have been very comprehensive.
What thread calls the paint method? And why can't that thread partially draw on the canvas, pause, then continue drawing? I've noticed that some Thread.sleep() calls work as expected, particularly when they are not in a loop.
UI needs to be repainted and this happens on UI thread.
Therefore you should not seize control of the UI thread - it seems that you are doing just this (animation loop with .sleep()).
You should return control of the UI thread (exit the function that you are in) so that it can be repainted.
Take a look at Swing Painting and SwingWorker to understand how to run a background thread to do some work and then update UI on UI thread.

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.

Java: Using multiple Threads to paint simultaniously on a JPanel

I have a JPanel on which I wish to have several threads painting "animations" on. An "animation" consists of a JLabel with an ImageIcon on it, which is being moved from one area of the screen to another area.
Now, problem is - I want several such animations to be portrayed on screen by those threads mentioned. Problem is - the JPanel's "paint()" method can only be trigged by one thread at a time - causing the animations to execute serially, instead of in a parallel way.
Any idea how to have several such animations on screen at the same time?
It is impossible to use multiple threads to do what you want. Swing Toolkit is single threaded
. The correct way to do it is to use one of the animation frameworks available:
Trident animation framework
TimingFramework
Swing is not thread-safe, thus it's simply not a supported use-case to do UI-related stuff from several threads simultaneously.
Go for the model-view-controller (MVC) pattern:
Let all threads update a (thread safe) model.
Whenever there is an update of the model, invoke repaint.
repaint() will schedule the UI-thread to call the proper paint-methods.
The paint-method should then simply read the state of the model, and draw the component accordingly.

How to use a delay in a swing application

I am building a swing application. At some point, I have to start an "animation":
...
jpanel1.setBackground(Color.Black);
Delay(milli)
jpanel1.setBackground(Color.White);
...
and so on.
The gui itself and all the logic behind it work.It is just this time depended color-changing that does not. I have read, that swing is not thread safe, but all the examples I found showed me how to start another thread (for example in the background) but never how to stop the current swing-gui thread.
Edit:
The application should work as following:
configuration files are read, jframe is set up.
some simple questions are beeing asked
a dialogue is opened, which explains the animation.
after the user clicked "ok" the animation - some color flashing - is started. the color and the delay between the color-changing is depended on the configuration
another dialogue is opened and the programm continues -> new jpanel inside the jframe, buttons and so on.
the online thing that does not work are the delays between the color-changing. I understand now why it does not work and I am trying to build a timer, which activates a actionlister, which then changes the color and stops the timer... it just seems so much work for a simple delay... and I have to reorganize the entire animation in the application.
Take a look at: https://timingframework.dev.java.net/
and the samples that come in http://filthyrichclients.org/
They provide some very good information on how animation work and using the Timer framework. You'll have a good understanding of how it works.
I did a sample animation here with Swing after reading those:
count down demo app http://img580.imageshack.us/img580/742/capturadepantalla201004wd.png
Java application featuring blog.stackoverflow.com page ( click on image to see the demo video )
But I'm not even sure what is what you want to achieve.
EDIT
I read about the timing framework to understand better what is all about, but I actually didn't use it ( it is useful to create animations with no linear times - ie no every second as mine, but things like 1, 5, 3, 2 seconds )
The code I'm using in the demo above is exactly this:
final Timer imageTimer = new Timer();
imageTimer.schedule( new TimerTask() {
public void run() {
changeImage();
}
}, 0, 10000 ); //<-- every 10 seconds.
The animation for the "stackoverflowing" and the count down use a similar approach.
You do not want to stop the GUI thread, even if you want to have a flashing effect. This is because other basic actions, like repainting when the GUI is hidden by other windows, will be stalled. Take a look at Timer. It will allow you to have an event fired on an interval and you can handle that, in the GUI thread, in your actionPerformed method.
You will want to use the javax.swing.Timer class and not the java.util.Timer class.
The later is preferred when you need general timing the former is preferred for UI updating/changes.
See http://java.sun.com/docs/books/tutorial/uiswing/misc/timer.html
You may also want to look at https://timingframework.dev.java.net/.
Do the timer on another thread and when the timer goes off it can send an update message for the animation to draw the next frame.
Another consideration is the delay itself. Don't pick a fixed delay-interval. Old games used to do that and they become unplayable on faster computers. Instead what the newer games do is use the speed of the current CPU to figure out how many update events they need a second at runtime, call it a 'delay-factor', and is set when the program starts up. . The timer uses the delay factor so the animation displays correctly even on machines of different clock-speed.

Categories