Skip to main content

RFC: Padding API

27 replies [Last post]
Anonymous

The other layout problem we want to address in 1.6 is the ability to get
the preferred distance between components. This will allow
LayoutManagers to honor the visual guidelines of each look and feel
without having code specific to the look and feel. The current plan is
to add the following to javax.swing.LookAndFeel:

Karsten,

I'm trying to solve the problem of look and feels offering up different
guidelines for how far apart components should be placed. I'm thinking
of something like (on LookAndFeel):

<br />
     /**<br />
      * Returns the amount of space to use between two components.  This<br />
method<br />
      * is intended for layout managers and builders to position components.<br />
      * The return value indicates the distance to place<br />
      * target relative to source.  For example,<br />
      * the following returns the amount of space to place between<br />
      * target and source when target<br />
      * is placed vertically above source:<br />
      * 
      *   int padding = getPadding(source, target, SwingConstants.NORTH,
      *                            PaddingType.RELATED);
      *
<br /> * The type parameter indicates how the two<br /> * components are visually grouped together. If the two<br /> * components are showing similar logically related items, than<br /> * use RELATED, otherwise use UNRELATED.<br /> Some<br /> * look and feels may not distinguish between the two.<br /> *<br /> * This method calls into the method of the same name on the<br /> * ComponentUI of each of the<br /> * JComponents. If one returns a value >= 0, the<br /> * max of the two return values is returned; otherwise this<br /> * returns the value from getLookAndFeelPadding.<br /> *<br /> * The return value is not intended to take into account the current<br /> * size and position of target or source,<br /> * rather the return value is just a hint based on visual design<br /> * guidelines of this look and feel.<br /> *<br /> * @param source the JComponent target is<br /> * being placed relative to<br /> * @param target the JComponent being placed<br /> * @param position the position target is being placed<br /> * relative to source; one of<br /> * SwingConstants.NORTH,<br /> * SwingConstants.SOUTH,<br /> * SwingConstants.EAST or<br /> * SwingConstants.WEST<br /> * @param type how the components relate<br /> * @return the amount of space to place between the two components<br /> * @throws IllegalArgumentException if position is not<br /> * one of SwingConstants.NORTH,<br /> * SwingConstants.SOUTH,<br /> * SwingConstants.EAST or<br /> * SwingConstants.WEST; or source,<br /> * type or target is<br /> null<br /> * @see #getLookAndFeelPadding<br /> * @see javax.swing.plaf.ComponentUI#getPadding(JComponent,<br /> * JComponent,int,LookAndFeel.PaddingType)<br /> * @since 1.6<br /> */<br /> public int getPadding(JComponent source, JComponent target,<br /> int position, PaddingType type);</p> <p> /**<br /> * Returns the amount of space to use when placing a component<br /> * against the edge of a parent. This method is intended for<br /> * layout managers and builders to position components.<br /> *<br /> * This method calls into the<br /> getPaddingRelativeToParent and<br /> * getChildPadding methods on the<br /> ComponentUI of<br /> * the target and parent respectively.<br /> If one<br /> * returns a value >= 0, the max of the two is returned, otherwise<br /> * the value of getLookAndFeelPaddingRelativeToParent is<br /> * returned.<br /> *<br /> * The return value is not intended to take into account the current<br /> * size and position of target or parent,<br /> * rather the return value is just a hint based on visual design<br /> * guidelines of this look and feel.<br /> *<br /> * @param parent where target is going to be placed in<br /> * @param target the JComponent being placed<br /> * @param position the edge target is being placed<br /> * along in target; one of<br /> * SwingConstants.NORTH,<br /> * SwingConstants.SOUTH,<br /> * SwingConstants.EAST or<br /> * SwingConstants.WEST<br /> * @return the amount of space to place between target<br /> * and the edge of parent<br /> * @throws IllegalArgumentException if target or<br /> * parent is null; or position<br /> * is not a valid identifier<br /> * @since 1.6<br /> */<br /> public int getPaddingRelativeToParent(JComponent parent,<br /> JComponent target, int position);<br />

To allow component writers to offer up custom positions we'll add
similar methods to ComponentUI. The default implementation of the
ComponentUI methods will return -1 so that the values from the look and
feel will be used.

Comments?

-Scott

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
karsten
Offline
Joined: 2003-06-11

Hi Scott,

First off, I'm glad to see that we discuss advanced
Java layout and design issues. And that you consider
adding advanced layout information that will help us
implement more precise and consistent screens.

Again, I'd like to setup a couple of real-life layouts
to specify the problem before we solve it with an API.

Anyway, here are some problems with the API you suggest.
It is based on instances; I'd like to use component types.
Your API addresses well the issues of an interactive
design tool like Apple's Interface Builder where you have
component instances that you arrange one after the other.
If you want to specify an abstract layout grid before
you arrange the concrete components, your API fails.

One of the things I've found in layout courses was,
that specifying a layout grid before arranging the
components seems to significantly boost a developer's
design productivity. I've seen that when I compared
the time necessary to implement a layout with GBL
vs. the TableLayout/HIGLayout. The latter two managers
allow to specify a grid before you add components.
Separating these two tasks seems to structure the way
how developer think, find, and then work with layouts
- regardless of the concrete layout manager and how
to add components to the grid.

So, if I want to setup the layout grid, I don't have
component instances. Instead I have component types
in my head and other constraints like "space is scarce",
or "use a lot of whitespace in this cool dialog", or
"use a padding similar to the padding of another tab".

The JGoodies Forms LayoutStyle provides only a few
abstract padding types. This is what a developer can
memorize. In constrast a visual builder tool that
arranges individual components may want to get more
rules about paddings between different components.

I doubt that we really need many different paddings.
In most cases we want to have a regular structure for
the layout rows. Either we want to have equal vertical
space between the component row's font baselines,
or equal height of the component rows. The need for
different paddings between components and the
component orientation (A on top of B vs. B on top of A)
arises only, if you have no means to describe the
component's perceived bounds and don't know where
the font baselines are located.

The other way round. If we know the font baseline
locations. Do we need any information about the
vertical padding between the component bounds?
I'd say No! Instead we just choose the vertical distance
between the font baselines. How many horizontal gap types
do we need? Hmm: label-component, related components,
unrelated components, attached components, a few other,
and the same set if space is scarce in screen.
Again, if I know about the perceived bounds,
I don't need the padding of concrete instances.

Also, we agree that the Windows skinning engine
doesn't provide information about the perceived bounds.
So, how can you provide precise information about
the paddings?

CONCLUSION
In my opinion, we don't need new padding types
beyond the ones provided by the Forms LayoutStyle.
Instead, a set of custom gaps and sizes would help
much better in getting consistent screen design.

Best regards,
Karsten

Scott Violet

Hi Karsten,

swing@javadesktop.org wrote:
> Hi Scott,
>
> First off, I'm glad to see that we discuss advanced
> Java layout and design issues. And that you consider
> adding advanced layout information that will help us
> implement more precise and consistent screens.
>
> Again, I'd like to setup a couple of real-life layouts
> to specify the problem before we solve it with an API.
>
> Anyway, here are some problems with the API you suggest.
> It is based on instances; I'd like to use component types.
> Your API addresses well the issues of an interactive
> design tool like Apple's Interface Builder where you have
> component instances that you arrange one after the other.
> If you want to specify an abstract layout grid before
> you arrange the concrete components, your API fails.

That is a valid point.

The concern I have with an approach like you have taken with LayoutStyle
is that you're assuming you know ahead of time all the ways visual
guidelines can be characterized. If you pass in the components the
visual design guidelines can take into account actual information about
the instances themselves and adjust accordingly. For example, as Thomas
indicated the Mac guidelines have different specifications for how far
apart different sized buttons should be placed. With the appoach you
have taken that would require new methods to account for that. With the
approach I'm suggesting the MacLookAndFeel could look at the buttons and
return the appropriate value.

I have implemented a LayoutManager using the proposed API and it has
worked out nicely. That isn't to say it couldn't be more efficient if I
were to do what you're suggesting, but I don't see how that could cover
all possible (and future) design guidelines.

> One of the things I've found in layout courses was,
> that specifying a layout grid before arranging the
> components seems to significantly boost a developer's
> design productivity. I've seen that when I compared
> the time necessary to implement a layout with GBL
> vs. the TableLayout/HIGLayout. The latter two managers
> allow to specify a grid before you add components.
> Separating these two tasks seems to structure the way
> how developer think, find, and then work with layouts
> - regardless of the concrete layout manager and how
> to add components to the grid.
>
> So, if I want to setup the layout grid, I don't have
> component instances. Instead I have component types
> in my head and other constraints like "space is scarce",
> or "use a lot of whitespace in this cool dialog", or
> "use a padding similar to the padding of another tab".

I think we could debate the merits of how people layout components for
ever;)

> The JGoodies Forms LayoutStyle provides only a few
> abstract padding types. This is what a developer can
> memorize. In constrast a visual builder tool that
> arranges individual components may want to get more
> rules about paddings between different components.
>
> I doubt that we really need many different paddings.
> In most cases we want to have a regular structure for
> the layout rows. Either we want to have equal vertical
> space between the component row's font baselines,
> or equal height of the component rows. The need for
> different paddings between components and the
> component orientation (A on top of B vs. B on top of A)
> arises only, if you have no means to describe the
> component's perceived bounds and don't know where
> the font baselines are located.
>
> The other way round. If we know the font baseline
> locations. Do we need any information about the
> vertical padding between the component bounds?
> I'd say No! Instead we just choose the vertical distance
> between the font baselines. How many horizontal gap types
> do we need? Hmm: label-component, related components,
> unrelated components, attached components, a few other,
> and the same set if space is scarce in screen.
> Again, if I know about the perceived bounds,
> I don't need the padding of concrete instances.
>
> Also, we agree that the Windows skinning engine
> doesn't provide information about the perceived bounds.
> So, how can you provide precise information about
> the paddings?

The windows guidelines specify this, and I believe it is in terms of
component bounds, not perceived bounds.

> CONCLUSION
> In my opinion, we don't need new padding types
> beyond the ones provided by the Forms LayoutStyle.
> Instead, a set of custom gaps and sizes would help
> much better in getting consistent screen design.

Consider the case where you aren't doing a grid based layout, and
instead have a more free form style layout. In that case specifying the
two components makes more sense.

If the API also had the ability to pass in Class s would that alleviate
your concern? That way you could set it up once for the grid and be
done with it. This would not allow handling all possible style
guidelines though.

-Scott

Scott Violet

As Karsten has said, there are cases where you don't have instances and
don't want to create them. So, how about we have both:

public int getPreferredGap(JComponent component1, JComponent
component2,
ComponentPlacement type, int position, JComponent parent) {

and

public int getPreferredGap(Class component1Class, Class
component2Class,
ComponentPlacement type, int position, Class parentClass) {

These will exist in a top level class. The implementation of these
methods will delegate directly to LookAndFeel.getLayoutStyle().getXXX

Karsten, if you don't mind I'll name it LayoutStyle.

The rationale for both is that the instance method can be more exact,
where as the Class based one is a best guess.

Comments?

-Scott

zander
Offline
Joined: 2003-06-13

> >> I agree that it is the responsibility of layout
> >> managers to honor the padding but where will layout managers get this
> >> information?
> >
> > This information provided by the designer (and this can be a builder)
> > based on the position of the widget in the Swing hierarchy.
>
> Where does the designer or builder get this information though? Doesn't
> it seem useful to have a standard place to get the spacing? Think of
> the developers that don't have a visual designer working on their
> project, what are they to use? Wouldn't something be better than
> picking some random values?

I think your return question brings us to the core of the problem; something we have not yet formulated giving us (at least me) the feeling of finding a problem for the solution.

The core of the problem then is how to move the ruleset of indenting and spacing, as found in various platform specific styleguides, to code (i.e. codify them) and allow any Swing UI to follow these styleguides automatically.

Before this can be answered some other questions need to be answered to not expand into an infinite solution.
1) How to handle the crossing of styleguides in a platform independent manner.
1.1) Is there any mapping of L&F to styleguide? 1 to 1, or other?
1.2) Is there a mapping of platform to styleguide? (Think Toolkit implementation here)
1.3) how much extention and customization is wanted/needed.
2) exactly which padding types are not handled by already existing solutions like Forms LayoutStyle and NaturalLayout's spacing/margin.
3) how will future changes in styleguides be handled.

wrandelshofer
Offline
Joined: 2004-11-11

Dear Scott,

I am thinking about how I would implement your API in my Look and Feel.

Currently, I believe I would do it this way:

> public int getPadding(JComponent source, JComponent target,
> int position, PaddingType type);

1. Depending on type, ask Source for its related padding or for its unrelated padding.
1.1 Source returns an instance of Insets.
2. Depending on type, ask Target for its related padding or for its unrelated padding.
2.1 Target returns an instance of Insets.
3. Depending on position return the greater value of the corresponding Insets attribute pairs of Source and Target.

> public int getPaddingRelativeToParent(JComponent parent,
> JComponent target, int position);

1. Ask Target for its related padding.
1.1 Target returns an instance of Insets.
2. Depending on position, return one of the four Inset attributes.

I wonder, if it is as simple as that, or if I am missing something.

In case, this would be really so simple, we could change the API into this:

public Insets getRelatedPadding(JComponent source);
public Insets getUnrelatedPadding(JComponent source);

What do you think?

With kind regards,
-Werner

wrandelshofer
Offline
Joined: 2004-11-11

Okay,

It ain't [i]that[/i] simple. :)
We have a different padding between components and window bounds.

Therefore here's how the API may look like:


public Insets getRelatedPadding(JComponent source);
public Insets getUnrelatedPadding(JComponent source);
public Insets getParentPadding(JComponent source);

I believe this is simpler than your original suggestion, because we do not have to do the checks for corresponding attribute pairs in the source and target Insets.

Also, the layout manager can cache the paddings, and thus only needs to retrieve them once from the API for a complete layout.

-Werner

Scott Violet

Hi Werner,

The position argument is meant to encapsulate the type. This avoids n
methods.

swing@javadesktop.org wrote:

> Okay,

> It ain't [i]that[/i] simple. :)
> We have a different padding between components and window bounds.
>

> Therefore here's how the API may look like:
>

>
> public Insets getRelatedPadding(JComponent source);
> public Insets getUnrelatedPadding(JComponent source);
> public Insets getParentPadding(JComponent source);
>

>

> I believe this is simpler than your original suggestion, because we do
> not have to do the checks for corresponding attribute pairs in the
> source and target Insets.
>

> Also, the layout manager can cache the paddings, and thus only needs to
> retrieve them once from the API for a complete layout.

Based on all the feedback here is the current API (in a class called
LayoutStyle):
[code]
public enum ComponentPlacement {
/**
* Enumeration value indicating the two components are
* visually related and will be placed in the same parent.
* For example, a JLabel providing a label for a
* JTextField is typically visually associated
* with the JTextField; the constant
RELATED
* is used for this.
*/
RELATED,

/**
* Enumeration value indicating the two components are
* visually unrelated and will be placed in the same parent.
* For example, groupings of components are usually visually
* separated; the constant UNRELATED is used for this.
*/
UNRELATED,

/**
* Enumeration value indicating the distance between the edge
* of the parent and child component is being requested.
*/
CHILD,

/**
* Enumeration value indicating the distance between the child
* and the edge of a parent is being requested.
*/
PARENT;
}

public int getPreferredGap(JComponent component1, JComponent
component2,
ComponentPlacement type, int position, JComponent parent);
public int getPreferredGap(Class c1Class,
Class c2Class, ComponentPlacement type,
int position, JComponent parent);

[/code]

The former methods is useful for places where you have both components,
the latter is useful for grid based layout managers that want to cache
values.

As far as I can tell the source and target are necessary for some visual
design guidelines that specify based on component types. For example,
jlf says labels should be 12 pixels away from the component they are
labeling. This maps to:

[code]
if (isLabel(component1) != isLabel(component2)) {
return 12;
}
[/code]

To allow for the return value to take into account borders or insets on
the component it takes actual instances. For example, checkboxs
typically have an empty border that is not drawn, to take that into
account you need to be able to call into the method.

-Scott

wrandelshofer
Offline
Joined: 2004-11-11

> The position argument is meant to encapsulate the
> type. This avoids n methods.

Okay. (I thought there were only two types.)

> As far as I can tell the source and target are
> necessary for some visual
> design guidelines that specify based on component
> types. For example,
> jlf says labels should be 12 pixels away from the
> component they are
> labeling. This maps to:
>
> [code]
> if (isLabel(component1) != isLabel(component2)) {
> return 12;
> }
> [/code]

Isn't this redundant with the "RELATED" type?

I mean, if getPreferredGap with the "RELATED" type is invoked, then shouldn't the implementation always return the 12 pixels value, even if there is not also an isLabel relationship present?
Or if an "isLabel" relationship a 'stronger' relationship than the "RELATED" type? In this case, wouldn't it be better to define a "LABEL" type for the API?
(I am still trying to make things simpler. ;)

> To allow for the return value to take into account
> borders or insets on
> the component it takes actual instances. For
> example, checkboxs
> typically have an empty border that is not drawn, to
> take that into
> account you need to be able to call into the method.

I agree that a component instance must be passed in. A component may have different preferred gaps depending on many individual factors, such as whether its border is drawn, whether it is a child of JToolBar, whether it uses a small or a large font, and so on...

-Werner

wrandelshofer
Offline
Joined: 2004-11-11

And yet another attempt to make things simpler. :)

I believe, that all children of a Container must have the same preferred gaps to the Container.

So, maybe we can fulfill all use cases with just the following API.


  public enum ComponentPlacement {
         /**
          * Enumeration value indicating the two components are
          * visually related and will be placed in the same parent.
          * For example, a JLabel providing a label for a
          * JTextField is typically visually associated
          * with the JTextField; the constant 
RELATED
          * is used for this.
          */
         RELATED,
 
         /**
          * Enumeration value indicating the two components are
          * visually unrelated and will be placed in the same parent.
          * For example, groupings of components are usually visually
          * separated; the constant UNRELATED is used for this.
          */
         UNRELATED,
     }
 
    /**
      * Returns the preferred margin between the provided component
      * and other components that are laid out on the same container.
      */
     public Insets getPreferredMargin(JComponent component,              ComponentPlacement type);
    /**
      * Returns the preferred padding between the provided container
      * and components that are laid out on it.
      */
     public Insets getPreferredPadding(JComponent container,              ComponentPlacement type);

Note, that I don't pass the parent to any of the API's, because it can be retrieved from the component. (If it needs to be).

Also I have dropped the API which works with classes instead of objects. Because using classes one can not return useful results. i.e. a layout manager that uses classes to lay out components can not give the same results like a layout manager that works with instances.

Message was edited by: wrandelshofer

Scott Violet

Hi Werner,

swing@javadesktop.org wrote:
> And yet another attempt to make things simpler. :)
>
> I believe, that all children of a Container must have the same padding to the Container.

Not necessarily so. In an attempt to account for perceived bounds JLF
specs things differently for buttons.

> /**
> * Returns the preferred margin between the provided component
> * and other components that are laid out on the same container.
> */
> public Insets getPreferredMargin(JComponent component, ComponentPlacement type);
> /**
> * Returns the preferred padding between the provided container
> * and components that are laid out on it.
> */
> public Insets getPreferredPadding(JComponent container, ComponentPlacement type);
>

I originally had something like this. I like the symmetry of keeping it
in terms of ints though. For layout managers like SpringLayout getting
the Insets is unnecessary and more work.

> Note, that I don't pass the parent to any of the API's, because it can
> be retrieved from the component. (If it needs to be).

Builders will want the ability to pass in a different component as the
parent. For example, if you're actively dragging a widget around the
builder may want to pass in a different parent then the actual parent.

> Also I have dropped the API which works with classes instead of objects.
> Because using classes one can not return useful results. i.e. a layout
> manager that uses classes to lay out components can not give the same
> results like a layout manager that works with instances.

I'm not a fan of that API either. It's there to appease folks that
don't want to pass in widgets, but want the ability to say something
like, this column will contain labels and the next textfields, what's
the appropriate padding.

-Scott

wrandelshofer
Offline
Joined: 2004-11-11

Dear Scott,

> Not necessarily so. In an attempt to account for
> perceived bounds JLF
> specs things differently for buttons.

Sad that the deadline for Mustang is so near.
It appears that support for perceived bounds is implemented anyway. Unfortunately this is now being sneaked in 'behind the scenes' and not at the API level.
If I had been aware about the upcoming baseline API and the padding API a few months earlier, my suggestions about the borderline API might have helped to make things easier.

At least, I know now, how I can workaround the lack of the borderline API using the padding API. :)

> I'm not a fan of that API either. It's there to
> appease folks that
> don't want to pass in widgets, but want the ability
> to say something
> like, this column will contain labels and the next
> textfields, what's
> the appropriate padding.

Yuk. Such an API won't work with Aqua components.
Basically, it won't work with any L&F that supports more than just one visual style for the same JComponent.
I would prefer forcing these folks to create an object of the desired type on their own, and have them pass that object as a 'prototype' into the method that takes objects as parameters. Such an approach will work with Aqua components, because it is now possible to configure the object before passing it to the API.

Under the give circumstances (the deadline and all the work that is already based on these API's), they are okay for me. I am not very enthusiastic about these API's, but at least, I can somehow make it work for my Quaqua L&F. (I guess I have to use negative padding values in some circumstances, but I am getting used to this.)

I hope, that in the long run, we can replace these two API's by the borderline API. Maybe for Java 1.7, or 1.8. ;)

Thanks for all your kind clarifications.
Also thanks for letting us (the Java community) discuss these API's. I know, how hard it is, to do this. There are always some 'slightly better' ideas popping up, but at one point, one has to do the implementation and move on.

Scott Violet

> Dear Scott,
>
>
>>Not necessarily so. In an attempt to account for
>>perceived bounds JLF
>>specs things differently for buttons.
>
>
> Sad that the deadline for Mustang is so near.

You got that right!

> It appears that support for perceived bounds is implemented anyway.
> Unfortunately this is now being sneaked in 'behind the scenes' and not
> at the API level.
> If I had been aware about the upcoming baseline API and the padding API
> a few months earlier, my suggestions about the borderline API might have
> helped to make things easier.
>
> At least, I know now, how I can workaround the lack of the borderline
> API using the padding API. :)

:)

>>I'm not a fan of that API either. It's there to
>>appease folks that
>>don't want to pass in widgets, but want the ability
>>to say something
>>like, this column will contain labels and the next
>>textfields, what's
>>the appropriate padding.
>
>
> Yuk. Such an API won't work with Aqua components.
> Basically, it won't work with any L&F that supports more than just one
> visual style for the same JComponent.
> I would prefer forcing these folks to create an object of the desired
> type on their own, and have them pass that object as a 'prototype' into
> the method that takes objects as parameters. Such an approach will work
> with Aqua components, because it is now possible to configure the object
> before passing it to the API.

I agree that the API can't work for all scenarios. One option is to
pull it;)

> Under the give circumstances (the deadline and all the work that is
> already based on these API's), they are okay for me. I am not very
> enthusiastic about these API's, but at least, I can somehow make it work
> for my Quaqua L&F. (I guess I have to use negative padding values in
> some circumstances, but I am getting used to this.)
>
> I hope, that in the long run, we can replace these two API's by the
> borderline API. Maybe for Java 1.7, or 1.8. ;)

After JavaOne I'm going to take a longer look into what you've done. If
it makes more sense and accomodates what I need perhaps we switch to it
now. We want to have the right API, not the right API for a release.

> Thanks for all your kind clarifications.
> Also thanks for letting us (the Java community) discuss these API's. I
> know, how hard it is, to do this.

And thanks for the valuable input!

> There are always some 'slightly
> better' ideas popping up, but at one point, one has to do the
> implementation and move on.

;)

-Scott

karsten
Offline
Joined: 2003-06-11

WHO SHALL ADDRESS THIS ISSUE?

From my perspective visual guidelines do not belong
to the Look and Feel but to the layout or build system,
a thing that can sit on top of a layout manager.

The L&F describes how components appear and behave;
visual guidelines and style vary with the platform;
a meta design may also change with the locale and
the application style.

In my opinion even the LayoutManager is not the
right place to request these information. The
layout manager API has been designed to compute
and set component bounds - nothing else.

I'd put platform style paddings, platform style
orientations (left-to-right vs. right-to-left),
as well as other meta design information in
customizable layout styles.

The JGoodies Forms class LayoutStyle provides an API
for non-customizable meta design information. There
are two concrete implementations, MacLayoutStyle and
WindowsLayoutStyle for the platform specific data.

HOW TO FIND AN APPROPRIATE SOLUTION?

It seems to me that we can better find a good
solution for the paddings and other layout issues,
if we start with the problem, not the solution.
Let's define a couple of tasks we want to solve.
Let's change the perspective so we can understand
the problems a Swing developer faces, who wants
to design and implement a layout for a single or
multiple platforms and for a single or multiple locales.

Let's say you want to design for Windows and Mac and
present the UI in a cross-platform L&f like Plastic.
Is the L&f the right place to provide paddings?
Would that better belong to a layout manager, or
to the layout system, or to non-viusual builders
that build the panels?

Let's say we want to deploy on Windows, Linux, Mac
and have to support English, German and Chinese.
The German texts are often longer than English texts;
Chinese can often express the same things with two glyphs.
On the other hand, Chinese tpyically requires a larger font
to make the UI readable/legible. If we want to achieve
a consistent panel design over multiple panels, developers,
teams, applications - where to specifiy that most
label columns shall be 85dlu wide in English and German,
but only 25dlu in Chinese?

Let's say we need to deploy on systems with significantly
different screen hardware resolutions. How to address this?

Let's say we are short of time and need to implement
a couple of layouts? Do we need to explicitly use the
padding information, or will they be used by a builder
or a visual builder tool?

Let's say we want to layout a panel with a couple of
labels/textfield, a radiobutton group, a resizable table
plus a button bar. Does the padding API provide all
information necessary?

Let's say our design crew creates a custom app style
(a meta design) that uses wide gaps for wide screens
but small gaps for smaller screen sizes. Can we
customize the paddings to implement the custom style?

Let's say Microsoft and Apple change their guidelines
and add new padding types. Is that addressed by our API?

The JGoodies Forms tutorial and the Forms Demo app
are starting points for a collection of layout tasks.
Both are intended to demonstrate what the Forms can do
and what it can't do. It is also a catalog of layouts
and layout implementations that developers can copy.

Hope this helps. Best regards,
Karsten Lentzsch

Scott Violet

Hi Karsten,

Thanks for the feedback.

I definitely agree that this in no way is going to ease most developers
job. Builders (both visual and non-visual) and easier layout managers
will address that issue. This API is meant to provide a way to get
information that is currently lacking from the toolkit, it is not for
all developers but rather folks writing new layout managers or visual
builders wanting to get information

LayoutStyle encapsulates a lot of what I wanted to address. Rather than
specifying two components LayoutStyle has explicit methods for getting
the information. This doesn't allow the return value to very based on
component type. For example, the windows style guidelines say that
between text labels and their associated controls use 3 DLUs, otherwise
use 4 DLUs between related controls. How would that be handled? JLF
has similar requirements that requiring new the two component types.

I would propose combining the approaches. I'll add a LayoutStyle class
that contains the single instance method: getPreferredGap. By default
it'll call to the ComponentUI methods then the LookAndFeel. LayoutStyle
will be pluggable so that you can substitute your own (should you want).
How does that sound?

Thanks,

-Scott

zander
Offline
Joined: 2003-06-13

> How does that sound?

It sounds like you missed this statement made before in this thread:
> > It seems to me that we can better find a good
> > solution for the paddings and other layout issues,
> > if we start with the problem, not the solution.

I'm seeing a solution in search of a problem. But I'm repeating myself.

skelvin
Offline
Joined: 2003-06-11

Hello again,
I like the proposal!
And I really do think the LAF is responsible for specifying default padding.
Of course it's up to the human designer and to the layout manager to use, change or ignore them. But honestly: Most GUI coders do no design at all and that's the way the result is looking like. So better enable layout managers to use sensible defaults.

At least both the Java Look and Feel Design Guidelines and the Aqua Guidelines deal with that topic, and I am pretty sure there are guidelines for Windows, KDE and others, too.

Java:
http://java.sun.com/products/jlf/ed2/book/HIG.Visual2.html#68004

Aqua (See spacing sections for each controls):
http://developer.apple.com/documentation/UserExperience/Conceptual/OSXHI...

I wouldn't be me, if I would not also criticize the API ;-)

* Isn't it time to get prepared for device resolution dependent padding somehow? Karsten's FormLayout pioneered this (though I am not sure how it is implemented exactly, i.e. how dialog units are converted to and from pixels). But maybe the next issue can already deal with it:

* "The return value is not intended to take into account the current size and position of target or source"
It should be possible though to take into account the minimum, preferred and maximum size of a component, and the javadoc should clarify this.
From the Aqua guidelines for button controls:
Spacing:
- Full size: Leave at least 12 pixels of space between buttons placed horizontally or stacked.
- Small: Leave at least 10 pixels.
- Mini: Leave at least 8 pixels.
Where Full, Small and Mini are different sizes (or better 'size styles'?).

* Can't we have enums instead of SwingConstants? I would favour a little inconsistency with legacy APIs in return of a self-documenting APIs and no need of IllegalArgumentException. Maybe have a getter in the Alignment enum class that, given a valid SwingConstants value, returns the Alignment constant?

* How about 'LEADING' and 'TRAILING' values?

* The padding between components might alsop need to take the parent into account. For example two buttons might be closer together in a toolbar than in another container. So either use allow to use the current parent of the components (then the parent argument should be removed from the getPaddingRelativeToParent() method also, as it can be inferred). Or else add a 'parent' argument to the getPadding() method.

* Many custom components do not care to provide a separate UI class. So they can never participate in the default padding mechanism. I can live with that, but maybe there is an easy way to allow for this.

It is close to impossible to do full justice to the LAF guidelines automatically, e.g. in the Java LAF guidelines:
"When you use mouse-over feedback, space individual toolbar buttons zero pixels apart within a group. Space groups of toolbar buttons 11 pixels apart."

Scott Violet

Hello Stephen,

> I wouldn't be me, if I would not also criticize the API ;-)

That's what I want;)

> * Isn't it time to get prepared for device resolution dependent padding
> somehow? Karsten's FormLayout pioneered this (though I am not sure how
> it is implemented exactly, i.e. how dialog units are converted to and
> from pixels). But maybe the next issue can already deal with it:

We will most definitely need to deal with resolution independence soon.
It's a much larger issue though, and not one I want to try and address
outside the scope of the big picture. You'll notice we don't use the
word pixel anywhere in this proposal.

> * "The return value is not intended to take into account the current
> size and position of target or source"
> It should be possible though to take into account the minimum, preferred
> and maximum size of a component, and the javadoc should clarify this.
> From the Aqua guidelines for button controls:
> Spacing:
> - Full size: Leave at least 12 pixels of space between buttons placed
> horizontally or stacked.
> - Small: Leave at least 10 pixels.
> - Mini: Leave at least 8 pixels.
> Where Full, Small and Mini are different sizes (or better 'size styles'?).

Are full, small and mini properties of the button, or is it really just
its size?

> * Can't we have enums instead of SwingConstants? I would favour a little
> inconsistency with legacy APIs in return of a self-documenting APIs and
> no need of IllegalArgumentException. Maybe have a getter in the
> Alignment enum class that, given a valid SwingConstants value, returns
> the Alignment constant?

You have a valid point, but I would only want to do that if we support
the constant in all the other places. That is not something I want to
do now.

> * How about 'LEADING' and 'TRAILING' values?

As far as I can tell all the visual design guidelines mention absolute
direction, and not a direction that depends upon component orientation.
As such, I don't think LEADING/TRAILING make sense.

> * The padding between components might alsop need to take the parent
> into account. For example two buttons might be closer together in a
> toolbar than in another container. So either use allow to use the
> current parent of the components (then the parent argument should be
> removed from the getPaddingRelativeToParent() method also, as it can be
> inferred). Or else add a 'parent' argument to the getPadding() method.

Good point. I'll mention that and remove the parent argument from
getPaddingRelativeToParent.

> * Many custom components do not care to provide a separate UI class. So
> they can never participate in the default padding mechanism. I can live
> with that, but maybe there is an easy way to allow for this.

I went this route for two reasons:
. I wanted to enable 3rd party components to have custom paddings.
. I didn't want to add API to JComponent proper that almost all
developers will never touch.
. It really is specific to the look and feel.

I agree with you that most people never provide a ComponentUI, but at
least this API provides a way for developers to accommodate different
paddings if they want to.

> It is close to impossible to do full justice to the LAF guidelines
> automatically, e.g. in the Java LAF guidelines:
> "When you use mouse-over feedback, space individual toolbar buttons
> zero pixels apart within a group. Space groups of toolbar buttons 11
> pixels apart."

Yes, the jlf guidelines have a handful of issues:(

Thanks for the feedback!

-Scott

zander
Offline
Joined: 2003-06-13

Oh; I solved these issues in my layout manager using spacing and margins which are layout-manager wide.
You might want to look at that, its a proven idea another toolkit has been using for about 7 years now. I really like it.

http://uic.sf.net/index.phtml?target=product/NaturalLayout/view.phtml
Be sure to try the webstart-able demo. (use the example menu for fast results)

zander
Offline
Joined: 2003-06-13

Hi Scott, proposals are going well :) Very nice!

I have some issues with this proposal;
* the absolute space between two components is not the responsibility of the look and feel or of the components itself. Only the layout manager (well, human designer) can know this.
* Please don't use SwingConstants.NORTH etc since SwingConstants.TOP etc have similar values making it impossible to correctly throw those IllegalArgumentExcetpions

* Just to be sure (I'm not sure this proposal is targeting this) the perceived bounds problem [1] can't be solved with this.

Cheers!

1) http://www.javadesktop.org/forums/thread.jspa?messageID=78404#78404

Scott Violet

swing@javadesktop.org wrote:

> Hi Scott, proposals are going well :) Very nice!
>
> I have some issues with this proposal;
> * the absolute space between two components is not the responsibility of
> the look and feel or of the components itself. Only the layout manager
> (well, human designer) can know this.

I agree that it is the responsibility of layout managers to honor the
padding but where will layout managers get this information? Each of
the various platform look and feels provides guidelines as to how far
apart various components should be placed:

Windows:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/h...
Metal: http://java.sun.com/products/jlf/ed2/book/HIG.Visual2.html
Gnome:
http://developer.gnome.org/projects/gup/hig/2.0/design-window.html#windo...

Wouldn't it be nice to provide this information in Swing so that each
layout manager doesn't need to duplicate it?

The API on LookAndFeel addresses this. To allow for custom components
(outside of Swing) to provide different values the API also exists on
the ComponentUI. The expectation is that you only ever call the
LookAndFeel methods, but if you're writing custom components you may
want to override the ComponentUI methods.

This API also enables visual builders to provide guiding lines as to
preferred distances between components.

> * Please don't use SwingConstants.NORTH etc since SwingConstants.TOP etc
> have similar values making it impossible to correctly throw those
> IllegalArgumentExcetpions

These constants are used extensively through out swing. I don't want to
introduce another constant that means the same thing but is specific to
this API.

> * Just to be sure (I'm not sure this proposal is targeting this) the
> perceived bounds problem [1] can't be solved with this.

This API is not directly trying to address the perceived bounds problem.

-Scott

zander
Offline
Joined: 2003-06-13

> > I have some issues with this proposal;
> > * the absolute space between two components is not the responsibility of
> > the look and feel or of the components itself. Only the layout manager
> > (well, human designer) can know this.
>
> I agree that it is the responsibility of layout
> managers to honor the
> padding but where will layout managers get this
> information?

This information provided by the designer (and this can be a builder) based on the position of the widget in the Swing hierarchy.

> Each of
> the various platform look and feels provides
> guidelines as to how far
> apart various components should be placed:

Yes, they do. That is; the Windows one does. The Gnome one has very simple rules and the Mac one has very non-simple rules.
The mac styleguide says that spacing between a button and componentX is different based on what the function of that button is (control or toolbar or whatever).
This is what I meant with my point that the responsibility of function lies not with the component. Since its based on information that spans a lot of different components.
If you want to know if a button is a toolbar button (meaning the indent should be different), how many times should it do a getParent() and check if the parent is a JToolBar? You don't want toolbar-indenting to be lost if you wrap it in another JPanel..

So my objection to this is based on the fact that looking at 2 widgets does not give you the information needed to make this decision. With this proposal the implementation will be so hard to do correctly it will be useless for anything but the Windows L&F which kind of defeats the purpose, don't you think?

> Wouldn't it be nice to provide this information in
> Swing so that each layout manager doesn't need to duplicate it?

Sure; use the builders from Karsten, they provide this by making the programmer state if its a normal button or something else.

> > * Please don't use SwingConstants.NORTH etc since
> e SwingConstants.TOP etc
> > have similar values making it impossible to
> o correctly throw those
> > IllegalArgumentExcetpions
>
>
> These constants are used extensively through out
> swing.

Thats not really a great reason to make the same mistake again..
Then at least loose the IllegalArgumentException since it gives developers a false sense of security.
Or have you never made the mistake of using EAST instead of RIGHT?

Scott Violet

Hi Thomas,

In rereading the thread online I realized this message never made it
out, I'm resending it.

swing@javadesktop.org wrote:

>>> I have some issues with this proposal;
>>> * the absolute space between two components is not the
responsibility of
>>> the look and feel or of the components itself. Only the layout manager
>>
>>
>> > (well, human designer) can know this.
>>
>> I agree that it is the responsibility of layout
>> managers to honor the padding but where will layout managers get this
>> information?
>
>
>
> This information provided by the designer (and this can be a builder)
> based on the position of the widget in the Swing hierarchy.

Where does the designer or builder get this information though? Doesn't
it seem useful to have a standard place to get the spacing? Think of
the developers that don't have a visual designer working on their
project, what are they to use? Wouldn't something be better than
picking some random values?

>> Each of the various platform look and feels provides
>> guidelines as to how far apart various components should be placed:
>
>
>
> Yes, they do. That is; the Windows one does. The Gnome one has very
> simple rules and the Mac one has very non-simple rules.
> The mac styleguide says that spacing between a button and componentX is
> different based on what the function of that button is (control or
> toolbar or whatever).

If you want to conditionalize based on the component you can, similarly
you could conditionalize based on some characteristic of the component
such as it's preferred size.

> This is what I meant with my point that the responsibility of function
> lies not with the component. Since its based on information that spans a
> lot of different components.

I believe we're in agreement. In that for the most part LookAndFeel
should be making this decision. Do you agree?
Delegating to the UI is a way for 3rd party component vendors to support
various look and feels and customize the padding. It's not the common
case and by default the ComponentUI method will return -1 indicating you
shouldn't use the value.

> If you want to know if a button is a toolbar button (meaning the indent
> should be different), how many times should it do a getParent() and
> check if the parent is a JToolBar? You don't want toolbar-indenting to
> be lost if you wrap it in another JPanel..

I've changed it to pass in the parent. This is necessitated by builders
that don't really want to parent the component to get the value. It
would also allow for the situation you're interested in.

> So my objection to this is based on the fact that looking at 2 widgets
> does not give you the information needed to make this decision. With
> this proposal the implementation will be so hard to do correctly it will
> be useless for anything but the Windows L&F which kind of defeats the
> purpose, don't you think?

What specific case are you suggesting? The parent (which is not
necessarily the direct parent) can be passed in, and you can look at the
specifics of the widgets if you need to.

Alternatively if I am missing something what extra information do you need?

>> Wouldn't it be nice to provide this information in
>> Swing so that each layout manager doesn't need to duplicate it?
>
>
>
> Sure; use the builders from Karsten, they provide this by making the
> programmer state if its a normal button or something else.

Can't this be determined from the buttons? If not, what information do
you need? I could make the method take alternating key value pairs that
provide extra information, but I'm a bit hesitant to do that as I don't
know how LookAndFeels would honor that or know what keys to look for.

Thanks for the feedback.

-Scott

zander
Offline
Joined: 2003-06-13

> >> Each of the various platform look and feels provides
> >> guidelines as to how far apart various components should be placed:
> >
> > Yes, they do. That is; the Windows one does. The Gnome one has very
> > simple rules and the Mac one has very non-simple rules.
> > The mac styleguide says that spacing between a button and componentX is
> > different based on what the function of that button is (control or
> > toolbar or whatever).
>
> If you want to conditionalize based on the component
> you can, similarly
> you could conditionalize based on some characteristic
> of the component
> such as it's preferred size.

Which characteristics would those be? There is no property or size or whatever different for a toolbar button or a control button. Similarly a label does not know if it is used for a textfield or for something else.
Unless you want to make the designer set some such property explicitly, which brings us back to my point that the designer should supply these marks anyway, register them with the layoutmanager instead, which means this framework is not needed anyway.

> > This is what I meant with my point that the responsibility of function
> > lies not with the component. Since its based on information that spans a
> > lot of different components.
>
> I believe we're in agreement. In that for the most
> part LookAndFeel should be making this decision. Do you agree?

Ehm; I don't like ruining the party; but I said that logic can't deduce function by looking at instances (or classes). How does that imply the L&F should handle these decisions then?

Scott Violet

Hi Thomas,

swing@javadesktop.org wrote:

>>>> Each of the various platform look and feels provides
>>>> guidelines as to how far apart various components should be placed:
>>
>>
>> >
>>
>>> Yes, they do. That is; the Windows one does. The Gnome one has very
>>> simple rules and the Mac one has very non-simple rules.
>>> The mac styleguide says that spacing between a button and componentX is
>>> different based on what the function of that button is (control or
>>
>>
>> > toolbar or whatever).
>>
>> If you want to conditionalize based on the component
>> you can, similarly you could conditionalize based on some characteristic
>> of the component such as it's preferred size.
>
>
>
> Which characteristics would those be? There is no property or size or
> whatever different for a toolbar button or a control button.

The parent will be passed in, if you want to conditionalize based on
that you can.

> Similarly a
> label does not know if it is used for a textfield or for something else.

The two components are passed in. So that if you do care specifically
about labels next to text fields you could conditionalize appropriately.

> Unless you want to make the designer set some such property explicitly,
> which brings us back to my point that the designer should supply these
> marks anyway, register them with the layoutmanager instead, which means
> this framework is not needed anyway.

Of the projects I have been involved in having a visual designer is the
exception, not the norm. Think of all those internal corporate apps
developed internally for a specific function. Most likely they will not
have a visual designer. We need to have a way for such developers to
get a good experience without hiring a designer.

>>> This is what I meant with my point that the responsibility of function
>>> lies not with the component. Since its based on information that
spans a
>>
>>
>> > lot of different components.
>>
>> I believe we're in agreement. In that for the most
>> part LookAndFeel should be making this decision. Do you agree?
>
>
>
> Ehm; I don't like ruining the party; but I said that logic can't deduce
> function by looking at instances (or classes). How does that imply the
> L&F should handle these decisions then?

Can you give an example of where the proposed API would not work? Early
on you sighted the Mac guidelines specifying different sized buttons
should be placed different distances apart. I believe that could be
handled by looking at the font or other properties of the button.

That Karsten provides API to accomplish similar functionality to me
proves this API is useful.

-Scott

zander
Offline
Joined: 2003-06-13

> The parent will be passed in, if you want to
> conditionalize based on
> that you can.
...
> The two components are passed in. So that if you do
> care specifically
> about labels next to text fields you could
> conditionalize appropriately.

...
> Can you give an example of where the proposed API
> would not work?

I just did; but your answers seem to claim that the layout manager can call the widgets in such a way to get the data anyway. Which brings me back to the point that the layout manager should know this info; but you still don't want the layout manager to learn this from the designer since there might not be a designer on the team.

Your design basically does not pinpoint where the intelligence to know what kind of UI features we are using will be programmed. And your answers give me the distinct impression you don't know either since you simply say it can be anywhere the implemented wants it to be.

> I believe that could be
> handled by looking at the font or other properties of
> the button.

I suggest you find some of these UIs which follow these guidelines and look at them at different levels; you will find out that the widgets are not themselves different at all.

> That Karsten provides API to accomplish similar
> functionality to me
> proves this API is useful.

Sure; thats fine. I can't imagine how to implement the features you want since the data to make the decisions you need is simply not available anywhere except in the designers head. If you lack a designer you need to make it easier for a programmer to mark buttons as control buttons (see the StandardDialog[1] which does this, as well as the ToolBarButton (also UICompiler) to mark them as.. You get the picture).
Karsten supplies builders like the ButtonBarBuilder which creates buttons marked as toolbarbuttons, he has methods that create a label with the jtextfield attached to mark those as combined.

Again; this means that the designer really does supply the datapoints needed to do what you intend to do. Without that info; you can't succeed. Your API will not solve that problem at all.

1) http://uic.sf.net/index.phtml?target=product/StandardDialog/view.phtml

Scott Violet

Hi Thomas,

swing@javadesktop.org wrote:

>> The parent will be passed in, if you want to
>> conditionalize based on that you can.
>
>
> ...
>
>> The two components are passed in. So that if you do
>> care specifically about labels next to text fields you could
>> conditionalize appropriately.
>
>
>
> ...
>
>> Can you give an example of where the proposed API
>> would not work?
>
>
>
> I just did; but your answers seem to claim that the layout manager can
> call the widgets in such a way to get the data anyway.

I'm confused. You say this API can't handle labels next to textfields
and I say it can. What am I missing?

> Which brings me
> back to the point that the layout manager should know this info;

The LayoutManager should call into LayoutStyle.

> but you
> still don't want the layout manager to learn this from the designer
> since there might not be a designer on the team.

If you have a designer you can provide your own instance of LayoutStyle
that gets used. For example, in NaturalLayout you have the developer
pick margins and spacing. Why not have that come from a LayoutStyle
that you know will be appropriate based on the look and feel.

> Your design basically does not pinpoint where the intelligence to know
> what kind of UI features we are using will be programmed. And your
> answers give me the distinct impression you don't know either since you
> simply say it can be anywhere the implemented wants it to be.

I don't follow this comment.

>> I believe that could be handled by looking at the font or other
properties of
>> the button.
>
>
>
> I suggest you find some of these UIs which follow these guidelines and
> look at them at different levels; you will find out that the widgets are
> not themselves different at all.

I don't understand. You have raised a couple of concerns on this
thread: labels next to text fields, placement of different buttons for
OS X, command buttons and the ability for the designer to override how
the look and feel would normally lay things out. It is my belief that
all could be handled by this proposed API. What am I missing?

>> That Karsten provides API to accomplish similar
>> functionality to me proves this API is useful.
>
>
>
> Sure; thats fine. I can't imagine how to implement the features you want
> since the data to make the decisions you need is simply not available
> anywhere except in the designers head. If you lack a designer you need
> to make it easier for a programmer to mark buttons as control buttons
> (see the StandardDialog[1] which does this, as well as the ToolBarButton
> (also UICompiler) to mark them as.. You get the picture).

A standard API to tag buttons would be nice and helpful here. In the
mean time I believe looking at the parent would suffice.

> Karsten supplies builders like the ButtonBarBuilder which creates
> buttons marked as toolbarbuttons, he has methods that create a label
> with the jtextfield attached to mark those as combined.
>
> Again; this means that the designer really does supply the datapoints
> needed to do what you intend to do. Without that info; you can't
> succeed. Your API will not solve that problem at all.

Most developers would know that buttons that are going into a toolbar
are toolbar buttons and what the command buttons are. I don't believe
you need a designer for that.

-Scott

zander
Offline
Joined: 2003-06-13

Scott wrote:
> I don't understand. You have raised a couple of
> concerns on this
> thread: labels next to text fields, placement of
> different buttons for
> OS X, command buttons and the ability for the
> designer to override how
> the look and feel would normally lay things out. It
> is my belief that
> all could be handled by this proposed API. What am I
> missing?

That I also noted that your assertions are incorrect meaning there is no correct implementation for your interface. It tries to solve a n-variable equation with more then 1 variable unknown.

I have a distinct feeling of deja-vu in this thread; I give up.