Search code examples
javaswingjframejmenuitemjmenubar

Empty JMenuItems in JMenuBar on JFrame


I have a problem creating a JFrame with a JMenuBar. I have a MenuBarBuilder class here:

public class MenuBuilder extends JMenuBar
{
  private Model model;

  public MenuBuilder(Model model)
  {
    this.model = model;
    buildMenuBar();
  }

  public void buildMenuBar()
  {
    JMenu menuFile = new JMenu("File");
    JMenu menuEdit = new JMenu("Edit");
    JMenu menuHelp = new JMenu("Help");

    menuHelp.setMnemonic('H');
    menuFile.setMnemonic('F');
    menuEdit.setMnemonic('E');

    JMenuItem menuItemExit = new JMenuItem("Exit");

    menuItemExit.setAccelerator(model.getKeyStroke(KeyEvent.VK_ESCAPE, 0));

    menuItemExit.setAction(new ActionExit(model));

    menuFile.add(menuItemExit);

    add(menuFile);
    add(menuEdit);
    add(menuHelp);
  }
}

And the JFrame is created in another class:

public MainGUI(boolean loadConfig, String loadConfigDir, Model model)
  {
    try
    {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e)
    {
      GlobalVariables.LOGGING_logger.error("Something went wrong while getting the Look and Feel of current Windows Version for Userinterface", e);
    }

    try
    {
      this.model = model;

      frameMain = new JFrame("MainFrame");
      frameMain.setJMenuBar(new MenuBuilder(model));
      frameMain.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
      frameMain.addWindowListener(this);
      frameMain.setMinimumSize(new Dimension(500, 500));
      frameMain.pack();
      frameMain.setSize(800, 800);
      frameMain.setLocationRelativeTo(null);
      frameMain.setVisible(true);
    }
    catch (Exception e)
    {
      GlobalVariables.LOGGING_logger.error("Error while seeting up the main GUI.", e);
      MessagesToUser.errorMessageBothFilesIssue(true);
    }
  }

After showing the JFrame, all MenuItems are empty, but existing and the function (ActionExit) is also working correct. Setting the new JMenuItem with the following code menuFile.add(new JMenuItem("Exit")); is working as expected and the JFrame has the correct JMenuBar. Why is this happening???

EDIT: Here is the ActionExit class which just exits the program:

public class ActionExit extends AbstractAction
{
  private Model model;

  public ActionExit(Model model)
  {
    this.model = model;
  }

  @Override
  public void actionPerformed(ActionEvent e)
  {
    System.exit(0);
  }
}

Solution

  • JMenuItem (and in fact all children of AbstractButton) derive their display text from the Action.NAME property.

    Try something more like...

    public class ActionExit extends AbstractAction
    {
      private Model model;
    
      public ActionExit(Model model)
      {
        this.model = model;
        putValue(NAME, "Exit");
      }
    
      @Override
      public void actionPerformed(ActionEvent e)
      {
        System.exit(0);
      }
    }
    

    Also, the Action class also defines the mnemonic and accelerator values.

    Take a look at How to use Actions and the Action API for more details