JMenuItem NOT dissapearing [SOLVED]

Hi, my JMenuItem is not dissappearing when I click on the canvas.

When I click on my menu bar (File) its menu items are displayed ok. The menu item doesn’t go away as it should do after I click on the canvas. It does go away when I selected or when I click anywhere else e.g. window title, menu bar, outside of the app…

How to make it dissappear when canvas is clicked?

This is how the menu bar is implemented:

        JFrame mainWindow = new JFrame("Swing Application");
        
        JMenuBar menubar = new JMenuBar();
        JMenu file = new JMenu("File");
        JMenuItem eMenuItem = new JMenuItem("Exit");
        file.add(eMenuItem);
        menubar.add(file);
        
        mainWindow.add(menubar, BorderLayout.NORTH);
        mainWindow.pack();
        mainWindow.setSize(600, 600);
        mainWindow.setVisible(true);

        AppSettings appSettings = new AppSettings(true);
        appSettings.setWidth(640);
        appSettings.setHeight(480);
        appSettings.setVSync(true);

        CanvasMain canvasApplication = new CanvasMain();
        canvasApplication.setSettings(appSettings);
        canvasApplication.createCanvas(); // create canvas!
        JmeCanvasContext ctx = (JmeCanvasContext) canvasApplication.getContext();
        ctx.setSystemListener(canvasApplication);
        Dimension dim = new Dimension(640, 480);
        ctx.getCanvas().setPreferredSize(dim);
        mainWindow.add(ctx.getCanvas(), BorderLayout.CENTER);
        canvasApplication.setPauseOnLostFocus(false);
        canvasApplication.startCanvas();

Any help much appreciated!
Thanks
Peter

It’s been a looooong time since I did a JME/Swing project, but I feel like I encountered similar types of issues. Swing is probably never getting the event it needs to know that focus has changed. I think it’s just kinda the nature of integrating JME and Swing. Lemme see if I can dig up anything that might be a useful workaround…

This is probably a bit hacky, but there might not be a better way. You need to have JME somehow tell the Swing side of your app that something has happened. Ex. add event listeners for mouse clicks on init:

inputManager.addMapping("LButtonClick", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(this, "LButtonClick");
inputManager.addMapping("RButtonClick", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
inputManager.addListener(this, "RButtonClick");

Notify your Swing app from your JME app:

public void onAction(String name, boolean isPressed, float tpf) {		
    if (name.equals("LButtonClick")) {
        RefToYourSwingApp.clicked(optionalEventTypeInfo);
    }
}

I actually just used a static method from the RefToYourSwingApp.clicked() part, which was located in the top level Swing class (extending JFrame). There it informs the instance…

if (string.equals("F12")) {
    toggleButton(bmeUI.chckbxmntmfShowWireframe);
    bmeUI.actionPerformed(new ActionEvent(bmeUI.chckbxmntmfShowWireframe, 0, ""));
}

This was sending an F12 keypress but I think you should be able to figure out a way to get Swing to react the way you need. I think you’ll also need to return focus back to JME afterwards, otherwise Swing might steal the focus back despite the user having clicked somewhere on your JME canvas, so at the end of your handler code in Swing, call focusJme(), this is what mine ended up looking like:

public void focusJme() {

    if (bme == null)
        return;
    JmeCanvasContext ctx = (JmeCanvasContext) bme.getContext();
    ctx.getCanvas().requestFocusInWindow();
}

This is kinda old code and I can’t remember if I did anything else unorthodox on that project so maybe it won’t help, but hopefully this gives you an idea to try out.

1 Like

I struggled with canvas for a long time before switching to AWTPanels… my life has been roses and sunshine ever since then. :wink:

1 Like

Hi @louhy, thanks for pointing me in the right direction. What I did is this:

public void onAnalog(String name, float intensity, float tpf) {
      javax.swing.MenuSelectionManager.defaultManager().clearSelectedPath(); // This does the trick for me :)
}

This works like a charm.

Regards
Peter

Cool! My Swing UI was more than just a menu so I had to do a little extra hackery, but for your needs that seems to make sense.

1 Like