[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 425
  • Last Modified:

MVC-ish question related to Java GUI component interaction

So I'm familiar with the Model-View-Controller (MVC) pattern, but still having difficulty when writing a Swing GUI app and having certain actions (button clicks, etc.) effect higher level classes in the application.  I've used MVC, Observer pattern, etc. for certain situations but what I find difficult to deal with is this type of situation:

I have a JFrame (a class that extends JFrame).  It has a menu bar (another class that extends JMenuBar) as a member variable.  It also has a panel (a class that extends JPanel) as a member variable, and this panel contains a button as a member variable.  The JMenuBar has a "File" drop down menu (another class that extends JMenu) as a member variable.  The "File" drop down menu has a menu item, say "Create new file" as a member variable.  

Obviously, there is some nesting here.  What I want to happen (elegantly) is when the button in the panel is clicked, the "Create new file" menu item should be disabled.  The point is that not all the swing components I've described are not accessible in one class... they are scattered in other classes as private member variables.  The button is a few levels below where the file items are, etc.  So do I use a model?  If so, how?  Do I use some type of Singleton state classthat somehow manages everything?
0
DiamonDogX
Asked:
DiamonDogX
  • 3
  • 3
  • 2
  • +1
2 Solutions
 
CEHJCommented:
You can consider a class that implements the Facade pattern that encapsulates all access to dispersed gui objects in one place:
http://en.wikipedia.org/wiki/Facade_pattern
0
 
objectsCommented:
you would define an Action  subclass for createing new files

public class MyAction extends AbstractAction
{
    ...
    public void actionPerformed(ActionEvent event)
    {
        // perform "Create new file" here
    }
}

And then wire up a listener on your panel button to disable the action whenever your button was pressed.

MyAction myaction = new MyAction();
panelButton.addActionListener(new ActionListener()
{
   public void actionPerformed(ActionEvent event)
   {
      myaction.setEnabled(false);
   }
}

you can then use your action to fcreate menu item

JMenuItem mi = new JMenuItem(myaction);
0
 
seet82Commented:
since you are using the MVC and observer pattern, the below can be done

say the button is a save document button and the menu item is also save item

initially, both the button and menu (or the jpanel that contains them) will observe the document

when you save the document using 1 of the options(menu or button), the document will trigger a changed event and you can handle the disabling of the save menu item and save button after the document is saved.

as opposed to a facade, when you save the document, the document needs to know what GUI objects need to be affected and thus, in future, when you say implement another save button somewhere else, you need to change the code for the document which, IMHO, is not really a gd programming practice.


0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
DiamonDogXAuthor Commented:
objects... interesting idea.  But if I have a "MyAction" class and I create an instance of it to use like you showed, I have to pass it to the JMenuItem constructor as well as use it in the class that contains the JButton.  The JMenuItem and JButton are in separate classes.  So how would you suggest using the "MyAction"?
0
 
objectsCommented:
you can either add getters/setters to your classes so top level classes can access what is required.
Or use a singleton to store your actions.

What u want to avoid is any coupling between your components.
0
 
CEHJCommented:
>>The JMenuItem and JButton are in separate classes.

That's why a Facade would be useful. This would place the responsibility of locating the dispersed classes on the Facade. All clients would query the same single point of entry (the Facade). Using Action alone won't help you
0
 
CEHJCommented:
:-)
0
 
objectsCommented:
Can u explaion why u acdepted that comment?

0
 
DiamonDogXAuthor Commented:
Because I liked it ;).  lol.  

Actually I should have probably split some points... both of you had good answers.  If you know how to make that change happen, I'm fine with it.
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 3
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now