Accessing Nested GUI components. Comments and Opinions needed.  
Author Message
valheru





PostPosted: 2003-11-14 15:25:00 Top

java-programmer, Accessing Nested GUI components. Comments and Opinions needed. Hi,

I have a question regarding GUI design...

Suppose I have a Swing Component such as a JPanel, that contains other
components. That is suppose A contains B contains C contains D. Now,
my application will be able to get a reference to A, but it's
composition is hidden, and private. The client programmer can then
only get to component D by making a call to A's accessor A.getD().
However, that means that B.getD() and C.getD() need to be defined *for
each accessible component* (ie if we had E then getE is needed etc and
maybe setD and setE etc)

It seems that this method of creating a GUI by composition of widgets
and nesting them inside each other creates the problem that to get to
the components down the bottom you need to "drill down" with get() and
set() methods. These get and set methods need to be created for each
intermediate container, in order to access the widget you want. Surely
there is a better way?

Currently I'm designing a GUI which has a lot of these nested
components. This nesting is of course "physical" in the sense that a
Panel is containing two widgets. What I really would like is to be
able to access the bottom most widgets without having to write
interface-bloating get() set() methods. I was thinking of (somehow?)
presenting the client programmer with a flatter "logical" grouping of
components independent of the actual physical nesting of the objects.
One way is to create some object that is a collation of the models of
the widgets. Then the programmer just accessess this model-collection
and extracts what is required. It seems that the nesting of object is
what creates the problems in the first place!

Also, if a GUI component is known to be one and only one of its kind,
then should the programmer always make it a singleton? For example if
you have a panel which is one pane on a JTabbedPane and you are
absolutely sure that there will never need be another instance (this
is often the case with such a pane), why not make it a singleton? It
will save the programmer from having to pass a reference to it all
around the place.

Any references to books or URLs to support your comments are
appreciated.

Thanks,

Mark
 
nobody





PostPosted: 2003-11-14 16:55:00 Top

java-programmer >> Accessing Nested GUI components. Comments and Opinions needed. email***@***.com (Mark) writes:
> It seems that this method of creating a GUI by composition of widgets
> and nesting them inside each other creates the problem that to get to
> the components down the bottom you need to "drill down" with get() and
> set() methods. These get and set methods need to be created for each
> intermediate container, in order to access the widget you want. Surely
> there is a better way?

MVC. Treat one such combination of widgets as one "view", and provide a
model for this kind of views. Let the top-level component, e.g. the
JPanel that you mentioned or a complete window, deal with the model
(handle events, set/get values to/from the model). Let the top-level
component call the individual set.../get... methods of the nested
widgets whenever there is a need.

> Currently I'm designing a GUI which has a lot of these nested
> components. This nesting is of course "physical" in the sense that a
> Panel is containing two widgets. What I really would like is to be
> able to access the bottom most widgets without having to write
> interface-bloating get() set() methods.

Why? You are talking of a "client programmer". I assume you mean
someone who is supposed to use your GUI components. Why should such a
programmer have to deal with your components on a widget level? I
assume each of your components provides a meaningfull abstraction of
something that should go-on on the screen. Let the client programmer
deal with that abstraction via the model, not with individual widgets.

The whole point of providing higher-level components is that client
programmers don't have to deal with the widgets.

> I was thinking of (somehow?)
> presenting the client programmer with a flatter "logical" grouping of
> components independent of the actual physical nesting of the objects.

Don't let them touch these widgets. Provide a meaningful abstraction.

> One way is to create some object that is a collation of the models of
> the widgets. Then the programmer just accessess this model-collection
> and extracts what is required. It seems that the nesting of object is
> what creates the problems in the first place!

I don't think so. The nesting of objects is just an artefact of the way
one assembles GUIs using Swing or AWT. You could keep references to
each nested widget on the top-level, e.g. in variables in the JPanel.
It is the lack of a suitable abstraction that forces you to think that
your client programmers absolutely must access every widget.

> Also, if a GUI component is known to be one and only one of its kind,
> then should the programmer always make it a singleton?

No, because

(a) you really don't know. You provide components. Why do you want to
reduce their application?

(b) Singletons are more often than not a bad excuse for introducing a
global variable and covering the fact up with this particular design
pattern. If you want a global variable, be honest and use a global
variable.

(c) There are some naughty issues with singletons and java
(double-check lock can not be made to work correctly).

> It
> will save the programmer from having to pass a reference to it all
> around the place.

You usually do not pass references to GUI components around. You
usually bind a GUI component to a model, and then use the model.

> Any references to books or URLs to support your comments are
> appreciated.

Any introduction text on MVC and MVC-like GUI design should do. Sun has
published in an introduction to their variant of MVC, too. A reference
is somewhere in the comp.lang.java.gui FAQ.

Regarding reusable GUI components, you can also have a look at the PAC
architecture (which can be done with Swing, but is not directly
supported. PAC is also not in wide usage).

/Thomas
 
valheru





PostPosted: 2003-11-15 12:51:00 Top

java-programmer >> Accessing Nested GUI components. Comments and Opinions needed. email***@***.com (Thomas Weidenfeller) wrote in message news:<bp259h$loo$email***@***.com>...
> email***@***.com (Mark) writes:
> > It seems that this method of creating a GUI by composition of widgets
> > and nesting them inside each other creates the problem that to get to
> > the components down the bottom you need to "drill down" with get() and
> > set() methods. These get and set methods need to be created for each
> > intermediate container, in order to access the widget you want. Surely
> > there is a better way?
>
> MVC. Treat one such combination of widgets as one "view", and provide a
> model for this kind of views. Let the top-level component, e.g. the
> JPanel that you mentioned or a complete window, deal with the model
> (handle events, set/get values to/from the model). Let the top-level
> component call the individual set.../get... methods of the nested
> widgets whenever there is a need.

So on my JPanel I would have a method setModel, and this would accept
the model object, and register the model as a Listener of some sort on
the widgets of interest eg:

public void setModel(ChangeListener model)
{
buttonA.addChangeListener(model);
buttonB.addChangeListener(model);
etc
}

and then inside the model we have

public class MyModel implements ChangeListener
{
private String buttonAtext;
private String buttonBtext;


public void stateChanged(ChangeEvent e)
{
if e comes from ButtonA then
buttonAtext = (Jbutton)e.getSource().gettext()
else if
buttonBtext = (Jbutton)e.getSource().getText()

}

public String getButtonAtext() { return buttonAtext; }

public String getButtonBtext() { return buttonBtext; }

}


Is this the correct way do approach the MVC pattern??

In this way I could then define an instance of MyModel and pass it
around and use getButtonAtext and getButtonBtext as accessors, rather
than pass the GUI object around.

Thanks,

Mark
 
 
nobody





PostPosted: 2003-11-17 16:35:00 Top

java-programmer >> Accessing Nested GUI components. Comments and Opinions needed. email***@***.com (Mark) writes:
> So on my JPanel I would have a method setModel, and this would accept
> the model object, and register the model as a Listener of some sort on
> the widgets of interest eg:
[...]

Not really. You are still thinking in individual widgets, instead of
the component. The component (and not the individual buttons) is
supposed to display something. It represents some concept. This is what
you reflect in the model.

The buttons are just some tools. Like you don't get access to the
"parent directory" button in the file chooser, I doubt that your
"client programmer" really wants to have to deal with these buttons.

In fact, there is no point in making a special component if it is just
a collection of widgets and requires the "client programmer" to deal
with each widget. What's the added value?

Your model represents some concept of the application, not buttons.
Your view visualizes this concept. Interaction elements, like buttons,
allow you to change the state of the view (e.g. change a directory in a
file chooser, change the color model in a color picker), or commit
changes to the model. The fact, however, that such a change was
commited to the model by some button-press is totally irrelevant to the
model.

/Thomas