ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 01.01.2026
Просмотров: 2655
Скачиваний: 0
Managing Layout
as non-engineers, heard or at least cared about. At best, engineers could throw at them a resource editor that would allow them to resize the UI components by hand. Such was the spirit back then.
After the web was born, layout design was doomed to change for ever. At first, layout didn't matter much, as everyone was happy with plain headings, paragraphs, and a few hyperlinks here and there. Designers of HTML wanted the pages to run on any screen size. The screen size was actually not pixels but rows and columns of characters, as the baby web was really just hypertext, not graphics.That was soon to be changed.The first GUI-based browser, NCSA Mosaic, launched a revolution that culminated in Netscape Navigator. Suddenly, people who had previously been doing advertisement brochures started writing HTML. This meant that layout design had to be easy not just for programmers, but also allow the graphics designer to do his or her job without having to know a thing about programming. The W3C committee designing web standards came up with the CSS (Cascading Style Sheet) specification, which allowed trivial separation of appearance from content. Later versions of HTML followed, XHTML appeared, as did countless other standards.
Page description and markup languages are a wonderful solution for static presentations, such as books and most web pages. Real applications, however, need to have more control. They need to be able to change the state of user interface components and even their layout on the run. This creates a need to separate the presentation from content on exactly the right level.
Thanks to the attack of graphics designers, desktop applications were, when it comes to appearance, far behind web design. Sun Microsystems had come in 1995 with a new programming language, Java, for writing cross-platform desktop applications. Java's original graphical user interface toolkit, AWT (Abstract Windowing Toolkit), was designed to work on multiple operating systems as well as embedded in web browsers. One of the special aspects of AWT was the layout manager, which allowed user interface components to be flexible, growing and shrinking as needed. This made it possible for the user to resize the windows of an application flexibly and also served the needs of localization, as text strings were not limited to some fixed size in pixels. It became even possible to resize the pixel size of fonts, and the rest of the layout adapted to the new size.
Layout management of Vaadin is a direct successor of the web-based concept for separation of content and appearance and of the Java AWT solution for binding the layout and user interface components into objects in programs. Vaadin layout components allow you to position your UI components on the screen in a hierarchical fashion, much like in conventional Java UI toolkits such as AWT, Swing, or SWT. In addition, you can approach the layout from the direction of the web with the CustomLayout component, which you can use to write your layout as a template in XHTML that provides locations of any contained components.
The moral of the story is that, because Vaadin is intended for web applications, appearance is of high importance. The solutions have to be the best of both worlds and satisfy artists of both kind: code and graphics. On the API side, the layout is controlled by UI components, particularly the layout components. On the visual side, it is controlled by themes. Themes can contain any HTML, CSS, and JavaScript that you or your web artists create to make people feel good about your software.
Because of pressing release schedules to get this edition to your hands, we were unable to completely update this chapter. The content is up-to-date with Vaadin 7 to a large extent, but some topics require revision. Please consult the web version once it is updated, or the next print edition.
172
Managing Layout
6.1. Overview
The user interface components in Vaadin can roughly be divided in two groups: components that the user can interact with and layout components for placing the other components to specific places in the user interface. The layout components are identical in their purpose to layout managers in regular desktop frameworks for Java and you can use plain Java to accomplish sophisticated component layouting.
You start by creating a content layout for the UI, unless you use the default, and then add the other layout components hierarchically, and finally the interaction components as the leaves of the component tree.
//Set the root layout for the UI VerticalLayout content = new VerticalLayout(); setContent(content);
//Add the topmost component.
content.addComponent(new Label("The Ultimate Cat Finder"));
// Add a horizontal layout for the bottom part. HorizontalLayout bottom = new HorizontalLayout(); content.addComponent(bottom);
bottom.addComponent(new Tree("Major Planets and Their Moons")); bottom.addComponent(new Panel());
...
You will usually need to tune the layout components a bit by setting sizes, expansion ratios, alignments, spacings, and so on. The general settings are described in Section 6.13, “Layout Formatting”, while the layout component specific settings are described in connection with the component.
Layouts are coupled with themes that specify various layout features, such as backgrounds, borders, text alignment, and so on. Definition and use of themes is described in Chapter 8,
Themes
You can see the finished version of the above example in Figure 6.1, “Layout Example”.
Overview |
173 |
Managing Layout
Figure 6.1. Layout Example
The alternative for using layout components is to use the special CustomLayout that allows using HTML templates. This way, you can let the web page designers take responsibility of component layouting using their own set of tools.What you lose is the ability to manage the layout dynamically.
The Visual Editor
While you can always program the layout by hand, the Vaadin plugin for the Eclipse IDE includes a visual (WYSIWYG) editor that you can use to create user interfaces visually. The editor generates the code that creates the user interface and is useful for rapid application development and prototyping. It is especially helpful when you are still learning the framework, as the generated code, which is designed to be as reusable as possible, also works as an example of how you create user interfaces with Vaadin. You can find more about the editor in Chapter 7, Visual User Interface Design with Eclipse.
6.2. Window and Panel Content
The Window and its superclass Panel have a single content component. The content is usually a layout component, but any component is allowed.
// Set the root content for the UI TabSheet tabsheet = new TabSheet(); setContent(tabsheet);
The size of the root layout is the default size of the particular layout component, for example, a VerticalLayout has 100% width and undefined height by default. In many applications, you want to use the full area of the browser view. Setting the components contained inside the root layout to full size is not enough, and would actually lead to an invalid state if the height of the root layout is undefined.
//This is actually the default. main.setContent(new VerticalLayout());
//Set the size of the root layout to full width and height.
174 |
Window and Panel Content |
Managing Layout
main.getContent().setSizeFull();
//Add a title area on top of the screen. This takes just the
//vertical space it needs.
main.addComponent(new Label("My Application"));
// Add a menu-view area that takes rest of the vertical space. HorizontalLayout menuview = new HorizontalLayout(); menuview.setSizeFull();
main.addComponent(menuview);
See Section 6.13.1, “Layout Size” for more information about setting layout sizes.
6.3. VerticalLayout and HorizontalLayout
VerticalLayout and HorizontalLayout are containers for laying components out either vertically or horizontally, respectively. These are the two most important layout components in Vaadin and some components, such as Window and Panel, have a VerticalLayout as the root layout, which you can set with setContent().
Typical use of the layouts goes as follows:
VerticalLayout vertical = new VerticalLayout (); vertical.addComponent(new TextField("Name")); vertical.addComponent(new TextField("Street address")); vertical.addComponent(new TextField("Postal code")); main.addComponent(vertical);
In these layouts, component captions are placed above the component. The layout will look on screen as follows:
Using HorizontalLayout gives the following layout:
The layouts can have spacing between the horizontal or vertical cells, defined with setSpacing(), as described in Section 6.13.3, “Layout Cell Spacing”.The contained components can be aligned within their cells with setComponentAlignment(), as described in Section 6.13.2, “Layout Cell Alignment”.
6.3.1. Sizing Contained Components
The components contained within an ordered layout can be laid out in a number of different ways depending on how you specify their height or width in the primary direction of the layout component.
VerticalLayout and HorizontalLayout |
175 |
Managing Layout
Figure 6.2. Component Widths in HorizontalLayout
Figure 6.2, “Component Widths in HorizontalLayout” above gives a summary of the sizing options for a HorizontalLayout. The figure is broken down in the following subsections.
Layout with Undefined Size
If a VerticalLayout has undefined height or HorizontalLayout undefined width, the layout will shrink to fit the contained components so that there is no extra space between them.
HorizontalLayout fittingLayout = new HorizontalLayout(); fittingLayout.setWidth(Sizeable.SIZE_UNDEFINED, 0); // Default fittingLayout.addComponent(new Button("Small")); fittingLayout.addComponent(new Button("Medium-sized")); fittingLayout.addComponent(new Button("Quite a big component")); parentLayout.addComponent(fittingLayout);
The both layouts actually have undefined height by default and HorizontalLayout has also undefined width, while VerticalLayout has 100% relative width.
If such a vertical layout with undefined height continues below the bottom of a window (a Window object), the window will pop up a vertical scroll bar on the right side of the window area. This way, you get a "web page". The same applies to Panel.
A layout that contains components with percentual size must have a defined size!
If a layout has undefined size and a contained component has, say, 100% size, the component would fill the space given by the layout, while the layout would shrink to fit the space taken by the component, which would be a paradox. This requirement holds for height and width separately. The debug mode allows detecting such invalid cases; see Section 11.3.1, “Debug Mode”.
An exception to the above rule is a case where you have a layout with undefined size that contains a component with a fixed or undefined size together with one or more components with relative size. In this case, the contained component with fixed (or undefined) size in a sense defines the size of the containing layout, removing the paradox. That size is then used for the relatively sized components.
The technique can be used to define the width of a VerticalLayout or the height of a HorizontalLayout.
176 |
Sizing Contained Components |
Managing Layout
//Vertical layout would normally have 100% width VerticalLayout vertical = new VerticalLayout();
//Shrink to fit the width of contained components vertical.setWidth(Sizeable.SIZE_UNDEFINED, 0);
//Label has normally 100% width, but we set it as
//undefined so that it will take only the needed space Label label =
new Label("\u2190 The VerticalLayout shrinks to fit "+ "the width of this Label \u2192");
label.setWidth(Sizeable.SIZE_UNDEFINED, 0); vertical.addComponent(label);
// Button has undefined width by default
Button butt = new Button("\u2190 This Button takes 100% "+ "of the width \u2192");
butt.setWidth("100%");
vertical.addComponent(butt);
Figure 6.3. Defining the Size with a Component
Layout with Defined Size
If you set a HorizontalLayout to a defined size horizontally or a VerticalLayout vertically, and there is space left over from the contained components, the extra space is distributed equally between the component cells. The components are aligned within these cells according to their alignment setting, top left by default, as in the example below.
fixedLayout.setWidth("400px");
Using percentual sizes for components contained in a layout requires answering the question, "Percentage of what?" There is no sensible default answer for this question in the current implementation of the layouts, so in practice, you may not define "100%" size alone.
Expanding Components
Often, you want to have one component that takes all the available space left over from other components.You need to set its size as 100% and set it as expanding with setExpandRatio(). The second parameter for the method is an expansion ratio, which is relevant if there are more than one expanding component, but its value is irrelevant for a single expanding component.
HorizontalLayout layout = new HorizontalLayout(); layout.setWidth("400px");
//These buttons take the minimum size. layout.addComponent(new Button("Small")); layout.addComponent(new Button("Medium-sized"));
//This button will expand.
Button expandButton = new Button("Expanding component");
Sizing Contained Components |
177 |
Managing Layout
//Use 100% of the expansion cell's width. expandButton.setWidth("100%");
//The component must be added to layout before setting the ratio. layout.addComponent(expandButton);
//Set the component's cell to expand. layout.setExpandRatio(expandButton, 1.0f);
parentLayout.addComponent(layout);
Notice that you must call setExpandRatio() after addComponent(), because the layout can not operate on an component that it doesn't (yet) include.
Expand Ratios
If you specify an expand ratio for multiple components, they will all try to use the available space according to the ratio.
HorizontalLayout layout = new HorizontalLayout(); layout.setWidth("400px");
// Create three equally expanding components. String[] captions = { "Small", "Medium-sized",
"Quite a big component" }; for (int i = 1; i <= 3; i++) {
Button button = new Button(captions[i-1]); button.setWidth("100%"); layout.addComponent(button);
// Have uniform 1:1:1 expand ratio. layout.setExpandRatio(button, 1.0f);
}
As the example used the same ratio for all components, the ones with more content may have the content cut. Below, we use differing ratios:
// Expand ratios for the components are 1:2:3. layout.setExpandRatio(button, i * 1.0f);
If the size of the expanding components is defined as a percentage (typically "100%"), the ratio is calculated from the overall space available for the relatively sized components. For example, if you have a 100 pixels wide layout with two cells with 1.0 and 4.0 respective expansion ratios, and both the components in the layout are set as setWidth("100%"), the cells will have respective widths of 20 and 80 pixels, regardless of the minimum size of the components.
However, if the size of the contained components is undefined or fixed, the expansion ratio is of the excess available space. In this case, it is the excess space that expands, not the components.
for (int i = 1; i <= 3; i++) {
// Button with undefined size.
Button button = new Button(captions[i - 1]);
178 |
Sizing Contained Components |