Swing Canvas and Events

Hi All,



I have a test harness running inside a swing window that I use for testing sections of functionality before putting them into the game proper. The problem I have though is that once it acquires focus the jME3 canvas never seems to release it. This means I can use drop down menus/type etc until the first time I click in the canvas but then after that I can’t type into text controls, use scrollwheel on menus, etc.



I’ve set

[java] flyCam.setDragToRotate(true);

flyCam.setRotationSpeed(1.5f);

flyCam.setMoveSpeed(50f);[/java]



Which doesn’t seem to have helped.

I then tried:



[java] public MainPanel(final JmeCanvasContext ctx, Main main) {

this.ctx = ctx;

this.main = main;

initComponents();

canvasWrapper.add(ctx.getCanvas());

ctx.getCanvas().setEnabled(false);

[/java]



Disabling the control did work in that it never claimed the focus but it meant I couldn’t navigate the scene, rotate the view, or (and this is where it becomes a problem) test interactions with objects.



I even tried dynamically enabling and disabling the control base on mouse enter/leave events but it seems once it has the focus even if you disable it it holds onto it!



If I switch to a completely different window the jme canvas pauses and I can then come back to the window and use the swing controls, but the updating of the view remains paused while I do so and when I click back on the swing canvas it resumes again but I can no-longer type.



Is there some setting I’ve missed or something else I need to do in order to get the Swing canvas to relinquish focus?



The behaviour I want is:


  1. The SimpleApplication is running all the time.
  2. When I click inside the canvas it gets focus for both mouse and keyboard
  3. When I click into another control on the same window the application keeps running but focus shifts to the control clicked on.
  4. When I switch to another app I don’t mind whether it pauses or continues. Either is fine.



    Does anyone know how to achieve this?



    Thanks,

    Zarch

Zarach



Put this in your settings section.



[java]setPauseOnLostFocus(false);[/java]



This will allow the update method to continue to run even when you loose focus.



Edit: Also set the focusable property for the other controls in the windows to false.

[java]object.setFocusable(false);[/java]

This will allow you to edit the scene even if you have clicked on a different control in your swing window.

3 Likes
@dm1056 said:
Zarach

Put this in your settings section.

[java]setPauseOnLostFocus(false);[/java]

This will allow the update method to continue to run even when you loose focus.

Edit: Also set the focusable property for the other controls in the windows to false.
[java]object.setFocusable(false);[/java]
This will allow you to edit the scene even if you have clicked on a different control in your swing window.


Thanks dm, setPauseOnLostFocus(false); has fixed that part of the problem. However setFocusable has not helped. I think I have the opposite problem from what that would fix:

My other swing components lose the focus as soon as the canvas is clicked on...and the only way to get it back is to switch to a different application and then back again. I've tried setting the canvas ctx.getCanvas().setFocusable(false);
but that makes no difference. I've also tried
ctx.getCanvas().setEnabled(false);

The enabled(false) works if called before it ever gets focus in order to cause it to not get it - however once it has focus even disabling it will not cause it to return focus to the other swing components - and disabling the canvas then means I cannot interact with it.

I need the "standard" behaviour for swing controls where a click on the canvas gives it focus but then a click anywhere else moves focus away.

What are you attempting to accomplish with your other swing controls?

I may not be understanding what you are wanting to accomplish.

I have a JTextArea. Into that I load templates with various data for entities in the game. I can modify the data and then hit a button to cause that data to be converted from text into the appropriate object and sent to be displayed/etc.



I have a JComboBox containing a drop down list of templates obtained by scanning a templates folder.



When the Render Test app starts up I can click on the combo box, use the mouse wheel to select an entry, hit the load button to populate the text area. I can then change the values in the text area to whatever I want and hit the next button to send it into the render area to view.



However as soon as I click inside the render area (the canvas) it claims the focus and will not relinquish it. If I click on the combo box it opens but the scroll wheel does not work. If I click inside the JTextArea the cursor appears but if I type the typing still goes to the canvas (i.e. asd move the viewpoint around rather than typing asd into the text area).



The only way to cause it to lose focus is to click on an entirely different application and then come back. In that case it works, but only until the next time the canvas gets focus again whereupon it will refuse to give it up.



Hope that’s clearer?



Thanks,

Zarch

Hello,



we are developing an application using swing and we found the same problem. In our JFrame we have 4 JPanels one of them contains the SimpleApplication Canvas. The problem is that when the cavas takes the focus (mouse + keyboard) we are not able to enter text in textareas located in different JPanel of the same JFrame (clicking on these components the cursor appears but the focus is not set properly and we are not able to enter text because the keyboard is blocked by JME).

We observed that this problem occured only in Windows platform, in fact using the same application in Linux it works correctly. Of course we need to use the mouse and keybord in the 3D world (so we can’t disable the 3d canvas or the keyboard and mouse listeners).

At the moment the only way to solve it seems to open and close another fake window/frame (such as a JDialog) but this is a very bad and raw solution… :frowning:

Have you found some better solution for this problem? Can you help us?



Thanks a lot!

Sorry, no. We never found anything and as this only comes up in our render testing application (used to test elements in isolation before putting them into the game) fixing it was never a priority so we haven’t spent any time on it.

The AwtPanel allows more flexible embedding in swing, including from where the jme application gets its input events. Theres a test example for that.

Thanks for your very fast answers! :slight_smile:



We have solved the problem using AwtPanel, so now it seems work properly and we are able to enter text in swing components (ex. TextArea, JTable, etc.) but we have a new problem with org.lwjgl.input.Mouse :? We are using the Mouse.isButtonDown(int btnNum) in order to know if we have to move the camera or drag a selected Spatial but using AwtPanel the Mouse is never created. Do you know how this happens? Could be a problem in the AwtPanelContext class?



This is the code used to create the SimpleApplication (world instance) and to create the AwtPanel which is added as child of a JPanel.



[java]

AppSettings settings = new AppSettings(true);

settings.setFrameRate(50);

settings.setCustomRenderer(AwtPanelsContext.class);

world.setPauseOnLostFocus(false);

world.setSettings(settings);

world.createCanvas();

world.startCanvas();



SwingUtilities.invokeLater(new Runnable(){

public void run(){

final AwtPanelsContext ctx = (AwtPanelsContext) world.getContext();

final AwtPanel panel = ctx.createPanel(PaintMode.Accelerated);

add(panel, “width 100%!, height 100%!, align center, gapright 5”);



panel.attachTo(true, world.getViewPort());



ctx.setInputSource(panel);

ctx.setSystemListener(world);

}

});

[/java]



The same problem is present also in this example found in google code:

http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/awt/TestAwtPanels.java?r=8344



Thanks a lot.

@AlessioDede: The LWJGL Mouse class is not part of jME3 API. You should use InputManager or RawInputListener instead.

Yes, we have solved using inputmanager and a new listener for the AwtPanel.



Thanks!



:smiley:

Love you guy (@dm1056) .

This is exacly for what i’m searching for (a long time) :} Now I can call all my methods to modify the JME scene from swing elements like button or something else.
thank you very much :}

EsKay