What would be the best way to draw a simple animation just before showing a modal JDialog? (i.e. expanding borders from the mouse click point to the dialog location). I thought it would be possible to draw on the glasspane of the parent frame on the setVisible method of the dialog. However since the JDialog is modal to the parent, I couldn't find a way to pump drawing events into EDT before the JDialog becomes visible since the current event on the EDT has not been completed yet.
Are you trying to show the JDialog indepentently of the annimation? In order to get the order set properly, you may need to bundle those actions in a runnable that is passed to the EDT at once.
eg:
SwingUtilities.invokeLater(new Runnable(){
public void run(){
doAnnimation();
showDialog();
}
}
It may be best to subclass JDialog so that you can just add the doAnnimation() logic to the setVisible(..) or show() method before calling the superclass implementation.
Finally, I imagine you'll need to set the dimensions of the dalog manually -- I don't remember if Java will know the actual size of the dialog before it is shown, so you may get some useless information for your annimation if you query the size before showing it.
@rcreswick
This solution was also what I tried first. However the problem with this solution is that invokeLater invokes the event calls after the events on the EventQueue are consumed. Since I want the dialog to be modal to the parent frame, the current event which calls setVisible for the dialog on the EDT cannot be finished until the dialog is closed. Therefore, the animation cannot be shown before the dialog is closed. However, this approach works very well for non-modal dialogs.
I think, the best solution is being able to pump events into the eventQueue, just like the way swing handles modal dialogs. However those methods of EventQueue class are all protected, I couldn't find a way to mimic that approach.
Another solution might be waiting until the java version with multiple event dispatching threads :)
About the size of the dialog, it's possible to obtain correct size, after the pack() is called for the dialog.
You may be able to take @rcreswick's answer and expand on it a little to make it work.
void myShowDialog() {
new Thread(new Runnable() {public void run() {
SwingUtilities.invokeAndWait(new Runnable() { public void run() {
doAnimation();
} } );
// Delay to wait for the animation to finish (if needed)
Thread.sleep(500);
SwingUtilities.invokeAndWait(new Runnable() { public void run() {
showDialog();
} } );
} } ).start();
}
It's pretty ugly and would have to be invoked in place of the basic showDialog() call, but it should work.
@John Meagher
Through this way, it's not also possible to obtain a modal dialog. Since doAnimation is invoked as another thread, myShowDialog method will return to the caller before doAnimation is finished. Even if it is possible to arrange the things in a way that myShowDialog returns after doAnimation is completed, then it will be a deadlock as the caller thread is EDT and invokeAndWait will wait for the current event in the EDT to be handled.
Maybe you have a look at the SwingWorker Project which is included in JSE 6. (Link to SwingWorker) In the book "Filthy Rich Client" that I am reading at the moment they use this tool a lot. Maybe you can find a hint in the examples on the books website: http://filthyrichclients.org/
One possibility is to paint your own dialog on the Glass Pane. Then you have full control of the dialog and can paint whatever you want. Here's a tutorial on creating animations on the Glass Pane.