Event delay in Java program - java

In my Java program, I have a text component that can fire events in rapid succession. Since I'm doing a lot of background processing whenever the text is modified, this can noticeably decrease the responsiveness of the text component. That's why I'd like to introduce a delay: When the text component starts firing, the attached listener should wait for a certain amount of time (e.g. 1 second) until the text component has "calmed down", and then start its own processing.
I know that it's relatively easy to roll my own simple delay mechanism that does what I want, but I'm wondering if the java.util.concurrent package (or some other system package) has a ready-made solution for this. I've been looking into
Executors.newScheduledThreadPool(int)
but this doesn't seem to be what I'm looking for, since this will fire all incoming events - I only want exactly one event to make it through to the listener after the delay.
Thanks in advance.

You're very close to the solution.
What you want is to schedule a firing of the listener to happen one second in the future, but to cancel that when the next event arrives (if it hasn't already happened) and reschedule. Using an executor is reasonable, but the key is that you need to keep around the Future object that scheduling returns, as it is that which you cancel.

Related

JFrame gets locked completely while method is running

I have a GUI(JFrame), with two Buttons and 1 Panel to show the result. One Button is to start the algorithm, one for stopping it. By pressing start, a method is called and it starts running. The runtime of this method varies from couple of seconds to 2-3 minutes, depending on the input.
The problem I have hereby is, by pressing the start-button, the GUI gets completely locked. I cannot press any button till the algorithm terminates. It would be great to be able to stop the algorithm and to visualize parts of the solution after a certain amound of time.
I checked every single line of the Frame, there is nothing that disables it.
//If needed I can provide code, but its pretty long and just some hints and reasons for the problem would be great and I try to fix it by myself.
thanks in advance.
Don't put long-running tasks on the EDT, or the Event Dispatching Thread. Use threading or a SwingWorker instead. Hopefully that's enough google keywords to get you started. :)
It sounds like your algorithm is running in the same thread as the UI components. You probably want to read up on Concurrency and Concurrency in Swing to better understand how to create threads, monitor execution, integrating these concepts with a Swing-based user interface, and so forth. At a very high level, you are going to need to somehow spawn a new thread when your algorithm starts and observe it for intermediate state changes to update the UI. You only want user interface related code running in the event dispatch thread.

java, calling a method after a modifiable delay

I'd like to ask you about the best solution/idea how to solve a following situation.
I'm developing an Android app which on one of screens has a set of buttons. After clicking on any of them a kind of config is posted to the server over http.
To prevent multiple clicks one by one which could result in concurrency problems I decided that after each click on a particular button there'll be a waiting interval of 30 seconds before a config is sent to the server. If another click on the same button happens before this 30 seconds are exceeded, then the execution of method is delayed for another 30 seconds - as long as no new click is performed, then the config will be sent.
I need an idea of an algorithm which would implement the mechanism above. What I know is that I don't want to start a separate thread for each click (too heavy for my app). A potential idea is to make a queue of events and send them in a loop but idea of a running endless loop in a thread (or Handler) also isn't my favourite.
Maybe there's a kind of mechanism in Android or J2SE in general, that allows to schedule an execution of method to a given time in the future but still be able to postopone execution for some additional time before 30sec rolled out.
thanks in advance!

How to write event buffer for Java Swing MouseEvent?

I have been trying to find a solution to this question for a while. What is the best practice for writing a swing event buffer? The idea is when triggering an action from a mouse gesture, such as 'mouseMoved', as the events may be fired many times, I only want to trigger the last call - for example,
if the mouse was clicked five times, while the first click listener is being executed, and four are queued, the next call will be the fifth one - all previous ones will be skipped.
It seems that I should be using the Executor class, as it can remove unsubmitted tasks, but I am still not quite sure. All help is appreciated!
user1291492 is right, this shouldn't happen at all. You should never run any code that could take longer than a couple of milliseconds to complete in an event handler. The SwingWorker documentation contains examples and explanations on how to do it. The most important quotes is
Time-consuming tasks should not be run on the Event Dispatch Thread. Otherwise the application becomes unresponsive.
To address the original question, there are two patterns I usually employ:
Use flags to mark actions that should be executed at some point in the future. When there's no other work for some time I check all the flags, reset them and perform the appropriate actions.
When scheduling work for a worker thread, hold a reference to it. Every time before scheduling new work, cancel the previously scheduled work. Most often used with CancellationTokens in C#/Async.

Java: How to interrupt a program partway through execution with a mouseclick

How would one go about implementing a mouselistener (or some other way, doesn't matter) that will handle a mouse click event at ANY part of the program? Preferably returning to the line it left off at when the click event handler method completes.
I am using swing. The 'context' is a GUI that constantly updates, but must respond to a mouse click from the user at any time with no delay. Indeed I do have experience with events, using and overwriting their handlers etc., not too in-depth I suppose but what i do know has been sufficient in anything until now.
I could not understand your first para, so my answer goes for your second para, if I understood that correctly. ;)
Swing follows single thread model. So, you should be updating the UI from Event Dispatch Thread (EDT). This thread is responsible for delivering the events to your code too, hence the name. If you are continuously updating an UI in a loop then that is going to keep the EDT busy and blocked. The end effect will be an UI which does not respond to user events. This because the events are getting queued and EDT can pick them and deliver them to your code when it becomes free.
Games typically encounter this kind of scenario. You might have noticed that games typically have one fixed rate of refresh which they call FPS (Frames Per Second). Typically maintaining 60 FPS is good enough. That is, you need to draw your UI 50 times per second, but right now it seems that your render loop (which updates the UI) is running continuously.
You need to have separate thread continuously running which is responsible for drawing the UI. This should draw into a buffer (Image). And then invoke repaint() on the UI element to be updated. That UI element's paintComponent() needs to overridden, so that it can copy the image in Image buffer and paint that on the graphics context.
Now comes the real trick. The loop which calls repaint() must do some arithmetic to make sure it does not go beyond drawing 60 times, i.e. looping 60 times, per second. If and when it does then it must call Thread.sleep(sleepTime), where sleepTime is the number of milliseconds left in a second after looping 60 times. It might happen sometime that your loop may take more than a second to complete 60 iterations, then don't just go ahead for next iteration, but call Thread.yield(). This will give other threads a chance to use the CPU, e.g. maybe your EDT. To make the matter more complicated, do not keep yielding always, so might want to put some logic to make sure that yield for only x consecutive times. This last scenario should be very rare, if at all. This scenario means the system is under heavy load.
Remember, repaint() is thread safe and allowed to be called from any thread. It schedules a paint() call on EDT. So, calling repaint() does not guarantee a paint. So, you may want to experiment with different values of FPS to find the one which suites you.
By the way, the trick of rendering to an in-memory Image is technically called Double buffer. This gives us the ability to render nice smooth animations.
Further reading:-
LANSim - Wrote this code a long time back. You can use this code as an example.
http://java.sun.com/docs/books/performance/1st_edition/html/JPSwingThreads.fm.html
Killer Game Programming in Java - This book is on this subject.
Have you looked at SwingWorker? It's a simple framework that lets you run computations in the background and periodically publish updates to the GUI thread.

Implementing java FixedTreadPool status listener

It's about an application which is supposed to process (VAD, Loudness, Clipping) a lot of soundfiles (e.g. 100k). At this time, I create as many worker threads (callables) as I can put into memory, and then run all with a threadPool.invokeAll(), write results to file system, unload processed files and continue at step 1. Due to the fact it's an app with a GUI, i don't want to user to feel like the app "is not responding" while processing all soundfiles. (which it does at this time cause invokeAll is blocking). I'm not sure what is a "good" way to fix this. It shall not be possible for the user to do other things while processing, but I'd like to show a progress bar like "10 of 100000 soundfiles are done". So how do I get there? Do I have to create a "watcher thread", so that every worker hold a callback on it? I'm quite new to multi threading, and don't get the idea of such a mechanism.
If you need to know: I'm using SWT/JFace.
You could use an ExecutorCompletionService for this purpose; if you submit each of the Callable tasks in a loop, you can then call the take method of the completion service - receiving tasks one at a time as they finish. Every time you take a task, you can update your GUI.
As another option, you could implement your own ExecutorService that is also an Observable, allowing the publication of updates to subscribing Observers whenever a task is completed.
You should have a look at SwingWorker. It's a good class for doing lengthy operations whilst reporting back progress to the gui and maintaining a responsive gui.
Using a Swing Worker Thread provides some good information.

Categories

Resources