Guys, I am embarrassed asking this question as I’ve been using jME for a while but it’s really more of a Java question maybe not sure.
I have a callable that gets triggered on action listener whenever user clicks a certain button during the game. So when this button is clicked the following code is triggered:
[java]
myApp.getInputManager().addMapping(“jumpTime”, new KeyTrigger(KeyInput.KEY_J));
…
if (name.equals(“jumpTime”) && keyPressed) {
exec.submit(jumpTime);
}
…
/** Jump time Callable. Allows user to jump
in time during the animation (forward/backward)
*/
Callable jumpTime = new Callable() {
public Object call() throws Exception {
try {
//setPauseOnLostFocus(false);
final float value = Float.parseFloat(JOptionPane.showInputDialog(null,
“Enter Time”,
“Choose Desired Jump Time”,
JOptionPane.QUESTION_MESSAGE));
myApp.enqueue(new Callable<Void>() {
public Void call() throws Exception {
cinematic.setTime(value);
System.out.println("Jumping to time: "+cinematic.getTime());
return null;
}
});
} catch (Exception nFE) {
// do nothing just cancel command
System.out.println(“Exception: Jumping in time failed”);
}
return null;
}
};
[/java]
The issue is that for some reason the JOptionPane window appears behind the jME window and not above it which didn’t used to happen before and I can’t figure out why. All dialogs windows are modal by default so I dont’ udnerstand why this is happening.
It doesn’t matter if it’s modal or not because the owner is not the JME window. Modality only controls how events are delivered but a confluence of events can happen such that the JME window gets focus and then the JOptionPane will be behind it. And then there is little you can do about it, though sometimes alt-tabbing away and back can fix it.
You can potentially mitigate this issue by using SwingUtilities.invokeLater() to pop-up the JOptionPane. It will at least decrease the cases where the pop-up gets hidden.
Other than getting a proper owner, the only other way is to create a dialog that is setup to be “always on top”… and that’s not as straight-forward as your JOptionPane call though there might still be a way to use JOptionPane to do it.
Also, I’m curious… what is “exec” and why are you running the JOptionPane part in a callable using it? I would have thought executing it on the Swing thread would be more appropriate.
[java] private ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(2);[/java]
I am using Cineamtics running and animation and wanted to trigger a window to specify a jump to a certain time on the fly while running the animation. If I don’t use a Callable (which makes it work just fine) the animation time won’t pause and will mess up my sequence of events so I used a callable as suggested by one of the developers here.
Yeah, you are pretty much screwed if you can’t pause the animation any other way than a bunch of chained event blocking. I thought animation could be paused at least.
At any rate, you shouldn’t ever interact with Swing on a thread other than the AWT thread. You could use SwingUtilities.invokeAndWait() but I suspect you will create a deadlock situation.
A real application that wanted to pause the animation would pause the animation. Then it would prompt the user on the swing thread. Then it would set the new time and let the animation run again. All as asynchronously as possible. Relying on blocking hacks to achieve this is dangerous.
@garnaout said:
Not sure how that would solve the problem?
You are fake-pausing animation by blocking the rendering thread. We were suggesting changes that would let you _actually_ pause the animation so that you wouldn't have to fake-pause it.
This would let you use more straight-forward approaches instead of a nineteen-layer deep Rube-Goldberg blocking strategy that requires lots of chanting and finger crossing.
Mostly, it would let you do swing on the swing thread... since anything else is scary.
hmmmm I see. So without using an approach where I have to fork the simpleApplication, what would be the right way to initiate a window that takes the user input from jME without jeopardizing the thread safety. What’s the right way to do this without having the implement some dirty hacks?
If that was the only thing you changed then of course you will get the same issue since that wasn't to fix the issue... that was to pause the animation.
I did this and still the window appear in the back. What else should I do? also @nightwolf911 has a point , why can't we just pass the parent component of the jME window, I know you guys are right but I am just interested to know why his approach is wrong (out of curiosity)
[java] else if (name.equals("jumpTime") && keyPressed) {
// intended to execute a new runnable thread from a Swing application
// without disturbing the normal sequence of event dispatching from the GUI
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
final float value = Float.parseFloat(JOptionPane.showInputDialog(null,
"Enter Time",
"Choose Desired Jump Time",
JOptionPane.QUESTION_MESSAGE));
}
}
);[/java]