I have 3 timers running on my application which takes care of different action. Timer 1 will deals with automatic logout of the application, timer 2 deals with updating a table, timer 3 deals with updating the color of swing buttons. First timer uses the calculation based on the variables and its values, second and third timers works out of MYSQL queries.
Now when i run this application on an average performance machine the application is not moving .I need to wait for few seconds to a normal click to happen or a window to open. Is it something to do with the timers ? If yes do I have any alternative suggestions to get rid of this timer problem?
It could well be the timers, if they are performing considerable work when fired. It's not usually a good idea to use swing timers for long-running tasks, since they will block the EDT and freeze the UI.
Here are some suggestions to avoid this:
Use a java.util.Timer rather than the swing timer. This will run the database code on a background thread, avoiding blocking the event queue.
Continue to use the swing timer, but have the timer action simply start a SwingWorker to perform the task. This gives the benefit of background processing with the ability to post updates to your UI, if it's a operation that takes more than a second or so to execute.
The problem isn't how many timers you have, but how long each timer takes to do it's work, since the timer's actionPerformed method is run on the swing event thread, meaning that while a timer is doing it's thing, no UI updates can happen.
That should not be related to the Swing timers, that is something else in your code. You need to debug the application to see what is causing the delay.
From what I remember, swing timers fire events on the same thread used for rendering, so you dont tend to get exceptions due to incorrect thread interractions - I have used them in the past for animations without issue - I suspect the answer lies elsewhere in your code. Have you tried profiling the code at the point where you are having an issue?
Is it OK if I run 5 timers at the same time?
All instances of javax.swing.Timer "perform their waiting using a single, shared thread." The limit occurs when the tread becomes saturated. As a practical matter, each Timer may have multiple listeners, but "the handlers must execute quickly to keep the GUI responsive."
Related
The context in this case is creating a game loop that integrates with the model and updates the view once per frame. Listeners interface with the controller, controller updates the model, repaint() handles the view update from model (on an overridden paintComponent() on a JPanel).
Appropriate answers include "never", haha.
This is a question I would think there is a preferable answer to, so it shouldn't be in violation of the rules.
I'm asking this because the main game loop is a Runnable instance which I'm locking to 60FPS (roughly, at the moment. Few milliseconds of difference as the current render loop is very inexpensive and 1000 / 60 loses a millisecond or two each cycle). Not locking the frame rate via Thread.sleep() causes something like 2.3 billion frames per second (apparently), which understandably thrashes my CPU. Not a problem per say, more of an example why frame-locking is desirable.
However in every single answer I come across, every single comment, the majority of them say "why are you even touching Thread.sleep() you don't want the EDT to sleep". Which is understandable if you have flaws in your loop that cause non-responsiveness, but this isn't the case in the applications I've put together yet. I've read all of the associated Event Dispatch Thread documentation, how to use Swing Timers, etc. I've even used Timers myself, and SwingWorkers too (in one case to delegate icon loading to the background to prevent blockers on GUI instantiation).
Is there even a preferred method here? I haven't come across many / any standalone game solutions in Java that don't rely on libgdx.
Use Swing Timer when:
You don't want to throttle or control the time between updates. Swing Timer only guarantees "at least" duration (it will trigger AFTER a given delay) and the length of time in which the event is processed may effect the amount of time before the next update.
So, if you have a delay of 16ms (rough 60fps), your callback takes 20ms to process, the time between the first and second callback may actually be 36ms
You would also use a Swing Timer when you want to use the existing (passive) rendering system supplied by Swing
Swing Timer is relatively simple and easy to use, it triggers callbacks within the Event Dispatching Thread, making it easy to modify the state of the game and schedule an updates to the UI, this reduces possible thread race conditions (between the painting and the updating)
Use Thread#sleep when:
You want more control over the timing, producing variable delays. In order to do this, you will need to manage your own Thread
This approach is more suitable to more complex animations and when you are using a BufferStrategy to control the output.
The reason for this is, with a Thread approach, you run the risk of race conditions between your thread changing the state and the paint cycle painting it. Instead, you will need to take control of the paint process yourself, so you know that when you paint something, the state does not change while you do it.
Using this approach provides more flexibility and control to make decisions about when things get done (and how), but increases the complexity and your responsibility for doing things
Thread.sleep is almost certainly used in the implementation of javax.swing.Timer and java.util.Timer, but these days the only real use case of Thread.sleep is for creating a timeout on something, typically an I/O connection. I used this once at work way back for delaying updating the GUI after requesting the users messages until a certain amount of time past from the last message sent from the server. I also used it here
In your case, you should be using the swing timer for your game loop
In my application I have a main frame window GUI, that launches a task in an executor service.
The submitted task generates output and stores in a file on Disk.
As soon as the o/p is generated GUI (observer) is informed of the o/p generated.
Here the problem is I am keeping a wait loop inside the main frame and as soon as a notification is received, the main panel is repainted on the main frame.
For small tasks this works fine, but as the size of the threaded task increases. The wait loop time increases and the GUI main window turns black till computations are done.
Can you please help me in correcting the design. Also How can a SwingWorker thread help in this case.
The wait loop time increases and the GUI main window turns black till computations are done.
Then you long running task is executing on the Event Dispatch Thread (EDT) which prevents the GUI from repainting itself. You need to execute the long running task in a separate Thread. A SwingWorker is a separate Thread which has an API that also allows you to execute code on the EDT as required, for example when the code finishes executing or when you have intermediate results.
Read the section from the Swing tutorial on Concurrency for more information. You can always search the forums for example of using a SwingWorker.
1)
Wait loops are the bane of all that is GUI. They are OK in other threads you have spawned, tricky in Executors (as they sometimes have limits on number of Threads, depending on which you use), and are completely out of the question on the EDT. That is the reason for your "blackscreen"
2)
Instead of using a custom (I assume it's custom) signal protocol and a wait loop, you could use one of the utility classes in Swing. For example, SwingUtilities has a couple of nice methods - invokeLater and invokeAndWait that take a Runnable and execute it on the EDT as soon as they can. Using this instead of the signal you have will allow you to not block the EDT and make your GUI responsive.
3)
If you really want to use a SwingWorkeryou may want to look through the documentation for it. It is essentially a way to do background tasks and report progress or completion/result to the EDT. Currently it uses an ExecutorService with 2 background threads, so having a lot of long running tasks on them is not a good idea (they will block each other). When creating a SwingWorker you would specify the method to be ran in the background, the method to be ran on the EDT when intermediate results are available, and the method to be ran on the EDT when you're finished either successfully or in error.
4)
This does not pertain to the question at hand, but if you ever get into a situation where you need a wait loop in the EDT and cannot avoid it using another design or technique, you can always switch to using a Timer. It can be setup to be called every x milliseconds without blocking the EDT and turned off once you are satisfied with some condition.
At the moment, I am working on a version of Conway's Game of Life for my own amusement. Up to this point, everything has gone smoothly, but just as I was testing some of the final parts, I noticed an irritating error. The main body of the code takes place inside of a while loop that is controlled by the number of 'generations' of the game the user would like see. While this loop is executing, the JFrame's red X refuses to respond and I am at a loss as to why this is.
Area where I am encountering this issue:
public void run(int steps) throws InterruptedException{
int a = 0;
do{
step();
myDisp.update(myDisp.getGraphics());
Thread.sleep(delay);
a++;
}while(a < steps);
}
I would suggest you to put this kind of processing in a separate thread.
As long as you keep it in the main body of your code, Swing components will not respond to any user interaction as long as the loop is running.
In this page you can find some good practices regarding asynchronous operations in Swing applications. I would like to highlight one of the topics:
Rule #2: do not run time-consuming operations on the event thread.
I'll keep repeating this: Swing uses a single thread for all GUI events. If your event handler is uploading a multi-megabyte file across the net, those events will be delayed until you're done. There is a balancing act involved with this rule: some operations (such as getting the size of a file) are so fast that they won't interrupt the user. However, that's not a reason to be cavalier, because some day your user will be getting the size of a file that resides on a fileserver that has an intermittent network connection.
This other page also shows an example of how to handle long-running tasks in a Swing application. You may also want to have a look at the SwingWorker class.
By default your while loop will be executing on the Event Dispatch Thread (EDT), which handles all GUI operations. You should never execute long running tasks on the EDT for this reason - the GUI will lock up, since you're not giving it any free time to handle user input! However, you must execute any code that touches the GUI on the EDT. There's a special method, SwingUtilities.invokeLater(), that will do this (take a Runnable and invoke it on the EDT.)
So in your example you would create a new thread and execute it, this thread would contain your while loop, and the myDisp.update() call would be wrapped in the above method to ensure it was still on the EDT. The alternative (neater) solution is to use a SwingWorker, which provides a nicer interface for accomplishing the same thing.
Your long-running while loop is running on the Swing Event Dispatch Thread or EDT, typing it up, and preventing all Swing graphics and user interactions. Solution: use a background thread for your long-running tasks.
Please read: Lesson: Concurrency in Swing
for more details on this and for how to use a SwingWorker.
I am really confused about this . Java has two Timer classes, one under swing , and one under util ... why is that? Which one should I use if I want to simply run X every Y seconds? Does this mean if I'm building a GUI I have to use the swing version for a timer?
thanks!
Here is the difference between javax.swing.Timer and java.util.Timer:
javax.swing.Timer
suitable for simpler cases, using low numbers of timers (say less than a dozen)
runs ActionListener objects on the event dispatch thread
can directly update the GUI, without using EventQueue.invokeLater
if the task runs entirely in the event dispatch thread (that is, if it does not spawn a worker thread), then the GUI will remain responsive only if the task does not take very long (say under 300 milliseconds)
java.util.Timer
more scalable than javax.swing.Timer, and with additional scheduling features
runs TimerTask objects on a private thread
needs to use EventQueue.invokeLater to update the GUI
You can use Swing timers in two ways:
To perform a task once, after a delay.
For example, the tool tip manager uses Swing timers to determine when to show a tool tip and when to hide it.
To perform a task repeatedly.
For example, you might perform animation or update a component that displays progress toward a goal.
Here is the sources for above information http://www.javapractices.com/topic/TopicAction.do?Id=160 and http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html
Which one should I use if I want to simply run X every Y seconds?
Depending upon what you are interacting with. If you are interacting with GUI then use javax.swing.Timer , else use java.util.Timer.
Does this mean if I'm building a GUI I have to use the swing version
for a timer?
YES
Swing version is for rendering swing components. If you just need to time, use util.
You're kind of correct. It's recommended that if you're going to do UI work that will be affected by a timer you should use the swing component. The util timer cannot set UI elements itself. Here is a nice comparison.
In v 1.3, another Timer class was added to the Java platform:
java.util.Timer. Both it and javax.swing.Timer provide the same basic
functionality, but java.util.Timer is more general and has more
features. The javax.swing.Timer has two features that can make it a
little easier to use with GUIs. First, its event handling metaphor is
familiar to GUI programmers and can make dealing with the
event-dispatching thread a bit simpler. Second, its automatic thread
sharing means that you don't have to take special steps to avoid
spawning too many threads. Instead, your timer uses the same thread
used to make cursors blink, tool tips appear, and so on.
You can find further documentation and several examples of using
timers by visiting How to Use Timers, a section in The Java Tutorial.
For more examples and help in choosing between this Timer class and
java.util.Timer, see Using Timers in Swing Applications, an article in
The Swing Connection.
From the official documentation.
If you have a simple, quick task that needs to interact with the swing framework, then it is simpler to use javax.swing.Timer
For almost every other case - even GUI appliactions you should use java.util.Timer
If you have a GUI then you have to handle integration with the swing event dispatch thread the same way any other task would by using EventQueue.invokeLater to update the GUI as mentioned above
Generally when you start, the first few timer events may seem quick and unlikely to effect performance, but as the requirements change, they will take longer and more will appear and the demands of the GUI itself will grow. It is a better practice to avoid the rework by just starting outside the swing environment - otherwise your GUI will quickly appear "sluggish" or "unusable"
How should I implement a function like that on my Swing editor?
I was thinking of a thread started on a releaseKey event. This thread should have a timer of a second. Every time I have the releaseKey I either start the thread or just reset the timer if it is already running.
I'm not convinced though. It seems like too heavy on the UI.
How should I do it?
A Timer starting/stopping every second is not a big weight on the UI at all. The "building" is what is going to possibly take some time. I think looking for a pause in keystokes is a fine solution.