"Build Automatically" function with Swing - java

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.

Related

delay in an java applet program without using threads

Is it possible in java to make the program to sleep or wait for a particular time peroid ?
As in C++ we do delay(1000);.
I am writing a java applet which does not include threads, but I want it to delay the execution of some statements. Its a clock(Digital) applet. so I need to make part of my applet code to delay for 1 second.
You don't want to do that. sleeping for a second in the Event Dispatching Thread will prevent any event processing during that time. One second may not be that much, but in general this is not a good practice.
What you want to do is setup a timer with a 1s period.
Yes. It is possible. Do a little research into the Thread.sleep() method as well as Timers as well as...

Correct design to prevent blackscreen issue in JFrame

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.

About the EDT (Java)

I have read a number of articles on the internet about when something should run in the EDT, and when it shouldn't. But I'm still not sure I understand, so I'd like to ask a few question about this:
What pieces of code are going to run by default inside the EDT?
What pieces of code are going to be run be default outside the
EDT?
When should I use InvokeLater() so something that by default would
run outside the EDT, will run inside it?
When should I prevent a piece of code from running (by default) inside the EDT, by creating a new thread and putting that code inside it?
Thanks
All the code executed by an event listener.
The code in your main method, the code executed inside a thread that you explicitely started, or that has been started by the usage of a Timer or SwingWorker.
When creating a Swing GUI in your main method. Or when you want to interact with a Swing component (or its model) from inside a background thread.
When this piece of code is blocking (like long IO) or is taking more than a few milliseconds to execute. All the code executed from inside the EDT prevent this thread from doing its main job: repainting the GUI and reacting to events.
First of all thank you so much for editing and formatting your question very well. It helps a lot when answering your question.
Also i have to admit i am not 100% sure about my answers, so guys: feel free to correct me if i am wrong.
Everything which changes your graphical user interface.
Not quite sure about that.
If you need to update your gui with the time intensive calculations.
For example if you want to show the numbers from 0to 100000000 in a
JLabel.
Everything which would block your gui from user interaction because
it takes a lot of time, for example some calculations with a lot
of datasets.. But you need to make sure to access values only from
one thread or to synchronize the threads with volatile and
synchronize...

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();

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