layouts in java

Upload: muttuswami

Post on 02-Jun-2018

212 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/11/2019 Layouts in Java

    1/13

    Layouts in java

    FlowLayout

    java.awt.FlowLayoutarranges components from left-to-right and top-to-bottom, centering

    components horizontally with a five pixel gap between them. When a container size is changed

    (eg, when a window is resized), FlowLayout recomputes new positions for all componentssubject to these constraints.

    Use FlowLayout because it's quick and easy. It's a good first choice when using iterativedevelopment. I often start with a FlowLayout in an early iteration then switch to a better layout,

    if necessary, on a later iteration.

    Example

    The window above is the default size after packing the FlowLayout.The window on the right shows the same window after it has been

    resized by dragging the lower-right corner, resulting in components

    flowing down onto other lines.

    Source code for example

    Here is the relevant part of the source code for the above example.

    // Note: a real program would add listeners to the buttons.JPanel content = new JPanel();content.setLayout(new FlowLayout());content.add(new JButton("Button 1"));content.add(new JButton("2"));content.add(new JButton("This is button three"));content.add(new JButton("four"));

    Constructors

    Typically the constructor is called in the call to the container's setLayoutmethod (see example

    code). The parameterless FlowLayout()constructor is probably most common, but there are

    some good places to use the alignment.

    new FlowLayout() // default is centered with 5 pixel gapsnew FlowLayout(int align)

  • 8/11/2019 Layouts in Java

    2/13

    new FlowLayout(int align, int hgap, int vgap)

    Alignment

    alignis one of FlowLayout.LEFT, FlowLayout.CENTER(the default), or FlowLayout.RIGHT.

    You might want to use the RIGHT aligment when building a dialog that puts the OK and Cancelbuttons at the lower right.

    Spacing

    The default spacing is good for most purposes and is rarely changed. hgapis the size in pixels of

    the horizontal gap (distance) between components, and vgapis the vertical gap.

    Typical uses

    Quick implementation. This is the most common use of FlowLayout. You can get

    something working quickly, and change it, if necessary, in a later iteration.

    Space around component in a BorderLayout.As a subpanel to keep components from

    expanding. For example, you might want to add a button to the SOUTH part of a

    BorderLayout, but don't want it to expand to the edges of the SOUTH region. Just put the

    button in a FlowLayout JPanel and add that to the SOUTH.

    Multiple components in a BorderLayout region.When you want to add several

    components to a BorderLayout region, drop them into a FlowLayout panel and put that in

    the BorderLayout.

    Problem

    FlowLayoutmakes components as small as possible, and does not use their preferred size. This

    can show up when you define a JPanel for drawing. Typically you will set a preferred size, but

    the panel may "disappear" in a FlowLayout because it was set to its minimum size (0).

    BorderLayout

    java.awt.BorderLayoutdivides a container (eg, JPanel) into 5 geographical sections: North,

    South, East, West, and Center. This is a very commonly used layout.

    Expand to fill region. Components start at their preferred size, but are expanded as needed tofill the region they are in.

    Use subpanel for more than one component in a region. You can add at most one component

    to each region of a BorderLayout. To put more than one component in a section, put them in a

    JPanel (with its own layout), then add that panel to the border layout.

  • 8/11/2019 Layouts in Java

    3/13

    Where extra space goes. The size of a region is adjusted depending on what is in it. If there is

    nothing in an region, its size will be reduced to zero. Components in the North and South cells

    are stretched horizontally, and those in East and West are stretched vertically to fill all the space.The center is stretched vertically and horizontally as needed, so it is a good place to put graphics

    or text areas that you want to expand.

    Specifying the region. When you add components to a container which uses BorderLayout,

    specify the target region as the second parameter as, for example, BorderLayout.NORTH.

    Resizing

    The window on the left

    was created by the

    sample code below. This

    same window was made

    larger by dragging on thelower right corner. Note

    which components had

    horizontal space added to

    them and which had

    vertical space added to

    them.

    To prevent component resizing, add a component to a JPanel with FlowLayout, and then add that

    panel to the BorderLayout. This is a common way to prevent resizing. The FlowLayout panelwill stretch, but the component in it will not.

    Not all regions are required

    If nothing has been added to a region, the neighboring

    regions expand to fill that space.

    This window was created with 5 pixel gaps using only theNORTH, WEST, and CENTER regions. It was then resized,

    which added both vertical and horizontal space to the

    regions.

    Constructors

  • 8/11/2019 Layouts in Java

    4/13

    If you don't need any space between regions, use the default constructor. You can also specify

    the number of pixels between regions.

    p.setLayout(new BorderLayout()); // Default is no gapsp.setLayout(new BorderLayout(hgap, vgap);

    Where hgapand vgapare the distances in pixels between the regions.

    Example of Borderlayout with all regions filled

    // File : layouts/borderLayout/BorderTest.java// Purpose: Demo use of BorderLayout.// Author : Fred Swartz - 2006-09-24 - Placed in public domain.

    import java.awt.*;import javax.swing.*;

    ///////////////////////////////////////////////// class BorderTestclass BorderTest extends JFrame {

    //======================================================= mainpublic static void main(String[] args) {

    JFrame window = new BorderTest();window.setVisible(true);

    }

    //================================================ constructorBorderTest() {

    //... Create components (but without listeners)JButton north = new JButton("North");JButton east = new JButton("East");

    JButton south = new JButton("South");JButton west = new JButton("West");JButton center = new JButton("Center");

    //... Create content pane, set layout, add componentsJPanel content = new JPanel();content.setLayout(new BorderLayout());

    content.add(north , BorderLayout.NORTH);content.add(east , BorderLayout.EAST);content.add(south , BorderLayout.SOUTH);content.add(west , BorderLayout.WEST);content.add(center, BorderLayout.CENTER);

    //... Set window characteristics.setContentPane(content);setTitle("BorderTest");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);pack();

    }}

  • 8/11/2019 Layouts in Java

    5/13

    BoxLayout and Boxes

    BoxLayout arranges components either horizontally or verticallyin a

    panel. You can control alignment and spacing of the components.Complicated layouts can be made by combining many panels, some with

    horizontal layout and some with vertical layouts.

    Several classes are typically used:

    javax.swing.BoxLayout, javax.swing.Box, and javax.swing.Box.Filler.

    To Create a JPanel with BoxLayout

    Choose either a horizontal layout (BoxLayout.X_AXIS) or vertical layout (BoxLayout.Y_AXIS)for a JPanel.

    JPanel p= new JPanel();p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));p.add(some_component);

    Unlike other layouts, the panel/container must be passed to the BoxLayout constructor.

    Example

    The above examples were created with this code, using either X_AXIS or Y_AXIS.

    content.setLayout(new BoxLayout(content, BoxLayout.X_AXIS));content.add(new JButton("Button 1"));content.add(new JButton("2"));content.add(new JButton("This is button three"));

    The Box class

    The Boxclass was designed to be a simple, and slightly more efficient, substitute for a JPanel

    with a BoxLayout. Because it doesn't support everything that JPaneldoes (eg, borders), I

    recommend using a JPanelwith a BoxLayoutrather than Box. However, the Boxclass has a

    number of necessary methods for working with BoxLayouts.

  • 8/11/2019 Layouts in Java

    6/13

    Because Boxis a Containerwith BoxLayout, all discussions of spacing and alignment applyequally well to both JPanels with BoxLayouts and Boxes.

    Creating Boxes

    You can create the two kinds of boxes with:

    import javax.swing.*;. . .Box vb= Box.createVerticalBox();Box hb= Box.createHorizontalBox();

    No Borders on Boxes

    Boxes are lighter weight (ie, more efficient) than JPanel, but they don't support Borders. If you

    need borders, either use a JPanel with BoxLayout, or put the Box into a JPanel with a border.

    java.awt.GridBagLayout

    Description

    GridBagLayoutlays out components based on a grid with rows and columns that need not all bethe same size. If you're familiar with HTML tables, you'll feel comfortable with the idea.

    Unfortunately, GridBagLayout is infernally awkward and error-prone to use. After reading some

    of this you might want to see example code atExample: GridBagLayout.

    Abandon hope, all ye who use GridBagLayout

    Altho GridBagLayoutcan produce acceptable results, it's not a happy story.

    It is very difficult to work with because eleven constraint valuesare used for each

    component! These constraint values are bundled in a java.awt.GridBagConstraints object. Fortunately, most of them have reasonable defaults.

    The layout doesn't have features which specifically help to use Sun's (or anyone else's)

    Human Interface Guidelines, for example in handling gaps.

    Spacing is specified in pixels, which provides no flexibility for screen resolution and font

    changes. I like this quote from Otaku, Cedric's blog: "GridBagLayout is an absolute disaster and

    the perfect example of something that is completely flawed and violates with a stunningregularity the principle of least surprise."

    Everyone who has touched GridBagLayout will enjoy Totally Gridbag, little bit of Flash

    foolishness -madbean.com/blog/2004/17/totallygridbag.html

    Some prefer to call it "GridBugLayout".

    http://www.leepoint.net/notes-java/GUI/layouts/gridbag-example.htmlhttp://www.leepoint.net/notes-java/GUI/layouts/gridbag-example.htmlhttp://www.leepoint.net/notes-java/GUI/layouts/gridbag-example.htmlhttp://madbean.com/blog/2004/17/totallygridbag.htmlhttp://madbean.com/blog/2004/17/totallygridbag.htmlhttp://madbean.com/blog/2004/17/totallygridbag.htmlhttp://madbean.com/blog/2004/17/totallygridbag.htmlhttp://www.leepoint.net/notes-java/GUI/layouts/gridbag-example.html
  • 8/11/2019 Layouts in Java

    7/13

  • 8/11/2019 Layouts in Java

    8/13

    Constraint parameters are instance fields in a GridBagConstraints object. The add()methodclones (copies) the constraint object, so typically the same GridBagConstraints object is reusedto pass constraints for the next component. It is common to use only one GridBagConstraints

    object to add all components, changing fields as necessary between adds, but this practice also

    leads to many errors and code which is difficult to change.

    GridBagConstraints fields

    The fields can divided into three groups:

    Necessary - row and column coordinates, width and height in terms of rows and columns

    Describe the location and size (in rows and columns) of the component using gridx,

    gridy, gridwidth, and gridheight.Common - expandability and alignment

    If a column or row can use extra space when a window is expanded, set weightxand

    weightyto 1.0; you will rarely want to use other values.

    Use filldepending on what the type of component is. For example, a JTextField canusually grow horizontally, so you would use

    gbc.fill = GridBagConstraints.HORIZONTAL;

    to allow it to stretch.

    Use anchorto tell which edges of the display area a component should be attached to.

    Less common - surrounding spacing

    You can also control the space around a component with ipadxand ipady.

    To control the amount of unused space around a component, use insets.

    GridBagConstraints attribute summary

    gridxgridy

    The int column (gridx) and row (gridy) of the component. If requires more than

    one cell (gridwidthor gridheight> 1), this is the coordinate of the top-left cell.

    The row and columns start at zero. The value GridBagConstraints.RELATIVE places the component in the next position.

    gridwidth

    gridheight

    Number of columns or rows the component occupies.

    GridBagConstraints.REMAINDERindicates that this component should fill out allrows or columns to the end. Default 1. Note these names violates naming standards

    (second word not capitalized).

    weightxweighty

    These double variables (default value 0) are used in calculating where space is

    allocated in rows and columns when a window is resized. extra space should be

    allocated in a column horizontally (weightx) and row vertically (weighty).

  • 8/11/2019 Layouts in Java

    9/13

    A column width is originally calculated as the maximum width of the preferredsizes of the components in that column. If a component is narrower than the column

    width, the value of the fillattribute is used in deciding how to use that extra space

    (see below).

    Extra horizontal space is allocated to a column in proportion to the maximum

    weightxvalue for that column. If weightxis zero, no extra space is allocated.Because these weights are relative, you can assign any arbitrary positive double

    value to produce the desired layout, altho it is common to work in the range 0-1.

    The analogous procedure is performed for the row heights using weighty.

    fill Fillspecifies how the component should expand within its display area if the area

    width/height is larger than its preferred size.GridBagConstraints.NONE // Can't expand (Default)GridBagConstraints.VERTICAL // Expand verticallyGridBagConstraints.HORIZONTAL // Expand horizontallyGridBagConstraints.BOTH // Expand vertically and

    horizontally

    For example, a text field typically expands horizontally

    (GridBagConstraints.HORIZONTAL), a text area expands vertically and

    horizontally (GridBagConstraints.BOTH), and a button might not expand at all

    (GridBagConstraints.NONE). If a component isn't expanded to fill the space, the

    anchorattribute (see below) is used to specify where it goes within that cell.

    Default value GridBagConstraints.NONE .

    anchor If the component doesn't occupy its entire display area, anchorspecifies where itshould be placed. The location is usually given as a compass direction. (A relative

    system which works for both right-to-left and left-to-right languages is also

    available).GridBagConstraints.CENTER (the default),GridBagConstraints.NORTH GridBagConstraints.SOUTHGridBagConstraints.NORTHEAST GridBagConstraints.SOUTHWESTGridBagConstraints.EAST GridBagConstraints.WESTGridBagConstraints.SOUTHEAST GridBagConstraints.NORTHWEST

    insets A java.awt.Insetsobject adds padding space to the component. Insets should berarely used because they often produce bad results, with the exception of JPanels

    and JLabels. The constructor parameters (in pixels) specify the top, left, bottom,

    right. For example,gbc.insets = new Insets(10, 5, 10, 4);

    Default value: Insets(0,0,0,0).ipadxipady

    These int fields specify an increase or decrease in the horizontal and/or vertical

    preferred size of the component. Default value 0. Negative values can be used to

    tighten the spacing. These values are rarely useful, altho they can be used for fine-tuning spacing.

    Java Idiom

  • 8/11/2019 Layouts in Java

    10/13

    It's common to write a utility method which sets the fields of a GridBagConstraints object. For

    example,

    GridBagConstraints gbc = new GridBagConstraints();. . .private void set_gbc(int row, int column, int width, int height, int fill) {

    gbc.gridy = row;gbc.gridx = column;gbc.gridwidth = width;gbc.gridheight = height;gbc.fill = fill; // GridBagConstraints.NONE .HORIZONTAL .VERTICAL .BOTH// leave other fields (eg, anchor) unchanged.

    }. . .

    set_gbc(3, 2, 2, 1, GridBagConstraints.HORIZONTAL);gbc.insets = new Insets(3,3,3,3); // put spacing around this field.p.add(myTextField, gbc);

    Adding a componentTo add myField to the third row (2) and first column (0), where the button will be one grid cellwide and one high, and it will be able to expand horizontally, do this:

    set_gbc(2, 0, 1, 1, GridBagConstraints.HORIZONTAL);gridbag.setConstraints(myField, gbc);panel.add(myField);

    GridLayout

    GridLayout lays out

    components in a rectangular

    grid, where all cells are equal

    size.

    GridLayout forces components

    to have the same size.

    JPanel content = new JPanel(new GridLayout(2,2));content.add(new JButton("Button 1"));content.add(new JButton("2"));content.add(new JLabel("")); // for empty cellcontent.add(new JButton("This is button three"));

    To Create a GridLayout

  • 8/11/2019 Layouts in Java

    11/13

    There are three constructors:

    p.setLayout(new GridLayout()); // One row. Columns expand.p.setLayout(new GridLayout(rows, cols));p.setLayout(new GridLayout(rows, cols, hgap, vgap));

    with the following int parameters: rowsis number of rows, colsis number of columns, hgapis horizontal

    space between components (in pixels), and vgapis vertical space between components (in pixels).

    For example, this creates a panel with a grid layout of 4 rows and 3 columns. There are 5 pixels of

    horizontal space between components and 10 pixels of space between vertical components.

    JPanel p = new JPanel();p.setLayout(new GridLayout(4, 3, 5, 10));p.add(. . .);

    To add Components to a GridLayout

    Use the .add(. . .)method to add components to a container with a GridLayout. You do not (can

    not) use the row and column to tell where to add the components -- add them in starting at the top left

    and going across the row first.

    Empty Cells

    There is no way to leave a cell empty in a grid layout. Although it often works ok to leave the final cells

    empty, there are reports of problems, so you should fill out the last cells in the final row too. The easiest

    way to do this is to put an empty label in any cell you want to skip. Eg,

    p.add(new JLabel(""));

    Null Layout is Evil

    You can set the layout manager to null(cont.setLayout(null);), but this is generally badpractice.

    Example - Compare constructors for the Km to Milesexample

  • 8/11/2019 Layouts in Java

    12/13

    You can see the complete FlowLayout version of this program atExample - Kilometers to Miles- Complete.Below is a comparison of the layout section of the FlowLayout constructor with the

    equivalent null layout constructor.

    FlowLayout Null Layout

    //... Content panel, layout, addcomponentsJPanel content = new JPanel();content.setLayout(new FlowLayout());content.add(newJLabel("Kilometers"));content.add(m_kilometersTf);content.add(m_convertBtn);content.add(new JLabel("Miles"));content.add(m_milesTf);this.setContentPane(content);this.pack();

    //... Create labels.JLabel kmLabel = newJLabel("Kilometers");//Note 1JLabel miLabel = new JLabel("Miles");

    //... Set the positions of components.kmLabel.setBounds(5, 10, 62, 16);//Note 2m_kilometersTf.setBounds(72, 8, 114,20);m_convertBtn.setBounds(191, 5, 78, 26);miLabel.setBounds(274, 10, 30, 16);m_milesTf.setBounds(309, 8, 114, 20);

    //... Content panel, layout, addcomponentsJPanel content = new JPanel();content.setLayout(null);//Note 3content.add(kmLabel);content.add(m_kilometersTf);content.add(m_convertBtn);content.add(miLabel);content.add(m_milesTf);this.setContentPane(content);this.setSize(436, 63);

    //Note 4

    Notes

    Note 1: Labels must be in variables to set their

    bounds.

    Note 2: How will you compute these coordinates?

    Note 3: Set the layout manager to null.

    Note 4: Explicitly set the size of the window.

    Problems with null layout that regular layouts don't have

    Difficult to change, therefore hard (expensive) to maintain

    http://www.leepoint.net/notes-java/GUI/layouts/30KmToMi.htmlhttp://www.leepoint.net/notes-java/GUI/layouts/30KmToMi.htmlhttp://www.leepoint.net/notes-java/GUI/layouts/30KmToMi.htmlhttp://www.leepoint.net/notes-java/GUI/layouts/30KmToMi.htmlhttp://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note1http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note1http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note2http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note2http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note3http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note3http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note4http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note4http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note4http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note3http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note2http://www.leepoint.net/notes-java/GUI/layouts/nulllayout.html#note1http://www.leepoint.net/notes-java/GUI/layouts/30KmToMi.htmlhttp://www.leepoint.net/notes-java/GUI/layouts/30KmToMi.html
  • 8/11/2019 Layouts in Java

    13/13

    Moving, adding, removing, etc require a lot of recalculation. Relatively little work is required

    with regular layouts.

    Hard to get right in the first place

    Exactly how do you get these coordinates?

    System dependent

    The components have different sizes in different systems. I once wrote a Java program that I

    proudly showed to an important colleague, who unfortunately was using a different system. The

    layout looked really, really bad - gaps, overlaps. What happened? Null layout! It was one of my

    early programs and the last null layout I ever wrote.

    Java version dependent

    A little know fact is that between Java versions the rendering of components something changes

    slightly. It's not big, but if you have things carefully aligned in null layouts, they may not be in

    the next version of Java.

    User setting dependent

    Another little used feature is that the user can actually change Java's default settings for fonts

    etc. I once decided I wanted larger fonts on the high resolution screen I had. Of course, this

    completely breaks any null layouts altho regular layouts will adjust properly.

    Not resizeable

    It's not uncommon to have text fields/areas that the use might want to make larger by draggingthe lower right corner of the window. Impossible with null layouts, automatic with regular

    layouts.