File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Swing / AWT / SWT and the fly likes where to define my menubar Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "where to define my menubar" Watch "where to define my menubar" New topic
Author

where to define my menubar

Jon Swanson
Ranch Hand

Joined: Oct 10, 2011
Posts: 200
I thought I was being clever and set my application up as follows:



where MyMenbar is a separate class in a separate file. Well, it worked nice when I was just playing around with figuring out how to get all the pulldowns and other menubar bits I wanted to implement working.

But now I actually need to have the menu options do something. They'll need to interact with the other pieces of myGUI and I am not sure how the menubar instance can call non-static methods from its parent.

I tried getting something like this, but I couldn't get it to work. I'm not sure what the type is of the thing I am passing to MyMenubar.



I keep reading about the importance of keeping things small and making separate classes so components can be updated independent of each other. On the other hand most code I get to see are just small examples. I never get to see examples of how a program thousands of lines long is constructed. Could someone give me some hints?

I have lots of other components of the GUI. They are all in their own class files and everything works through an observable. It occurs to me I also have a class that holds the defaults for the whole GUI. At some point, the menubar may change these, though they are all static variables. So I think that should work.

What is working for me at the moment is having static variables and static methods that the menubar calls. That doesn't quite seem right. Though it does let me have separate files and the program does work. I've been told static is generally not good in Java, but my 'big picture' of how things are supposed to come together is a bit fuzzy.

Below is a short example of how I am forcing things to work by declaring them static.





In the real code it is the panel I need to be static, since I make changes to it.

I got this to work





so I am tempted to go this way. Is this the smartest option? Or is there something more clever I should be doing?
Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
Jon Swanson wrote:I thought I was being clever and set my application up as follows:



where MyMenbar is a separate class in a separate file. Well, it worked nice when I was just playing around with figuring out how to get all the pulldowns and other menubar bits I wanted to implement working.

But now I actually need to have the menu options do something. They'll need to interact with the other pieces of myGUI and I am not sure how the menubar instance can call non-static methods from its parent.

I tried getting something like this, but I couldn't get it to work. I'm not sure what the type is of the thing I am passing to MyMenubar.





You are passing an instance of MyGui. One way to approach things is to define operations in MyGui that can then be invoked by another class, like MyMenuBar.

For instance, let's say your application has the concept of "opening a file", with the common "File / Open" Menu / Option for that operation. MyMenuBar knows what menu option, when chosen, indicates that you want to do that operation. You could decide to have that operation handle some stuff outside MyGui -- display a file chooser, handle cancellation, etc. -- and pass a file or filename string to a public method in MyGui that performs the operation. This method could use instance variables -- no need for statics. (and it wouldn't have to be MyGui, of course -- some other class that knows how to do the operation could be used. You were just asking about how to hook back to MyGui.)

Let's say you have a search option. Again, MyMenuBar knows what option indicates a need to search; perhaps it could display a popup to get search terms or whatever, and then pass the necessary information to a public method in MyGui to actually do the work.

I am a fan of Swing Actions, incidentally -- the idea is to define an Action, and then there are ways to associate that action with more than one UI element; you can create a menu option and a toolbar button, associate the same action with both, and not have to glue them together yourself. The action takes a couple of strings and an optional icon, and is a great place to put the logic associated with what is to be done without mixing it into how the user chooses it.

Anyway. Those are a couple of ideas.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38765
    
  23
You ought not to have your fields declared static, unless you specifically want the same copy for all instances. If you create two instances of the class, each will have the same static fields as each other.
Jon Swanson
Ranch Hand

Joined: Oct 10, 2011
Posts: 200
Thanks. It sounds like my last set of code is the way to go.

Ralph, one question about actions. In my simple example, MyPanel implements the action listener. Were you suggesting that the action listeners should be implemented in MyGui rather than MyPanel? I'm having trouble understanding how that would work. In my simple case I can get this to work.





But I'm reluctant to have one actionPerformed for dozens of buttons. So my next thought was:





That is fine for one listener, but the menubar will have dozens of them. So while in the first case, I just need to pass in one object (the parent) whereas my latest invocation I would be passing one per listener.

Or is this what you meant?





I've got 5 different snippets that all run. I'm not experienced enough that one jumps out as the best choice, but am pretty sure that once my actual code gets long enough, some of these options would be ones I would regret and others would be more maintainable.

Right now I have an ItemListener for my checkboxes rather than an ActionListener. I only have one for 5 check boxes that set the visibility of the 5 main components of the GUI. I am using getItemSelectable() to determine which check box had the state changed, and that context is in the menubar class. So maybe that argues for keeping the listeners in the menubar class and just calling functions from the main MyGui class? Or is there a more clever way to implement my check box listener? Or would it just be better to have 5 check box ItemListeners? I suppose I could also use (JCheckBoxMenuItem) event.getItemSelectable().getLabel() in my item listener to test for which window I have, right now I am using:



Any opinions on a preferred method for my menubar and item listeners?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38765
    
  23
I think at this stage I ought to move this discussion to our GUIs forum.
Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
I really did mean actions -- or perhaps I should have said Actions (javax.swing.Action in the API I have, though I thought javax had been discontinued...)

Anyway, there's a tutorial at http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html
Jon Swanson
Ranch Hand

Joined: Oct 10, 2011
Posts: 200
Implementation of actions sounds a lot like implementation of Observer/Observable so I think I get the basic idea. It still leaves open the confusion I have over where and how things are defined. For example, take the simple case:

Main: knows about window1 and window2
Menubar: knows the state of checkbox1 and checkbox2

Since menubar is it's own class, if anything else was going to use the actions, presumably they would be in a separate class and not in the Menubar class. So I could either define the Actions in the Main class or a separate Action class. To define Actions, they at least need to know about the windows, or they cannot perform any actions on the windows. Which would make it easier to define them in the Main class. I then presumably need to pass the parent reference to the menubar so that it can change the state of the actions.

Or I can have an action class which would need to be passed the reference to the Main class to actually do anything.

It looks to me like I would need to have five actions for my five windows, rather than one action listener that switches based on the checkbox that called it, otherwise there seems to be no point to the overhead of setting text and icons for the action.

My real question is on structure. Where do things get defined and when should I make separate classes and then what functions are delegated to each class?
Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
There are many options as to how to design things; it isn't going to be simple, since any reasonably complex UI tends to be not-simple, and I don't think there's one way to do it.

That said, the tools you have to work with give you some flexibility. Your menu bar (and your toolbar, if you have one) needs to have information it can present to the user; this includes text, icons, maybe hover or help text, etc. It doesn't have to know what those options do, necessarily. To me, what an Action does is encapsulate what the option does within its class, and expose the other things. So your main class (or a delegate of the main class) can create a number of actions, each of which can have a reference to main, or to a model created by main, or whatever is necessary to actually do the work; then the action can be passed to a class that creates the menu bar, which needs to know those user UI things but doesn't need the reference(s) to the class(es) that the actions will call when the user invokes them.

Yes, if an action is going to perform an operation "on a window", then it needs a reference to that window. But keep in mind that some things don't require the window itself. If an action were to change the model on which a JTable is based, for instance, an action could be passed the model; the action could update the model and fire an event that it had been updated. No reference to the window would be needed.

Or if an action is supposed to alter a set of check or option buttons; it could be passed the set, or a collection that contained all the buttons necessary; it could do whatever it takes to alter them, in actionPerformed so it's in the event dispatch thread already, and again need no reference to the window in which the buttons sit.

I hope that's helpful. I'm having to guess a bit as to your overall question. As to how to design your app, I don't know of an overall rule that will tell you where to do these things.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: where to define my menubar