当用户在我的 Vaadin 6 或 7 Web 应用程序中调整窗口大小时,我希望布局的各个区域调整大小以充分利用可用空间。
GridLayout 似乎是这样做的方法。但是开始使用 GridLayout 可能会很棘手。我阅读了 GridLayout API 页面,以及 Vaadin 之书(GridLayout 页面和Layout Formatting 页面)。
一个展示 GridLayout 的例子会很有帮助。
当用户在我的 Vaadin 6 或 7 Web 应用程序中调整窗口大小时,我希望布局的各个区域调整大小以充分利用可用空间。
GridLayout 似乎是这样做的方法。但是开始使用 GridLayout 可能会很棘手。我阅读了 GridLayout API 页面,以及 Vaadin 之书(GridLayout 页面和Layout Formatting 页面)。
一个展示 GridLayout 的例子会很有帮助。
我创建了一个示例 Vaadin 7 Web 应用程序,展示了GridLayout
. 两种用法都Table
在布局的四个角中的每一个中放置一个带有虚拟数据的数据。当窗口大小调整为更大或更小时,四个表的大小也会相应改变。
一种用法是由四个单元格、两列和两行组成的简单网格。另一种用法包括在中间列和中间行中带有按钮的嵌套布局,在具有三列和三行的 GridLayout 中,总共九个单元格,其中三个为空。
每种用法的屏幕截图……</p>
这是两个重要的类,每个类都是 GridLayout 的子类。首先越简单,然后越复杂。
/**
*
*/
package com.example.quadrantgridlayout;
import com.vaadin.server.Sizeable;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.Table;
/**
* An example use of GridLayout in Vaadin 7.1.
*
* Each quadrant of the layout contains a table. Each table resizes in both width and height to fill any available space.
*
* @author Basil Bourque
*
* Copyright © 2013 Basil Bourque.
*
* This example source code may be used freely forever by anyone taking full responsibility for doing so.
*
*/
public class QuadrantGridLayout extends GridLayout {
/**
* Constructor
*/
public QuadrantGridLayout() {
super();
this.setMargin( true ); // Add space around the perimeter.
this.setSpacing( true ); // Add space between widgets.
// Make this Layout fill all available space in its container.
// In this case its container is a UI.
// In this case, that UI happens to fill its container, the web browser's tab/window.
this.setWidth( 100, Sizeable.Unit.PERCENTAGE );
this.setHeight( 100, Sizeable.Unit.PERCENTAGE );
// Create four cells for our four tables.
this.setColumns( 2 );
this.setRows( 2 );
// Create widgets.
Table upperLeft = new AstronomersTable( "Upper Left " + new java.util.Date() ); // In real work I would use Joda Time, not j.u.Date.
Table upperRight = new AstronomersTable( "Upper Right" );
Table lowerLeft = new AstronomersTable( "Lower Left" );
Table lowerRight = new AstronomersTable( "Lower Right" );
// Compose layout.
upperLeft.setWidth( 100, Sizeable.Unit.PERCENTAGE );
upperLeft.setHeight( 100, Sizeable.Unit.PERCENTAGE );
this.addComponent( upperLeft );
upperRight.setSizeFull(); // Alternate syntax for setting both width and height to 100%, instead of two lines seen earlier above.
this.addComponent( upperRight );
// Cursor automatically moved to next row upon reaching the row's last cell.
lowerLeft.setSizeFull();
// lowerLeft.setHeight( 72 * 2, Sizeable.Unit.POINTS ); // Use this if you want to play with fixed sizing. 72 points per inch.
this.addComponent( lowerLeft );
lowerRight.setSizeFull();
this.addComponent( lowerRight );
}
}
这是带有按钮的 GridLayout。
/**
*
*/
package com.example.quadrantgridlayout;
import com.vaadin.server.Sizeable;
import com.vaadin.ui.Button;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
/**
* An example use of GridLayout in Vaadin 7.1.
*
* Each quadrant of the layout contains a table. Each table resizes in both width and height to fill any available space.
*
* @author Basil Bourque
*
* Copyright © 2013 Basil Bourque.
*
* This example source code may be used freely forever by anyone taking full responsibility for doing so.
*/
public class QuadrantWithButtonsGridLayout extends GridLayout {
/**
* Constructor
*/
public QuadrantWithButtonsGridLayout() {
super();
this.setMargin( true ); // Add space around the perimeter.
this.setSpacing( true ); // Add space between widgets.
// Make this Layout fill all available space in its container.
// In this case its container is a UI.
// In this case, that UI happens to fill its container, the web browser's tab/window.
this.setWidth( 100, Sizeable.Unit.PERCENTAGE );
this.setHeight( 100, Sizeable.Unit.PERCENTAGE );
// Create 9 cells, like Tic-Tac-Toe. A table goes in each corner.
this.setColumns( 3 );
this.setRows( 3 );
// Create tables.
Table upperLeft = new AstronomersTable( "Upper Left " + new java.util.Date() ); // In real work I would use Joda Time, not j.u.Date.
Table upperRight = new AstronomersTable( "Upper Right" );
Table lowerLeft = new AstronomersTable( "Lower Left" );
Table lowerRight = new AstronomersTable( "Lower Right" );
// Create buttons, and collect into a Layout.
Button alphaButton = new Button( "Alpha" );
Button betaButton = new Button( "Beta" );
VerticalLayout upperButtonsLayout = new VerticalLayout();
upperButtonsLayout.setCaption( " " ); // Add an empty caption (Space character, actually) to force the buttons downwards to line up with tables.
upperButtonsLayout.setSpacing( true ); // Add space between widgets.
upperButtonsLayout.addComponent( alphaButton );
upperButtonsLayout.addComponent( betaButton );
Button gammaButton = new Button( "Gamma" );
Button deltaButton = new Button( "Delta" );
HorizontalLayout leftButtonsLayout = new HorizontalLayout();
leftButtonsLayout.setSpacing( true );
leftButtonsLayout.addComponent( gammaButton );
leftButtonsLayout.addComponent( deltaButton );
// Compose layout.
// ----| ROW 1 |------------------------
// Vaadin 6 & 7 seem to suffer a bug that makes one row wider than another despite being assigned the same ratio.
// As a workaround, divide the wide column's ratio by half (give or take) to compensate.
this.setRowExpandRatio( this.getCursorY(), 0.5F / 1.5F );
// Column 1
// Vaadin 6 & 7 seem to suffer a bug that makes one column wider than another despite being assigned the same ratio.
// As a workaround, divide the wide column's ratio by half (or more) to compensate.
this.setColumnExpandRatio( this.getCursorX(), 1F / 1.5F ); // Notice first argument is soft-coding the column position. Also, index (zero-based) counting .
upperLeft.setWidth( 100, Sizeable.Unit.PERCENTAGE );
upperLeft.setHeight( 100, Sizeable.Unit.PERCENTAGE );
// upperLeft.setHeight( 72 * 2, Sizeable.Unit.POINTS ); // Use this if you want to play with fixed sizing. 72 points per inch.
this.addComponent( upperLeft );
// Column 2
// should not expand or contract with window re-sizing. So set expansion ratio to zero.
upperButtonsLayout.setSizeUndefined(); // Setting size to be "undefined" is the trick to getting this column to collapse to its own minimal size.
this.addComponent( upperButtonsLayout );
// Column 3
this.setColumnExpandRatio( this.getCursorX(), 1F );
upperRight.setSizeFull(); // Alternate syntax for setting both width and height to 100%, instead of two lines seen earlier above.
this.addComponent( upperRight );
// Cursor automatically moved to next row upon reaching the row's last cell.
// ----| ROW 2 |------------------------
// Column 1
leftButtonsLayout.setSizeUndefined(); // Setting size to be "undefined" is the trick to getting this row to collapse to its own minimal size.
this.addComponent( leftButtonsLayout );
this.newLine(); // Move cursor to next row. We have nothing to place in the remaining two cells.
// ----| ROW 3 |------------------------
this.setRowExpandRatio( this.getCursorY(), 0.5F );
// // Column 1
lowerLeft.setSizeFull();
this.addComponent( lowerLeft );
// Column 2
this.space(); // Move cursor to next cell. We have nothing to place in this middle cell.
// Column 3
lowerRight.setSizeFull();
this.addComponent( lowerRight );
}
}
这是将 GridLayouts 放到屏幕上的代码。对于 Vaadin 6,将此类的内容移至适当的类。
package com.example.quadrantgridlayout;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Layout;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.UI;
/**
*
* Main UI class
*
* This example app demonstrates the use of GridLayout to build a smart resizing layout.
*
* Built in Vaadin 7.1 (pre-release), but the GridLayout & Table portions should work in Vaadin 6 as well.
*
* * @author Basil Bourque
*
* Copyright © 2013 Basil Bourque.
*
* This example source code may be used freely forever by anyone taking full responsibility for doing so.
*/
public class QuadrantGridLayoutUI extends UI {
@Override
protected void init( VaadinRequest request ) {
// This app demonstrates two versions of a GridLayou made of quadrants, each containing a table.
// The simpler version contains only the four tables.
// The other version includes a middle column and row, each containing a Layout with buttons.
final Layout layoutQuadrant = new QuadrantGridLayout();
final Layout layoutQuadrantWithButtons = new QuadrantWithButtonsGridLayout();
// Display content on screen.
// If for simplicity you want to remove the TabSheet from the situation, swap this next line for all remaining code below.
// this.setContent( layoutQuadrant ); // Copy-paste either Layout variable to try each version.
TabSheet tabs = new TabSheet();
tabs.setSizeFull(); // Make the TabSheet fill all available space. By default the height is fixed.
tabs.addTab( layoutQuadrant, "Simple" );
tabs.addTab( layoutQuadrantWithButtons, "With Buttons" );
this.setContent( tabs );
}
}
最后,这是虚拟数据的代码,它是 Table 的子类。
/**
*
*/
package com.example.quadrantgridlayout;
import com.vaadin.ui.Table;
/**
*
* Creates a simple Vaadin table with some dummy data.
*
* @author Basil Bourque
*
* Copyright © 2013 Basil Bourque, except where noted below.
*
* This source code may be used freely forever by anyone taking full responsibility for doing so.
*
*/
public class AstronomersTable extends Table {
/**
*
*/
public AstronomersTable() {
super();
this.configure();
}
/**
* @param caption
*/
public AstronomersTable( String caption ) {
super( caption );
this.configure();
}
private void configure() {
// This method's source code taken from "The Book of Vaadin 7", plus I added an earlier astronomer.
// https://vaadin.com/book/vaadin7/-/page/components.table.html
// Configure options.
this.setSelectable( true );
/*
* Define the names and data types of columns. The "default value" parameter is meaningless here.
*/
this.addContainerProperty( "First Name", String.class, null );
this.addContainerProperty( "Last Name", String.class, null );
this.addContainerProperty( "Year", Integer.class, null );
/* Add a few items in the this. */
this.addItem( new Object[] { "Hypatia", "of Alexandria", new Integer( -370 ) }, new Integer( 1 ) );
this.addItem( new Object[] { "Nicolaus", "Copernicus", new Integer( 1473 ) }, new Integer( 2 ) );
this.addItem( new Object[] { "Tycho", "Brahe", new Integer( 1546 ) }, new Integer( 3 ) );
this.addItem( new Object[] { "Giordano", "Bruno", new Integer( 1548 ) }, new Integer( 4 ) );
this.addItem( new Object[] { "Galileo", "Galilei", new Integer( 1564 ) }, new Integer( 5 ) );
this.addItem( new Object[] { "Johannes", "Kepler", new Integer( 1571 ) }, new Integer( 6 ) );
this.addItem( new Object[] { "Isaac", "Newton", new Integer( 1643 ) }, new Integer( 7 ) );
}
}