How: Add menu to GUI app?

In IntelliJ IDEA, the Help topic "GUI Designer Basics" tells us: "The GUI Designer does not create a main frame for an application, nor does it create menus."

OK, so what is the recommended way to add and configure a menu, in such a way that it works in conjunction with whatever IDE features might be helpful?

Is there a doc somewhere on that?

Thanks,

-- Graham

5 comments
Comment actions Permalink

You can do so simply by writing Java code, as documented in the Swing documentation. There are no specific features for working with menus in IntelliJ IDEA.

0
Comment actions Permalink

OK, thanks.  I wanted to make sure I wasn't missing something.
-- Graham

0
Comment actions Permalink

Hi Dmitry,

In a Java GUI app built with IDEA's Designer, and using IDEA's boilerplate main(), it turns out not to be so obvious where to build menus and their ActionListeners.  I have built a sample that works, but it is sufficiently deviant from what the GUI Designer and code Generate produce, that I'm prompted to ask what the "best practice" is in this area, or whether there is an official "right way to do things" sample.

I would appreciate docs or clarification on the following issues:

0. Assume an example form module class MyForm.

1. I have concluded that createUIComponents is NOT the place to create menus, if only because createUIComponents() doesn't get called if there are no Designer-managed components with Custom Create checked.  Am I right?

2. A JMenuBar has to be supplied to frame.setJMenuBar(), which obviously can't happen until that frame is created, which is in the boilerplate static main().  Is there any rationale for building the menus before frame gets created?

3. So I consolidated all menu-building code into initMenus() method, called from main() after frame is created. That works, but seems like a kludge since all other components get instantiated and initialized by MyForm's constructor (or initialization block) calling $$$setupUI$$$().  Or to put it another way, why is frame created in main() instead of in MyForm's constructor or $$$setupUI$$$()?

4. initMenus() needs to reference the frame (for frame.setJMenuBar()), so either frame needs to be an instance field of MyForm, (not a local variable of static main()), or needs to be passed as an argument. I suspect frame might be needed by other methods later -- doesn't it make sense for frame to be a field of MyForm, like the other Designer-managed components? Ie: why is frame a local variable in main()?

5. The menuItem ActionListeners will need to access the form's components.  To facilitate that access (given that the components are private fields of MyForm) the simplest way seemed to be to have MyForm implement ActionListener.  Again, is this the right way, or is there some cleaner "right way" to do it?

Thanks,  Graham

0
Comment actions Permalink

The IntelliJ IDEA-generated main() isn't intended to be any kind of best practice; it's simply the fastest way to get your form to show on the screen.

createUIComponents() is indeed only used for creating components on the form which have the custom-create flag set.

The frame isn't created in the form constructor because the ownership hierarchy works the other way: the form can be displayed in a frame, in a dialog or as part of a larger composite component. In a real application, you'll probably want to create a separate class for the frame, construct the menus in its constructor, and add the instance of the form class as its content.

Having the form implement ActionListener is a possible approach, but more often ActionListeners are created as anonymous classes which call the necessary code on the form or the frame.

0
Comment actions Permalink

Hi Dmitry,
Thanks for your comments, they were helpful.  I have now concluded that actually the GUI code can look much more like various non-IDEA examples, and see that the GUI Designer constrains the design less than I had suspected.

In particular, it sems best to think of GUI Designer as only supervising the structure of a panel, with the structure above that (JFrame and menu) left to the developer.  Although IDEA can insert a boilerplate main(), that's really only for a very small app, or testing, and not the way an application would normally construct (or maintain references to) one or more windows.

And of course I've seen anonymous classes used for ActionListeners (or adapters). What I had not understood (but do now) is the special ability that Java inner classes have to reference the fields of the containing class, which is crucial for them to be useful in this role.

Thanks again for your comment.

-- Graham

0

Please sign in to leave a comment.