Swing timers and time consuming task - java

I´m developing a Swing application. I need to run some tasks in background that, as a result, need to display messages on the TrayIcon. Those tasks must execute repeatedly, after some fixed delay, so i research and found Swing Timers as a good option. However, at the same time those tasks can be time consuming, and i don´t want that the GUI freezes or something like that (so, in order to fullfill this last requiriment i should go with Worker Threads instead). The thing is that worker threads don´t allow me to execute this tasks with some fixed delay and "forever".
I don´t know how to solve this, so any help would be appreciated :)

Have the actionPerformed of the Timer create a SwingWorker for the actual work.

you needn't create any extra multithreading support. timers create a new thread for running the commands in actionPerformed. alternatively you may also use 'java.util.Timer' as your timer. it is easier than swing and it also creates automatic threads each time you run.
import java.util.*;
after this you may add
Timer t=new Timer();
t.scheduleAtFixedRate(new TimerTask(){
void run(){
// your codes to perform
}, /*time in miliseconds*/);
this may solve your problem

You can create your task queue.
Create a Timer, that will shedule your task to some executor. (like ThreadPoolExecutor). At any delay, periodically, an so on.
Register a listener to task completion.
Executor will work with task on background.
When task is ready, notify main application via callback.
Do not work with simple threads. Java has a lot of concurent machanics, like Future and Executors.

Related

How to utilize SwingWorker and/or Timer?

I have been working on a program and am currently trying to resolve an issue. The program's purpose is to read through records from a database, pull information upon a certain trigger, and then display that information the GUI. The problem here is getting that data from the database to appear in the GUI, allow for some time for it to be represented on the screen, and then do the same for the next one and loop through.
I can get the data and put it on screen in the GUI, but my problem lies within allowing for that pause.
I have tried Thread.sleep but I have read that it is discouraged to do so.
What seems to be recommended is utilizing SwingWorker and/or Timer. I have spent a good amount of time studying these two but I am having difficulty fully understanding it and being able to apply it to my program. Given my problem and my program's purpose, can anyone help explain the significance of SwingWorker and Timer?
Timer executes in the EDT and the SwingWorker makes work in another threads. I really like this example Swing Worker example
Note that the Swing timer's task is performed in the event dispatch
thread. This means that the task can safely manipulate components, but
it also means that the task should execute quickly. If the task might
take a while to execute, then consider using a SwingWorker instead of
or in addition to the timer.
Caveats:
All interactions with the UI, updates, creates, should be done from within the context of the Event Dispatching Thread.
javax.swing.Timer
The Swing Timer is a special timer that allows you to setup a periodical callback that is guaranteed to execute within the context of the EDT
SwingWorker
SwingWorker is solution desinged to make a UI developers life easier by providing the mechanisms for running code in the background while providing easy (at least easier) mechanisms for synchronizing updates to the UI within the EDT.
For your problem, I would recommend the use of the SwingWorker, as you can pause in the background without effecting the UI's responsiveness
SwingWorker worker = new SwingWorker<Object, Object> {
public void doInBackground() throws Exception {
while (!loadingDone) {
Object data = loadMoreData();
publish(data);
}
// This only matter if you actually care about the result
// of what has being processed here...
return null;
}
public void process(List<Object> chunks) {
// Now in the UI...
}
}
Check out...
SwingWorker JavaDocs
Worker Threads and SwingWorker
For more details...

What is the most passive way to create a timer loop?

For those of you need to know, I'm writing a plugin for CraftBukkit, which is a modded version of Minecraft, and I'm a beginner level java programmer. I have what I think is a really basic question.
I'm trying to implement a countdown that executes methods to send messages to players every second for 20 seconds.
Obviously, I can't simply create a loop that loops for 20 seconds, because that loop will freeze the main thread until it finishes, which is unacceptable. (There is a lot of game code executing)
What are some approaches to creating a loop that will run passively or without halting the main thread?
The only thing I can possibly think is creating a new thread to run the countdown in.
Surely there is a simpler way to do this?
So you aren't confused, the countdown isn't initialized as part of some main loop, its initialized linearly by a user command listener, but its code executes in the main loop. What I mean by that is I need to actually START a loop that checks time, because this code is only executed once.
Sorry if I'm not being clear or making sense.
I would recommend java.util.Timer if you are not using Swing for GUI/Graphics (not familiar with CraftBukkit, so that will be up to you to determine). In particular, look at forms of schedule which allow a task to be repeated at fixed intervals.
javax.swing.Timer is similar. The biggest difference (aside from the interfaces used to respond to timers being triggered) is that javax.swing.Timer utilizes the EDT (event dispatch thread) to run events. If you're using a Swing GUI, this thread is already present and running and you want to use it. If you're not using Swing or AWT, then this is extra overhead that you don't need.
You would use a java.util.concurrent.Executors.newSingleThreadScheduledExecutor() and conveniently schedule a countdown task at 1-second intervals.
Alternatively, if you task must run on the Event Dispatch Thread (the "GUI thread"), you'll be better served by javax.swing.Timer.
Try javax.swing.Timer:
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();

Scheduling multiple tasks using timers

How can I schedule multiple tasks using java.util.Timer. I want to read multiple files using timers. I think I have to give each file a different TimerTask so that one file gets one instance of TimerTask and other file gets another, but I don't know how to do it. Please help. Thanks in advance. Here is what I'm doing:
Timer timer = new Timer();
// repeat the check every second
timer.schedule(fileWatcherTask, new Date(), 1000);
As javadoc of Timer class indicates your tasks should take very few time. In this case you can forget about time clash. If your tasks take more then 0.1 seconds run them in separate thread. I mean use Timer as a trigger that just makes task to start in separate thread.
you can also use quartz scheduler for that refer http://www.mkyong.com/java/quartz-scheduler-example/
if you want to use timer class see the example in following image
refer link for more details

Sleeping in a SwingWorker?

I need to feed test data to a Swing interval over a time period. The data set is long to parse, so I'm using a SwingWorker to parse it in the background. When it comes to feeding the data to the GUI (say, one item per second), I could start a Timer from the SwingWorker, but this seems overkill. Any reasons not to sleep from within the SwingWorker itself?
Cheers
Since SwingWorker doesn't run on the EDT, sleeping within is perfectly fine.
SwingWorker is designed for situations
where you need to have a long running
task run in a background thread and
provide updates to the UI either when
done, or while processing.
In my opinion, a Timer in addition to a SwingWorker would be overkill. Instead, just publish the parsed test data whenever possible, even at irregular intervals.
While you make the SwingWorker sleep it will not be loading data. If that is desired then this approach is fine.
If you want to keep loading the data and just pace the feeding to the GUI then it seems like a better design would be to start a Timer in the GUI that would check and pull new data from the worker at an interval, instead of the worker having to make invokeLater calls back to the GUI.

Issues with Swing timers

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."

Categories