Hi all,
I am experiencing the following problem.
I have a JMonkey simple application initialised as follows:
pre type="java"
setPauseOnLostFocus(true);
setSettings(settings);
createCanvas();
startCanvas(true);
canvas = ((JmeCanvasContext) getContext()).getCanvas();
((JmeCanvasContext) getContext()).setSettings(settings);
canvas.setSize(settings.getWidth(), settings.getHeight());/pre
I also have the following method to get the canvas from outside the application:
pre type="java"
public Canvas getCanvas() {
return canvas;
}/pre
Furthermore, I have a JDialog with 2 panels.
In the left panel I have some jtextfields and some jbuttons that accept user input; some jbuttons trigger new popup dialogs for more complex user input.
In the right panel I paint the canvas from the jmonkey instance (got via the getCanvas() method above).
It seems to work smoothly, except for the problem that the jmonkey animation is not updated automatically when the focus is lost. Of course the solution would be to setPauseOnLostFocus(false).
This is actually true: with the above option set, the canvas seems to be updated everytime, even if I resize/minimize/maximize the window or if I pass some new parameters to the amination.
However, when clicking on jbuttons that pops up new JDialogs, the application (or better the parent JDialog) locks and the application has to be restarted.
ThIs seems to happen ONLY if setPauseOnLostFocus is set to false. Everything goes smoothly otherwise.
Any idea or suggestion?
Maybe this is caused by poor design of my application? Or there is any other parameter that I am not aware of?
Canvas painted into swing panel + setPauseOnLostFocus(false) + cursor + swing events causes deadlock
You are probably not considering that you are having two threads, the AWT thread and the OpenGL update loop. When you have pause on lost focus the problems probably don’t appear because the OpenGL thread is suspended. Only modify the jme3 part via callables from the AWT thread (e.g. button presses):
[snippet id=“10”]
Thank you Normen,
i supposed that the problem could be caused by multi-threading .
I will try that very carefully.
Thank you!
Hello Normen,
I am afraid, but maybe I misunderstand something.
THis is my code:
pre type="java"
public NewJDialog(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
jPanel1.add(new AniCanvas().getCanvas());
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
DepositDialog dd = new DepositDialog(this);
dd.setVisible(true);
}
/**
@param args the command line arguments
/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
NewJDialog dialog = new NewJDialog(new javax.swing.JFrame(), true);
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
}
});
dialog.setVisible(true);
}
});
}
private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;/pre
As you see, it’s very simple.
When I click on the button to display the new Dialog, the application hangs.
The only thing that I can see is the method getCanvas(). It just returns the context.getCanvas() from the JME application. I also tried to enqueue the getCanvas method but without success.
Any cue?
Theres no jme3 code whatsoever in what you posted… Except the adding of the jme3 canvas. The problem you were talking about in the first post sounded like you got your window working already… This sounds like some basic misconception due to lack of knowledge about java…
Hello,
the problem was caused by poor architecture: in the update loop I was calling a method to hide mouse pointer, that caused the application lock.
Thank you for helping to point it out.
I’ll open a new thread on how to hide the mouse cursor within the panel where the canvas is painted. Unfortunately, inputManager.setCursorVisible(true); didn’t work for me
Dont open new threads for everything. Just enqueue everything to the right thread (in the code you posted you have the equivalent of a Callable for the OpenGL thread - A Runnable for the AWT thread)
Hi Normen,
sorry for my poor explaination. I meant I would have opened a new “post” on this forum instead of continuing here, to discuss on how to hide the mouse cursor when using JME canvas painted into a jPanel in Swing.
I opened the new post here (http://hub.jmonkeyengine.org/groups/general-2/forum/topic/hide-mouse-cursor-for-jme-canvas-painted-into-a-swing-panel/) , because I tought the problem is not related to the original post anymore.
Thank you for your help!
I meant threads as in processes on your computer ^^
Hello,
sorry for reopening the thread, but I did some tests.
I really can’t understand how to disable the cursor. I tried many ways but none seems to work. Others cause application lock.
Everything is reported in the code below (in the example I try to customize che cursor instead of hiding, but the wanted behaviour is to hide it).
Any idea?
public class TestCanvas extends SimpleApplication {
protected Geometry player;
public static void main(String[] args) throws InterruptedException{
AppSettings settings = new AppSettings(true);
settings.setWidth(640);
settings.setHeight(480);
final TestCanvas app = new TestCanvas();
app.setPauseOnLostFocus(false);
app.setSettings(settings);
app.createCanvas();
app.startCanvas(true);
JmeCanvasContext context = (JmeCanvasContext) app.getContext();
Canvas canvas = context.getCanvas();
canvas.setSize(settings.getWidth(), settings.getHeight());
final JFrame frame = new JFrame(“Test”);
JPanel jPanel = new JPanel();
jPanel.add(canvas);
//This is ignored (or overridden by swing?)
canvas.setCursor(new Cursor(Cursor.HAND_CURSOR));
jPanel.setCursor(new Cursor(Cursor.HAND_CURSOR));
frame.setCursor(new Cursor(Cursor.HAND_CURSOR));
//This is ignored (or overridden by swing?)
JButton jButton = new JButton(“Popup new jDialog”);
jButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, “This is a popup”);
}
});
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(jPanel, BorderLayout.CENTER);
frame.getContentPane().add(jButton, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
@Override
public void simpleInitApp() {
flyCam.setEnabled(false);
flyCam.setDragToRotate(false);
setPauseOnLostFocus(false);
Box b = new Box(Vector3f.ZERO, 1, 1, 1);
player = new Geometry(“blue cube”, b);
Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);
mat.setColor(“Color”, ColorRGBA.Blue);
player.setMaterial(mat);
rootNode.attachChild(player);
//This is ignored (or overridden by swing?)
inputManager.setCursorVisible(false);
//This is ignored (or overridden by swing?)
}
@Override
public void simpleUpdate(float tpf) {
player.rotate(0, 2*tpf, 0);
//This is ignored (or overridden by swing?)
inputManager.setCursorVisible(false);
//This works but causes application lock when I click on jButton to show jDialog
JmeCanvasContext ctx = (JmeCanvasContext) getContext();
ctx.getCanvas().setCursor(new Cursor(Cursor.HAND_CURSOR));
}
}
hello,
you need to call : inputManager.setCursorVisible(false); in order to disable the cursor.
However there is a bug. That method doesn’t work in simpleInit()!!!
It wont disable the mouse and will happily lie by saying that cursor is not visible.
In order for this to work you have to :
- in simple init : inputManager.setCursorVisible(true);
- in simpleUpdate(); disable it :
if (totalTime > 0.5f) getInputManager().setCursorVisible(false);
Why this happens ? Potential scenarios:
- canvas doesnt have focus, thus cannot disable your mouse.
- setCursorVisible is in “I am lying mode”, it says it is not visible and ignores your call.
Hello,
I tried that, but the approach has the following problem:
when the mouse is over the canvas, it disappears, but if I click on the canvas (i.e. the canvas gets focus), the mouse is trapped into the canvas and I have to alt-tab to get it back.
The only way I got to hide the cursor is through a rawinputlistener with the following code into the onMouseMotionEvent() :
Toolkit toolkit = Toolkit.getDefaultToolkit();
java.awt.Image image = toolkit.getImage("");
Point hotSpot = new Point(0,0);
AniCanvas.getInstance().getCanvas().setCursor(toolkit.createCustomCursor(image, hotSpot, “Empty”));
I am pretty sure that this is not the best approach ever, as I have to set the empty cursor at every mouse movement, but up to my (very limited) knowledge, it is the only that works.
Thank you