Can't bring Java window to front when busy - java

I have written an image processing application with the GUI part written in Java and the number crunching part is written in C and is called via JNI.
My problem is that it takes 20 - 30 seconds for the application to process an image, and during this time the application disappears from the Task Switcher (the Alt-Tab thingy) and it is not possible to move the application's window to the front (this is my main concern). It is still possible to bring the application to front via the task bar.
Some more info:
The application isn't stuck or anything, I can see that it updates a progress bar as expected.
When the calculation is done, the application will show up the Task Switcher and can become the top window again. If I start a new calculation the application will disappear from the Task Switcher again.
The JNI call is made on a separate thread (from EDT), I have tried both the main thread and a created thread.
The EDT is not blocked. I have added printfs in WindowListener's and WindowFocusListener's methods and if the window lose focus the appropriate methods are called.
On Mac OS X the application works without problem.
This is on Java 1.6 on Windows 2003 Server.
First I thought that it was openMP that was doing something nasty with the threads, but turning it off didn't make any difference.
The JNI lib is compiled with MinGW 4.5.
It seems to me that Windows expects that an application answer/send some requests or else it will be thrown out of the Task Switcher. But I don't even know enough about Windows programming to even be able to google for an answer. Can someone give me some pointers?

I hate to say this as an answer, but are you sure that the number crunching is happening on a separate thread from the EDT? Because seriously, it shouldn't be behaving this way at all. There's a logical reason for it, I'm sure, and the most obvious is, you're blocking the EDT while you number crunch.
Maybe you think you're creating a new thread, but you're not?
Runnable r = new Runnable() {
public void run() {
ClassName.this.executeJNI();
}
};
new Thread(r).start();
Either that, or something in the number crunching is locking a resource that the EDT thread needs - but I don't even know what this could possibly look like.

Related

while loop not executed

I am developing a java project where an external microcontroller device is connected via serial port to the computer. I have a wait dialog in the java application, waiting for a command to execute on the microcontroller device. If the microcontroller doesn't respond within 10 seconds the application shuts down.
The problem is that some commands are too fast, and the microcontroller responds before the wait dialog becomes active. This causes the application to shutdown after ten seconds.
Here is the first idea I thought to wait for the dialog to be visible:
new Thread() {
public void run() {
while (!Main.mainFrame.waitDialog.isVisible()) {}
Main.usbManager.start();
}
}.start();
But the application is stuck in the while loop and the wait dialog is visible, but if I add some random sentence to the while loop, for example, System.out.flush();, it works and when the dialog is visible the program exits from the while loop.
How can I wait for the dialog to be visible?
Thanks
Most GUI libraries are single threaded. This means that calls to it might not be thread safe, you are never guaranteed to see a change. In particular boolean values can be inlined, so you can be sure after a certain point you won't see a change in the value.
If you use something which slows down the loop, it won't optimise the code for a while (this is unreliable) or has a memory barrier like System.out.flush() does, then this optimisation won't occur.
A better way to poll might be to use Thread.yield() or Thread.sleep(40) to save yourself some CPU as well.
I think there is a problem with the .isVisible() method and a general fail usage of while loop.
if I add some random sentence to the while loop, for example, System.out.flush();, it works
There is a question with a similiar problem "Why does while(true) loop just run once - Java" on the while loop
it runs with random method like System.out.println()
I think you should call something when the actual window in the other thread closes in this thread, so you don't have to wait.

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.

Java: Using Swing for programming games

I am relatively new to game development. I have been developing games and studying game development for 2-3 months now. I use Java.
I have always used Swing for my graphics (aka, the entire game is displayed on a JPanel, using a Graphics2D object). I had no trouble with this up until now.
Very recently, I came across a problem in my most recent project. Some method has problems with being called in consistent time intervals (sometimes it runs every 15-16 milliseconds, as it should, and sometimes it starts to run every 3000 (!) milliseconds).
I did some frustrating debugging and some research, and found out that the reason this happens is probably because I'm not handling Swing and threads right.
My entrie game loop runs inside the run() method of a thread (which is not the EDT). So I'm modifying Swing elements outside of the EDT all of the time. Obviously this was bound to cause problems.
When I found out this was the problem was, I thought:
"Hey, I'll simply use SwingUtilities.invokeLater() in order to run the gameloop inside the EDT!"
But then I remembered, that just as it's 'forbidden' to manipulate Swing elements outside of the EDT, it's also problematic to manipulate non-Swing objects from inside the EDT (I think... is this correct?).
If so, then I have no idea how to develop games in Java using Swing without running into weird problems.
My question is:
How can I develop games safely, using Swing? What would be good guidelines for me to be strict about in order to avoid problems involving Swing and threading? Any instructions every game developer who uses Swing should know?
This is very important for me to understand, since I really want to progress with game development using Java, but if I won't understand this, I'm always going to run into weird problems and won't be able to progress.
Thank you for your help
As long as you don't modify anything but the graphics drawn on the panel, you should be ok most of the time. Just like a single non-EDT thread works most of the time. As long as you don't add or remove any gui elements, don't resize anything, don't hide anything etc., Swing won't fiddle with its internal details enough to cause race conditions between your thread and the EDT - most of the time.
Even the case that the user minimizes the panel while your non-EDT-code is drawing on it will not cause crashes - the panel will probably throw away its old graphics context and start working with a new one, but the old context will remain valid until you release it (this is different from C++ where a delete invalidates the object immediately, which causes crashes when a different thread still uses a local pointer).
The problem is that if you're using the "i've yet to see a case where it goes wrong, always worked for me" approach, you're relying on undefined behaviour, and your code may start crashing as soon as you update your JVM.
The best thing you can do is set up your GUI on the EDT thread, run your game logic on a different thread, have a timer call repaint() on the panel every 20 ms (or whatever you want your frame rate to be). Then, have a class object that holds everything needed to display the current game state. Within a synchronized code block, let the panel's paint() generate its own copy of the object , and have paint() use the copy while the main thread calulates whatever the game needs. The main thread should use the same synchronized to write to the class object of course. That way, you get the maximum possible separation between the threads.
Just running your whole game thread on the EDT probably won't do, as anything your game does that might take a while will cause the UI to freeze. And anything that will need a lot of UI resources will affect your game logic.
BTW, are you sure your initial problem (long delays every now and then, but not always) isn't a result of garbage collection? I've seen this several times; if you aren't using the parallel garbage collector, GC might run for several 10's of a second and block everything else.

What does the common advice "start a thread in a service" even mean?

Service callbacks run on the main thread just like activities' (unless otherwise specified). I seem to stumble upon lots of advice here on SO that goes something like "start a thread in a service [to do work in the background]". That doesn't make sense to me. What does it matter if I start a thread from activity code compared to service code, just as long as there exists a started service component in the application process?
If the answer is what I think (that it doesn't matter) then it's a shame that people give the impression that a service object needs to be somehow related to the background thread.
The term "background" can be misleading when it comes to Services as it can have two meanings. Services are used, simplistically talking, to run tasks even if there is no Activity of your application running. To clarify, think of a music player; you want the music to still play even if the Activity is not running. That is the definition of background that doesn't have to do with Threads; you are running a portion of your application in the background because you do not have any visible component of your app on the screen (maybe some Notification but no full screen UI).
Now, lets say you want to download some data from the internet. As you might know, you cannot perform long running tasks in the UI Thread (as of API 11+ you will get a NetworkOnMainThreadException), so you need to use a background Thread. Let's say you do not want to use an AsyncTask to download the content because a Service is better suited for your needs. In this case, you will have to start the Service on a background Thread. That is the second meaning of background, which basically means creating a new Thread. Android provides a class that does exactly this; IntentService. It is a Service that runs on a background Thread and that it finishes itself when the given task is done.
It does not matter where you actually start a thread if the lifetime of that thread is reflected via your app process state: http://developer.android.com/guide/components/processes-and-threads.html#Lifecycle
Android does not care if there is a Thread running or not. Threads just run even when your app is considered an empty process "that doesn't hold any active application components." Don't abuse that, since users don't want that apps are secretly active although they look dead.
If you want (and you should) that Android does not kill you randomly although your threads are not done you have to make sure that you keep e.g. a Service in started state.
Creating a thread from within a Service (or just using IntentService) will primarily result in better, simpler & cleaner code. For example because a Service has a Context and you can't leak your Activity from there. You also get free callbacks from the system.
And leaks via threads are extremely easy.
new Thread(new Runnable() {
#Override
public void run() {
SystemClock.sleep(Long.MAX_VALUE);
}
}).start();
Will leak your activity if you just put it in e.g. onCreate because the anonymous inner Runnable keeps a reference to your Activity and will not release it until the thread stops running and is itself garbage collected.
In case you really know what you are doing, feel free to start threads in Activities and sync their lifecycle manually to some empty Service. I would not recommend it because it's unlikely to be less work to do that correctly.

Invalid thread access in SWT (progressBar help)

first of all I'm sorry about my English level, I'm Spanish.
I have a little problem with a progressBar in SWT application:
I have 1 Class(The application (SWT)) with all controls(progressBar, textboxes, combos, etc).
I have 1 Thread class who makes a file upload to an FTP server.
My problem is, I'm getting invalid thread access when I try to update my ProgressBar.Selection(int) from my UploadThread.
I'm trying hard to solve this problem, with Timertask(I wanna upload my progressBar every second), with events (an Event fires when UploadThread stay active) but it didn't work.
I hope you can help me with this problem.
When you use SWT, you must remember that all access to SWT objects must be performed in the SWT UI Event thread. There are a few exceptions to this, but they are typically noted in the API or rather obvious.
To make any changes to a control use the following template:
c.getDisplay().asyncExec(new Runnable() {
#Override
public void run() {
if (c.isDisposed()) return;
// ...
}
});
This will run the Runnable object in the event thread at the soonest possible time. You can even use this construct in the event thread itself, to postpone work for later - usually to get a rapid UI response.
The if (c.isDisposed()) return; construct is here to guard against the situation where the control is disposed in the time between asyncExec(...) and run() are executed.
If you need to wait for the result to be performed, use syncExec(...) instead of asyncExec(...).
How are you creating your upload thread?
If your thread implements IRunnableWithProgress and is run by a class that implements IRunnableContext, your progress bar should be able to run in a separate thread fine.
Just specify true for the fork parameter on the run method.
The run method on IRunnableWithProgress provides an IProgressMonitor for your thread to update.

Categories