JMEDesktop: Swing within jME scene

If all else fails you could add a focus listener that onFocus calls jmeDesktop.setFocusTarget(somethingElse) (or whatever the method is)?



Kind of hacky, but it should work. :o



darkfrog

You should also be able to add a window/component (not sure what you are moving) listener that rejects the move.

Hi, first of all:



THANKS !!! :smiley:



Wonderful fnuctionality.



Now for the problems :wink:



You stated: "- JScrollPane needs repainting in JDK1.4 (see TestJMEDesktop source)"

I use JDK 1.5_06 (WinXP) and it definetly needs repainting there as well.



I also have some other strange problem with JComboBoxes.

I have a JMEDesktop. On top of that a panel  and a jcombobox on that panel.



Seems when i click on it the list appears BELOW the panel.

Any idea why that happens  or how to avoid it (without me spamming here with lines of code :wink: )

Todi said:

You stated: "- JScrollPane needs repainting in JDK1.4 (see TestJMEDesktop source)"
I use JDK 1.5_06 (WinXP) and it definetly needs repainting there as well.

Yes, I noticed that, too, on some platforms, but I still need to find a better workaround/fix for it :|

I also have some other strange problem with JComboBoxes.
I have a JMEDesktop. On top of that a panel  and a jcombobox on that panel.

Seems when i click on it the list appears BELOW the panel.
Any idea why that happens  or how to avoid it (without me spamming here with lines of code ;) )

Err, that's strange, I'll check that...

Hmm, does TestJMEDesktop run fine for you? If yes, please post a link to an example app - it looks fine (above the panel) over here…

If TestJMEDesktop has the same issue it would be quite strange :?

irrisor said:

Hmm, does TestJMEDesktop run fine for you? If yes, please post a link to an example app - it looks fine (above the panel) over here...
If TestJMEDesktop has the same issue it would be quite strange :?

TestJME works fine yes.
I have made a workaround using a List instead of a combobox.
Will see if i can rewind the code and print a listing here.

Has anybody an example running JMEDesktop in gamestates? i can't get it to work…

Hopiu said:

Has anybody an example running JMEDesktop in gamestates? i can't get it to work...


Yep.
Unfortunatly i dont think the architecture of gamestate is usable for jmedesktop. It would be good to have some class "in between" the state classes.
So we created a new state class extending BasicGameState and more or less adding all the stuff the other states have one after the other.

Take a look at "BaseGameState" here ..
http://svn.berlios.de/wsvn/bmws/MBWSClient/src/de/mbws/client/state/?rev=0&sc=0
and the classes that make use of it :)

irrisor said:

Hmm, does TestJMEDesktop run fine for you? If yes, please post a link to an example app - it looks fine (above the panel) over here...
If TestJMEDesktop has the same issue it would be quite strange :?

Ok,
i use  modified gamestate classes all extending a class called BaseGameState (not BasIcGameState) http://svn.berlios.de/wsvn/bmws/MBWSClient/src/de/mbws/client/state/?rev=0&sc=0

I guess the problem could be this method in BaseGameState:

public void showComponentCenteredOnScreenOnTop(JComponent panel) {
JDesktopPane desktopPane = jmeDesktop.getJDesktop();
int x = (desktopPane.getWidth() / 2) - (panel.getWidth() / 2);
int y = (desktopPane.getHeight() / 2) - (panel.getHeight() / 2);
panel.setLocation(x, y);
desktopPane.setLayer(panel, 1);
desktopPane.add(panel);
desktopPane.revalidate();
}

I already tried 0 but it didnt help either

Now the code that calls it is:
is LoginPanel

http://svn.berlios.de/wsvn/bmws/MBWSClient/src/de/mbws/client/gui/mainmenu/LoginPanel.java?op=file&rev=0&sc=0:

private JButton getShowOptionsButton() {
                if (showOptionsButton == null) {
                        showOptionsButton = new JButton();
                        showOptionsButton.setBounds(new java.awt.Rectangle(220, 280, 210,
                                        30));
                        showOptionsButton.setText(ValueMapper
                                        .getText(ClientGlobals.MENU_BUTTON_OPTIONS));
                        showOptionsButton.setContentAreaFilled(false);
                        showOptionsButton
                                        .addActionListener(new java.awt.event.ActionListener() {
                                                public void actionPerformed(java.awt.event.ActionEvent e) {
                                                        logger
                                                                        .info("actionPerformed(): showing option panel");
                                                        getInputHandler()
                                                                        .getState()
                                                                        .showComponentCenteredOnScreenOnTop(
                                                                                        new OptionsPanel(getInputHandler()));
                                                        // TODO
// Auto-generated
// Event stub
// actionPerformed()
// getInputHandler().getMyState().displayInfo("blalbalb");
// //displayInfo("blab");
}
                                        });
                }
                return showOptionsButton;
        }


And the final code where my combobox WAS(its not in svn):
http://svn.berlios.de/wsvn/bmws/MBWSClient/src/de/mbws/client/gui/options/OptionsPanel.java?op=file&rev=0&sc=0
The original method on my disk looked like this however:
private JPanel getVideoPanel() {
String[] info = new String[modes.length];
for (int i = 0; i < modes.length; i++) {
info = getResolutionEntry(modes);
}
resolutionCb = new JComboBox(info);

resolutionCb.setSelectedIndex(getSelectedResolution());

JPanel p = getDefaultPanel();
p.add(new JLabel("Resolution(lang)"));
p.add("tab", resolutionCb);
p.add("br", fullScreen);
return p;
}


Result: The combobox is visible but the list doesnt pop up. It appears UNDER the panel visible only of you make the size of the panel small and have many entries in the list.

I'm using multiple JMEDesktops within multiple gamestates without any problems…



darkfrog

Todi, I haven't used setLayer anywhere yet, but that seems to explain it. Can you add a panel directly to the desktop that shows above your occluding panel? If yes, please post the code for that. I could use it for the popups then…

irrisor said:

Todi, I haven't used setLayer anywhere yet, but that seems to explain it. Can you add a panel directly to the desktop that shows above your occluding panel? If yes, please post the code for that. I could use it for the popups then...

Ok, i am not sure if i undertsood you correctly.
You want me to give you the code needed to have multiple panels/frames etc. show up above each other. Correct ?
Actually i already did that above ;)

Anyway here is a cleaner version along with a modified TestJMEDesktop:

Normally you add the following code somewhere (preferably JMEDesktop, then you could use desktop directly instead of getting a reference first):

public void showComponentOnLayer(JComponent comp, int layer) {
JDesktopPane desktopPane = jmeDesktop.getJDesktop();
desktopPane.add(comp, new Integer(layer));
desktopPane.revalidate();
}


Here is a modified TestJMEDesktop using the method, poping up 3 panels and 3 internal frames above each other.
Since setVisible(false) doesnt work (which is to be understood as a begging to make it work ;) ) i "teleport" the panels away (location 0,0) if you click the button.
Code is marked by //ADDITIONS FOR LAYERS

I guess its obvious how it works.
I included a combobox in the panel so you see the problem.
If you find out what the problem with the combobox is i would be ALMOST as gratefull as i would be for a fix for the bug that hidden elements still get all mousevents ;)



/**
* Called near end of initGame(). Must be defined by derived classes.
*/
protected void simpleInitGame() {
display.setTitle("jME-Desktop test");
display.getRenderer().setBackgroundColor(ColorRGBA.blue);

input = new InputHandler();
lookHandler = new KeyboardLookHandler(cam, 50, 1);
input.addToAttachedHandlers(lookHandler);

jmeDesktop = new JMEDesktop("test internalFrame");
jmeDesktop.setup(display.getWidth(), display.getHeight(), false, input);
jmeDesktop.setLightCombineMode(LightState.OFF);
desktopNode = new Node("desktop node");
desktopNode.attachChild(jmeDesktop);
rootNode.attachChild(desktopNode);
createBoxBorder();

perspective();
// fullScreen();

jmeDesktop.getJDesktop().setBackground(new Color(1, 1, 1, 0.2f));

switchLookAndFeelAndCreateSwingStuff(0);

create3DStuff();

createCustomCursor();

// ADDITIONS FOR LAYERS START
createFrameOnLayerX(1);
createFrameOnLayerX(2);
createFrameOnLayerX(3);

createPanelOnLayerX(1);
createPanelOnLayerX(2);
createPanelOnLayerX(3);
// ADDITIONS FOR LAYERS END

// for experimenting with events:
// JFrame frame = new JFrame();
//
// frame.pack();
// frame.setVisible( true );
// Toolkit.getDefaultToolkit().addAWTEventListener( new
// AWTEventListener() {
// public void eventDispatched( AWTEvent event ) {
// System.out.println( event );
// }
// }, 0xFFFFFFFFFFFFFFl );
// JButton button = new JButton( "test" );
// button.setMnemonic( 't' );
// frame.getContentPane().add( button );
// button.addActionListener( new ActionListener() {
// public void actionPerformed( ActionEvent e ) {
// System.out.println( "now" );
// }
// } );
}



// ADDITIONS FOR LAYERS METHODS START HERE
public JComponent centerOnScreen(JComponent panel) {
JDesktopPane desktopPane = jmeDesktop.getJDesktop();
int x = (desktopPane.getWidth() / 2) - (panel.getWidth() / 2);
int y = (desktopPane.getHeight() / 2) - (panel.getHeight() / 2);
panel.setLocation(x, y);
return panel;
}

public void showComponentOnLayer(JComponent comp, int layer) {
JDesktopPane desktopPane = jmeDesktop.getJDesktop();
desktopPane.add(comp, new Integer(layer));
desktopPane.revalidate();
}

protected void createFrameOnLayerX(int x) {
JInternalFrame p = new JInternalFrame("Layer: " + x);
p.setSize(200, 80);
p.setVisible(true);

centerOnScreen(p);
showComponentOnLayer(p, x);
}

protected void createPanelOnLayerX(int x) {
final JPanel p = new JPanel();

JButton closeButton = new JButton("close layer:" + x);
closeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// p.setVisible(false); Doesnt work because mousclicks still go
// to the panel
p.setLocation(0, 0);
}
});
String[] items = new String[] {"test","test2","test3"};
JComboBox b = new JComboBox(items);
p.add(b);
p.add(closeButton);
p.setSize(200, 80);

centerOnScreen(p);
showComponentOnLayer(p, x);
}
}



Todi said:

Since setVisible(false) doesnt work (which is to be understood as a begging to make it work ;) )

Strange enough - Component.componentAt returns invisible components, too o_O ... JMEDesktop doesn't use it any more. I have added a call to setVisibile to the "more stuff" button in TestJMEDesktop - works alright now.

If you find out what the problem with the combobox is i would be ALMOST as gratefull as i would be for a fix for the bug that hidden elements still get all mousevents ;)

Hehe, what if I solved both? :D
The scrolling thing is only a workaround though (still repainting but automatically) - haven't found the actual reason...
Quote:
Hehe, what if I solved both? :D
The scrolling thing is only a workaround though (still repainting but automatically) - haven't found the actual reason...
I would say you forgot one  :wink:

The problem with hidden components is solved. PERFECT ! (now i finally get a chance to move around on my terrain when my dialogs are have been hidden and i click at a spot where they previously where visible)

The scrollproblem of the listbox is also solved (so i can finally get rid of my actionlistener code).: PERFECT
You know its actually were refreshing to start the day with a visit here and see you folks do such a good job  :)

Only problem that remains is the combobox problem with the "entriespane" showing up below the panel holding the combobox.
Did you have a look at my code (aeh... 3 lines)  for layers ? Was that what you had asked for ?
Todi said:

I would say you forgot one  ;)

Hmm, still thought you would tell me how to get a component on top of all layers . Now tested myself and a simple desktop.add( popup, Integer.MAX_VALUE ) does the trick... committed.
irrisor said:

Todi said:

I would say you forgot one  ;)

Hmm, still thought you would tell me how to get a component on top of all layers . Now tested myself and a simple desktop.add( popup, Integer.MAX_VALUE ) does the trick... committed.


Just look again three posts above
I posted:
public void showComponentOnLayer(JComponent comp, int layer) {
      JDesktopPane desktopPane = jmeDesktop.getJDesktop(); 
      desktopPane.add(comp, new Integer(layer));
      desktopPane.revalidate();
  }


;)

The higher the value the nearer the top. There are some constants you might use like MODAL etc.
You might use my modified TestJMEDesktop to test the layer behaviour (and the combobox)
Todi said:

You might use my modified TestJMEDesktop to test the layer behaviour (and the combobox)

Yes, that's what I have done ;)

Wink overload!!!



croak

I've noticed that if the mouse cursor is initialised before creating the JMEDesktop stuff(JME and swing) then the mouse

cursor appears below the Swing components(JButtons in my case). This doesn't actually pose a real problem for me since

I now initialise the mouse after creating all the needed Swing and jme stuff, although this was not an issue before,

so I thought I should mention this, in case something more weird is happening… or a bug fixing introduced a new bug.

The custom mouse cursor is another Quad than the JMEDesktop. So it's ok that it shows below the desktop if given such a z-order. This happens if you create the cursor first and don't change the order. I wouldn't consider it harmful…