+ All Categories
Home > Documents > Layout How multiple components are composed to build interfaces.

Layout How multiple components are composed to build interfaces.

Date post: 18-Jan-2016
Category:
Upload: isaac-jacobs
View: 227 times
Download: 0 times
Share this document with a friend
32
Layout Layout How multiple components are How multiple components are composed to build interfaces composed to build interfaces
Transcript
Page 1: Layout How multiple components are composed to build interfaces.

LayoutLayout

How multiple components are How multiple components are composed to build interfaces composed to build interfaces

Page 2: Layout How multiple components are composed to build interfaces.

Placement of widgetsPlacement of widgets We need to be able to control the placement of

widgets on the screen

Need to be able to handle movement and repositioning and keep these consistent

Keeping objects geometrically consistent is a fundamental problem. • When the objects are widgets it is called the layout

problem.• When the objects are other things it is called constraints.

Page 3: Layout How multiple components are composed to build interfaces.

Change in Menu from 1 to 2 lines

Moved but same orientation Scroll bars and palette unchaged wrt edge of frame

Page 4: Layout How multiple components are composed to build interfaces.

LayoutLayout

We need to programme interfaces to ensure all We need to programme interfaces to ensure all widgets move appropriately. widgets move appropriately.

Three basic algorithms underpin layout Three basic algorithms underpin layout • Fixed positionFixed position• Edge anchored Edge anchored • Variable intrinsic sizeVariable intrinsic size

For each approach we need to consider For each approach we need to consider 1.1. whatwhat information must be stored with the widgetsinformation must be stored with the widgets from from

which the layout can be computedwhich the layout can be computed

2.2. what is the algorithmwhat is the algorithm for computing the layout, for computing the layout,

3.3. how will the interface designer specify the layouthow will the interface designer specify the layout either either interactively or programmatically. interactively or programmatically.

Page 5: Layout How multiple components are composed to build interfaces.

Fixed Position Layout Fixed Position Layout

Simplest layout approach assign every widget a Simplest layout approach assign every widget a fixed rectanglefixed rectangle• Coordinates relative to the parent Coordinates relative to the parent • Good for fixed interface that you do not want to resize or Good for fixed interface that you do not want to resize or

whose components do not change. whose components do not change.

Page 6: Layout How multiple components are composed to build interfaces.
Page 7: Layout How multiple components are composed to build interfaces.

public class Widget {

other fields and methods public Rectangle desiredBounds;

public void doLayout(Rectangle newBounds) { setBounds(newBounds);

foreach child widget C { Rectangle newChildBounds=

new Rectangle(newBounds.left+C.desiredBounds.left, newBounds.Top+C.desiredBounds.top,

C.desiredBounds.width, C.desiredBounds.height); C.doLayout(newChildBounds);

} }

}

Simple rectangle for each widgetSimple rectangle for each widget Container widget sets the childs bounds location Container widget sets the childs bounds location

to its own plus the child’s to its own plus the child’s

Page 8: Layout How multiple components are composed to build interfaces.

Fixed LayoutFixed Layout Advantages

• a simple algorithm• minimal data • very simple model to specify.

Designing Programmatically Designing Programmatically • construct a rectangle with the desired location and size• set desiredBounds • add the widget to its container.

Disadvantage Disadvantage • Resizing not handled at all well Resizing not handled at all well

To small parts of components clipped or not shown at allTo small parts of components clipped or not shown at all To big – all in the top corner To big – all in the top corner

Page 9: Layout How multiple components are composed to build interfaces.

Edge anchored layoutEdge anchored layout Modifying widgets so that their edges can be anchored to the Modifying widgets so that their edges can be anchored to the

edges of their container’s rectangle. edges of their container’s rectangle. • widget has coordinates for widget has coordinates for left, right, top and bottomleft, right, top and bottom..• interpretation depends upon the boolean values interpretation depends upon the boolean values anchorLeft, anchorLeft,

anchorRight, anchorTop, anchorBottomanchorRight, anchorTop, anchorBottom. . • widget has a widget has a desiredWidthdesiredWidth and and desiredHeightdesiredHeight. .

Edges are either anchored or notEdges are either anchored or not• If If anchoredanchored then it is a fixed distance away from the corresponding then it is a fixed distance away from the corresponding

container edge. container edge.

The algorithms for the X and Y axes are independent and identical. The algorithms for the X and Y axes are independent and identical. • If If only one edge is anchoredonly one edge is anchored, then the desired width is used to , then the desired width is used to

determine the location of the other edge. determine the location of the other edge. • If If neither edge is anchoredneither edge is anchored, then the left value is used to compute a , then the left value is used to compute a

proportional distance between the container edges and the desired proportional distance between the container edges and the desired width is used for the other edge. width is used for the other edge.

• Both edges are anchoredBoth edges are anchored, they follow their respective edges. , they follow their respective edges.

Page 10: Layout How multiple components are composed to build interfaces.

Public class Widget {

. . . . other fields and methods . . . public Rectangle bounds; public int left, right, top, bottom; public boolean anchorLeft, anchorRight, anchorTop, anchorBottom; public int width, height; public const int MAXSIZE=4096; public void doLayout( Rectangle newBounds) {

bounds=newBounds; foreach child widget C { Rectangle childBounds=new Rectangle();

if (C.anchorLeft) { childBounds.left=newBounds.left+C.left;

if (C.anchorRight) { childBounds.right=newBounds.right-C.right; } else { childBounds.right=childBounds.left+C.width; }

} else if (C.anchorRight) // right is anchored left is not { childBounds.right=newBounds.right-C.right;

childBounds.left=childBounds.right-C.width; } else // neither edge is anchored { childBounds.left = newBounds.width*C.left/MAXSIZE; childBounds.right=childBounds.left+C.width; } . . . . perform similar computation for Y . . . . C.doLayout(childBounds);

} }

}

Page 11: Layout How multiple components are composed to build interfaces.

Key conceptsKey concepts Container does the layout work on the widgets Container does the layout work on the widgets

childrenchildren

To lay out a widget, a programmer sets the various member fields and adds the widget to its container.

The container then will make certain that the widget’s bounds are placed in the correct position.

Programming this interactively requires a special Programming this interactively requires a special interface to highlight the edge relationships and interface to highlight the edge relationships and specify how they are boundspecify how they are bound

Page 12: Layout How multiple components are composed to build interfaces.

resize

Page 13: Layout How multiple components are composed to build interfaces.

Variable intrinsic size layout On many occasions he designer does not want to manually

position the widgets Create group and have them position themselves

• Menus• Changes in language/font for labels

Want to automatically adapt the layout to changes in interface content • Each widget knows how much screen space it can reasonably

use (intrinsic size) • Each container has a plan for how to allocate screen space

based on the needs of its children. Recursively arranging containers with various layout plans This is main approach used in Java

Page 14: Layout How multiple components are composed to build interfaces.

Layout algorithm Layout algorithm

Based on two recursive passes Based on two recursive passes • first pass requests each widget to report its desired size. • second pass sets the widget bounds

public void doLayout(Rectangle newBounds) {

foreach child widget C { ask for desired size of C } //based on desired sizes and newBounds, decide where//each child should go foreach child widget C { C.doLayout( new bounds for C); }

}

Page 15: Layout How multiple components are composed to build interfaces.

Intrinsic size layouts ask a widget for Intrinsic size layouts ask a widget for • minimum sizeminimum size (the smallest dimensions that (the smallest dimensions that

it can effectively use), it can effectively use), • desired sizedesired size (the dimensions that would work (the dimensions that would work

best for this widget) best for this widget) • maximum sizemaximum size (the largest dimensions that it (the largest dimensions that it

can effectively use). can effectively use). Determined by nature of each widget Determined by nature of each widget Containers calculate this based on the size Containers calculate this based on the size

of its children of its children

Page 16: Layout How multiple components are composed to build interfaces.

Widget class extended to handle sizes for layout Widget class extended to handle sizes for layout Each component implements in own way Each component implements in own way

public class Dimension { public int width;

public int height; } public class Widget {

. . . other methods and fields . . . public Dimension getMinSize() { . . . } public Dimension getDesiredSize() { . . . } public Dimension getMaxSize() { . . . }

}

Page 17: Layout How multiple components are composed to build interfaces.

Sizes of Simple Widgets Sizes of Simple Widgets

Page 18: Layout How multiple components are composed to build interfaces.

public class Button { . . . other methods and fields . . .

public Dimension getMinSize() { int minWidth = bevelWidth*2+font.getLength(labelText);

int minHeight = bevelWidth*2+font.getHeight(); return new Dimension(minWidth,minHeight);

} public Dimension getDesiredSize() { int desWidth = bevelWidth*2+marginWidth*2+font.getLength(labelText);

int minHeight=bevelWidth*2+marginHeight*2+font.getHeight(); return new Dimension(desWidth,desHeight)

} public Dimension getMaxSize() { return getDesiredSize(); }

}

Desire sizes includes the marginDesire sizes includes the margin Minimum size looses the marginMinimum size looses the margin Font details used to calculate size based on text Font details used to calculate size based on text

in labelin label

Page 19: Layout How multiple components are composed to build interfaces.

Simple container layouts Simple container layouts

The simplest containers are the vertical and horizontal stack. Box widgetsBox widgets in Java in Java

Vertical Stack

Horizontal Stack

A B C D

Page 20: Layout How multiple components are composed to build interfaces.

public class HorizontalStack {

public Dimension getMinSize() { int minWidth=0;

int minHeight=0; foreach child widget C { Dimension childSize = C.getMinSize();

minWidth += childSize.width; if (minHeight<childSize.height) { minHeight=childSize.height; }

} return new Dimension(minWidth,minHeight);

} public Dimension getDesiredSize() { similar to getMinSize using C.getDesiredSize() } public Dimension getMaxSize() { similar to getMinSize using C.getMaxSize() }

}

Width1 Width2 Width3Width4

Page 21: Layout How multiple components are composed to build interfaces.

doLayout() for horizontal stack when a new window is opened

• request the desired size of the root widget and allocate that as the window size.

• BUT, there may not be enough screen space for a window that big.

Space is allocated among the children depends upon • whether the width is less than min • greater than min but less than desired • greater than desired but less than max• greater than max.

The idea of the algorithm is to give each child as much as possible and then divide up the remainder proportionally among the children according to their requests.

Page 22: Layout How multiple components are composed to build interfaces.

public class HorizontalStack {

. . . the other methods and fields . . . public void doLayout(Rectangle newBounds) { Dimension min = getMinSize();

Dimension desired = getDesiredSize(); Dimension max = getMaxSize(); If (min.width>=newBounds.width) { // give all children their minimum and let them be clipped

int childLeft=newBounds.left; foreach child widget C { Rectangle childBounds = new Rectangle();

childBounds.top=newBounds.top; childBounds.height=newBounds.height; childBounds.left=childLeft; childBounds.width= C.getMinSize().width; childLeft+=childBounds.width; C.doLayout(childBounds);

} }

Page 23: Layout How multiple components are composed to build interfaces.

else if (desired.width>=newBounds.width) { // give min to all and proportional on what is available for desired

int desiredMargin = desired.width-min.width; float fraction= (float)(newBounds.width-min.width)/desiredMargin; int childLeft=newBounds.left; foreach child widget C { Rectangle childBounds=new Rectangle();

childBounds.top=newBounds.top; childBounds.height=newBounds.height; childBounds.left=childLeft; int minWidth=C.getMinSize().width; int desWidth=C.getDesiredSize().width; childBounds.width=minWidth+(desWidth-minWidth)*fraction; childLeft+=childBounds.width; C.doLayout(childBounds);

} }

Page 24: Layout How multiple components are composed to build interfaces.

else { // allocate what remains based on maximum widths

int maxMargin = max.width-desired.width; float fraction= (float)(newBounds.width-desired.width)/maxMargin; int childLeft=newBounds.left; foreach child widget C { . . . Similar code to previous case . . . }

} }

}

Page 25: Layout How multiple components are composed to build interfaces.

Combining layoutsCombining layouts

Use multiple horizontal and vertical stacks to Use multiple horizontal and vertical stacks to produce layouts produce layouts

Page 26: Layout How multiple components are composed to build interfaces.

Efficiency of layoutEfficiency of layoutProblem 1 : Recursion The window will call the root widget to ask for its desired size. The root widget will recursively call all of its children to compute that size.

• When the root widget starts to do its layout it will call the Palette group’s desired sizes again.

• When the Palette group starts its own layout it will call the Colors group’s desired sizes yet again

• finally when the Colors group does its layout it will call desired sizes on the text box.

• The desired size methods on the Colors text box was called at least 4 times.

Problem 2: Changes. The size of a window may be changed many times but the desires sizes of the various widgets do not change often.Most systems cache but what happens when things do change

• an invalidate() method is provided that informs the parent widget that the desired sizes are no longer correct.

• invalidate() method not only sets its own sizes to be invalid, but also sends the invalidate() message to its container.

• Java/Swing does not propagate invalidate() up the tree causing interfaces not to change when they might be expected to.

Page 27: Layout How multiple components are composed to build interfaces.

public class HorizontalStack { private Dimension minSize;

private Dimension desiredSize; private Dimension maxSize; private boolean sizesAreValid; public Dimension getMinSize() { if (sizesAreValid)

return minSize; int minWidth=0; int minHeight=0; foreach child widget C { Dimension childSize = C.getMinSize();

minWidth += childSize.width; if (minHeight<childSize.height) { minHeight=childSize.height; }

} sizesAreValid=true; return new Dimension(minWidth,minHeight);

}

public Dimension getDesiredSize() { similar to getMinSize using C.getDesiredSize() }

public Dimension getMaxSize() { similar to getMinSize using C.getMaxSize() }

public void invalidate() { sizesAreValid=false;

if (myContainer!=null) myContainer.invalidate();

} }

Page 28: Layout How multiple components are composed to build interfaces.

public class HorizontalStack { private Dimension minSize;

private Dimension desiredSize; private Dimension maxSize; private boolean sizesAreValid; public Dimension getMinSize() { if (sizesAreValid)

return minSize; int minWidth=0; int minHeight=0; foreach child widget C { Dimension childSize = C.getMinSize();

minWidth += childSize.width; if (minHeight<childSize.height) { minHeight=childSize.height; }

} sizesAreValid=true; return new Dimension(minWidth,minHeight);

}

public Dimension getDesiredSize() { similar to getMinSize using C.getDesiredSize() }

public Dimension getMaxSize() { similar to getMinSize using C.getMaxSize() }

public void invalidate() { sizesAreValid=false;

if (myContainer!=null) myContainer.invalidate();

} }

Page 29: Layout How multiple components are composed to build interfaces.

Spatial arrangementsSpatial arrangements Simple Stacks not enough to provide layouts Simple Stacks not enough to provide layouts Need some more control over spacing between componentsNeed some more control over spacing between components We use “spreaders” and “spacers” to do this We use “spreaders” and “spacers” to do this

• In java this is the role of the In java this is the role of the Box.Filler Box.Filler classclass Special widgets that are not drawn Special widgets that are not drawn

• Invisible Invisible • Have min, desired and max sizes Have min, desired and max sizes

Spacer Spacer • min, desired and max sizes set to same value ensuring fixed min, desired and max sizes set to same value ensuring fixed

space between widgetsspace between widgets Spreader Spreader

• Small min and desired but large max making spacing widgets Small min and desired but large max making spacing widgets apartapart

Use of spreaders and spacer is effective but not that Use of spreaders and spacer is effective but not that intuitive for new designers. intuitive for new designers.

Page 30: Layout How multiple components are composed to build interfaces.

Layout ManagersLayout Managers

Separate objects that handle a particular style of Separate objects that handle a particular style of layout layout

Desired layout for containers is a property of the Desired layout for containers is a property of the container container

Page 31: Layout How multiple components are composed to build interfaces.

public interface LayoutManager {

public Dimension getMinSize(Widget containerWidget); public Dimension getDesiredSize(Widget containerWidget); public Dimension getMaxSize(Widget containerWidget); public void doLayout(Rectangle newBounds, Widget containerWidget);

} public class Widget {

. . . other methods and fields . . . private Dimension minSize; private Dimension desiredSize; private Dimension maxSize; private boolean sizesAreValid; private LayoutManager myLayout; public LayoutManager getLayoutManager() { return myLayout; } public void setLayoutManager(LayoutManager newLayout ) { myLayout=newLayout;

invalidate(); } public Dimension getMinSize() { if (sizesAreValid)

return minSize; minSize=myLayout.getMinSize(this); sizesAreValid=true;

} public Dimension getDesiredSize() { . . . similar to getMinSize() . . . } public Dimension getMaxSize() { . . . similar to getMinSize() . . . } public void doLayout(Rectangle newBounds) { myLayout.doLayout(newBounds,this); }

}

Page 32: Layout How multiple components are composed to build interfaces.

Summary

Introduced the importance of layout and Introduced the importance of layout and placementplacement

Discussed a series of techniques for layoutDiscussed a series of techniques for layout Outlined the broad approach of layout managers. Outlined the broad approach of layout managers.

Next : Examples of the use of Swing Layouts in Next : Examples of the use of Swing Layouts in practice practice

Read through the swing tutorials.Read through the swing tutorials.


Recommended