1

Using Java's Swing, you'll often have to wrap elements in others to achieve the desired layout. These panel's elements does however need to be accessable by the super-panel (further called view), upon for example, form-submission.

Consider the following (simplified) example:

class AddUserView extends JPanel {

   private JPanel elementWrapper = new JPanel();
   private JPanel buttonWrapper = new JPanel();

   private JTextField userNameField = new JTextField();
   private JButton submitButton = new JButton("Submit");

   public AddUserView() {

      // .. add elements to the wrappers
      elementWrapper.add(userNameField);
      buttonWrapper.add(submitButton);

      // .. add listeners etc

      // Add the wrappers to the view
      add(elementWrapper);
      add(buttonWrapper);

   }

}

This obviously works, however I believe that this is an ugly solution since now the view owns all the elements, instead of the wrappers - which I find more appropriate. More on, now all (i.e) GridBagConstraints has to be placed in the view.

One solution could of course be to place all the elements in the appropriate wrappers class, and then make it either public + final, or create a bazillion getters & setters.

However, I'm sure there is a more pretty OOP way to achieve this?

Zar
  • 6,786
  • 8
  • 54
  • 76
  • *"you'll often have to **wrap** elements in others to achieve the desired layout."* Typically known as a [Nested Layout](http://stackoverflow.com/a/5630271/418556). But note that example does not extend any `JPanel` but simply uses instances of them. -- It seems by extending `JPanel` the code here is creating too tight a coupling between GUI and model. – Andrew Thompson Jan 14 '13 at 02:02

1 Answers1

2

Well, I don't believe there is a silver bullet solution here.

When I used to work with Swing I tried to keep in mind the following: - Use the encapsulation. Treat your Panel as a reusable component. - Decouple the data layer from the view as much as possible.

When applied to your question this might mean the following: - The only thing that your AppUserView panel knows are 2 wrappers: elementWrapper and buttonWrapper. These are "black-boxes" - reusable components that can be used "as they are" by the AppUserView. Each "wrapper" has a reference on button/textfield/whatever it needs. The data model should be completely decoupled from these views, the only interaction should should be done is by events, when the model decides that it should fire some events, relevant views should be registered as listeners to such events and react respectively.

Hope this helps

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97