This sounds like s focus problem. Do you use the getFocusedComponent method of JMEDesktop somehow to disable ingame input? (Like in TestJMEDesktop)
Second
I wonder if creating a new game state is really a good idea to implement 'new game'. What about resetting the old game state. Nonetheless it should be possible, of course. Which line actually causes the NPE?
Was it getFocusOwner() for JMEDesktop ? I wasn't using it, i'll give it a try.
I agree that my "New Game" state is not the best way to go, but i'd like to understand why it doesn't work though
The NPE occurs in MenuState on
ingame = new IngameState("ingame");
Caused apparently by StandardGameState.initCamera();
I don't understand what's different from the MenuHandler "enter" Action (TestGameStateSystem)...
The whole exception :
java.lang.reflect.InvocationTargetException
at java.awt.EventQueue.invokeAndWait(EventQueue.java:863)
at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1225)
at com.jmex.awt.swingui.JMEDesktop.onButton(JMEDesktop.java:412)
at com.jmex.awt.swingui.JMEDesktop$ButtonAction.performAction(JMEDesktop.java:1097)
at com.jme.input.ActionTrigger.performAction(ActionTrigger.java:253)
at com.jme.input.InputHandler.update(InputHandler.java:475)
at com.jme.input.InputHandler.update(InputHandler.java:483)
at brian.test.b02.MenuState.stateUpdate(MenuState.java:342)
at com.jme.app.StandardGameStateDefaultCamera.update(StandardGameStateDefaultCamera.java:90)
at com.jme.app.GameStateNode.update(GameStateNode.java:71)
at brian.test.b02.Brian.update(Brian.java:61)
at com.jme.app.FixedLogicrateGame.start(FixedLogicrateGame.java:128)
at brian.test.b02.Brian.main(Brian.java:162)
Caused by: java.lang.NullPointerException
at org.lwjgl.opengl.GL11.glMatrixMode(GL11.java:1718)
at com.jme.renderer.lwjgl.LWJGLCamera.onFrustumChange(LWJGLCamera.java:116)
at com.jme.renderer.AbstractCamera.<init>(AbstractCamera.java:213)
at com.jme.renderer.lwjgl.LWJGLCamera.<init>(LWJGLCamera.java:70)
at com.jme.renderer.lwjgl.LWJGLRenderer.createCamera(LWJGLRenderer.java:223)
at com.jme.app.StandardGameState.initCamera(StandardGameState.java:111)
at com.jme.app.StandardGameState.<init>(StandardGameState.java:76)
at brian.test.b02.IngameState.<init>(IngameState.java:60)
at brian.test.b02.MenuState$2.actionPerformed(MenuState.java:194)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1819)
at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(AbstractButton.java:1872)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:247)
at java.awt.Component.processMouseEvent(Component.java:5166)
at java.awt.Component.processEvent(Component.java:4963)
at java.awt.Container.processEvent(Container.java:1613)
at java.awt.Component.dispatchEventImpl(Component.java:3681)
at java.awt.Container.dispatchEventImpl(Container.java:1671)
at java.awt.Component.dispatchEvent(Component.java:3543)
at com.jmex.awt.swingui.JMEDesktop.dispatchEvent(JMEDesktop.java:617)
at com.jmex.awt.swingui.JMEDesktop.sendAWTMouseEvent(JMEDesktop.java:796)
at com.jmex.awt.swingui.JMEDesktop.access$9(JMEDesktop.java:729)
at com.jmex.awt.swingui.JMEDesktop$6.run(JMEDesktop.java:414)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:179)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:478)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:178)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:170)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)
Hmm, I don't have a clue yet what it could be. Please try to replace JMEDesktop by a simple Quad and reduce your test until you can pin down the actual problem. I'd guess it's erroneous camera setup . . .
Could someone please explain why invokeAndWait() is being used in JMEDesktop at all? Removing them seems to work fine, and gets rid of those nasty-looking "Don't call invokeAndWait in the event-handling thread" entries in the log.
You should not get those in the log. Do you get them in HelloJMEDesktop or TestJMEDesktop? Or only in your own program?
InvokeAndWait is used to execute an operation in the awt event thread while current control flow is in the jME (usually main-) thread. When you get the log messages you describe, methods from JMEDesktop are already invoked in the awt thread - that should not happen!
I've been seeing the focus problem in current HelloJMEDesktop, TestJMEDesktop and my own program.
For example in HelloJMEDesktop, pressing "esc" to exit doesn't work until I Apple-Tab twice, once to another application and then once to come back to HelloJMEDesktop. Pressing "esc" then work if I haven't clicked the buton with the mouse.
On some platforms, some JDKs/JREs cause these focus problems. We weren't able to solve them all. Especially on MacOS there are some unresolved focus problems. If you are able to find a fix or workaround, we would really appreciate it when you would post it on the board.
I'm working through HelloJMEDesktop and JMEDesktop to try and find the problem or a work around, no luck yet I still digging into it.
I think I can confirmed your comment about focus problems and that it happens in Java 1.5 on and Intel Mac with OSX 10.4.7.
I've also found that the keyboard input isn't getting to the InputHandle, I'm assuming thats because of the focus problem.
I've go one question about the code in JMEDesktop. I found the following in JMEDesktop…
// this internal frame is a workaround for key binding problems in JDK1.5
// todo: this workaround does not seem to work on mac
if ( System.getProperty( "os.name" ).toLowerCase().indexOf( "mac" ) < 0 ) {
final JInternalFrame internalFrame = new JInternalFrame();
internalFrame.setUI( new BasicInternalFrameUI( internalFrame ) {
protected void installComponents() {
}
} );
internalFrame.setOpaque( false );
internalFrame.setBackground( null );
internalFrame.getContentPane().setLayout( new BorderLayout() );
internalFrame.getContentPane().add( desktop, BorderLayout.CENTER );
internalFrame.setVisible( true );
internalFrame.setBorder( null );
contentPane.add( internalFrame );
}
else {
// this would have suited for JDK1.4:
contentPane.add( desktop, BorderLayout.CENTER );
}
I've found that the awtWindow Frame in JMEDesktop has the missing focus.
When the application starts it seems that nothing has the focus so keyboard input doesn't get to the JME InputHandler. Using Apple-tab you can move the focus to the JME window and the key event then get to the JME InputHandler (which can then get passed to AWT).
However when a mouse button event hits an AWT component then that hidden Frame (awtWindow) gets given the focus. Keyboard inputs doesn't get to the JME InputHandler. Keyboard input does however get to AWT via the hidden Frame (awtWindow).
I'm not sure if this is a symptom or the cause.
One thought is to writing an AWT event listener that can pass the input back to JME.
One other thought is to somehow prevent the focus changing at all (but that not such a good idea).
First about that win/lin fix: In the windows and linux jdk 1.5 there is a check if a component should be draw. It checks whether the component is in a natively visible window (uses a native method which can't be overwritten) or if it's in a virtually visible internal frame. Only if the check is successful the component is drawn. So the only possibility was to put them into an internal frame as the frame shouldn't be visible. On Mac the whole drawing seems to fail with the internal frame - thus the fix is only applied on windows and linux.
Passing back swing events to jME would mean to pass swing events to OpenGL - which won't be possible without alot of a hassle. So preventing that focus change seems the only possibility to me. This is done on windows and linux by making the window unfocusable and invisible. But it already was a pain to get it working that way for Win/14 + Win/1.5 + Lin/1.5 + Mac10.3/1.4. Now it seems there are problems with Mac10.4/1.5 and Win/1.6 . . .
I've been looking at this over the weekend and on OSX with JDK 1.5 it seems that:
you simple can't get the focus in the first place, it seem that neither the lwjgl or awt frame has it when the application start (even if the awtWindow is visable).
if you never call awtWindow.setFocusableWindowState( true ) then once the lwjgl window has the focus it can keep (but then things like text input which require focus can't work). Otherwise each time you press a button the awtWindow takes the focus back.
Not sure what to try next. I'm going to have a quick look at replacing awt Toolkit, I've found some simple example that make it look simple (eg: PJA). At first look it doesn't seem to hard if you only support swing component (only light weight components) and it might mean the the awt thread is not needed. I'll let you know how I go.