Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 

Swing Chapter 4. (The basics) Layout Managers. Easy for reading, Click here!

Custom Search
Swing Chapter 4. (The basics) Layout Managers. Easy for reading, Click here!

[ Return to Swing (Book) ]

Page: 4/7 



Previous Page Previous Page (3/7) - Next Page (5/7) Next Page
Subpages: 1. Layouts overview 
2. Comparing common layout managers
3.
Using GridBagLayout
4. Choosing the right layout
5. Custom layout manager: part I -Label/field pairs
6. Custom layout manager: part II - Common interfaces
7. Dynamic layout in a JavaBeans container

4.4    Choosing the right layout

In this section we'll show how to choose the right combination of layouts and intermediate containers to satisfy a pre-defined program specification. Consider a sample application which makes airplane ticket reservations. The following specification describes which components should be included and how they should be placed in the application frame:

1. A text field labeled "Date:", a combo box labeled "From:", and a combo box labeled "To:" must reside at the top of frame. Labels must be placed to the left side of their corresponding component. The text field and combo boxes must be of equal size, reside in a column, and occupy all available width.

2. A group of radio buttons titled "Options" must reside in the top right corner of the frame. This group must include "First class", "Business", and "Coach" radio buttons.

3. A list component titled "Available Flights" must occupy the central part of the frame and it should grow or shrink when the size of the frame changes.

4. Three buttons titled "Search", "Purchase", and "Exit" must reside at the bottom of the frame. They must form a row, have equal sizes, and be center-aligned.

Our FlightReservation example demonstrates how to fulfill these requirements. We do not process any input from these controls and do not attempt to put them to work; we just display them on the screen in the correct position and size . (Three variants are shown to accomplish the layout of the text fields, combo boxes, and their associated labels. Two are commented out, and a discussion of each is given below.)

Note: A similar control placement assignment is part of Sun's Java Developer certification exam.

Figure 4.13 FlightReservation layout - Variant 1

<<file figure4-13.gif>>

Figure 4.14 FlightReservation layout - Variant 2

<<file figure4-14.gif>>

Figure 4.15 FlightReservation layout - Variant 3

<<file figure4-15.gif>>

The Code: FlightReservation.java

see \Chapter4\3

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.border.*;

import javax.swing.event.*;

public class FlightReservation extends JFrame

{

  public FlightReservation() {

    super("Flight Reservation Dialog");

    setSize(400, 300);

    JPanel p1 = new JPanel();

    p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));

    JPanel p1r = new JPanel();

    p1r.setBorder(new EmptyBorder(10, 10, 10, 10));

    // Variant 1

    p1r.setLayout(new GridLayout(3, 2, 5, 5));

    p1r.add(new JLabel("Date:"));

    p1r.add(new JTextField());

    p1r.add(new JLabel("From:"));

    JComboBox cb1 = new JComboBox();

    cb1.addItem("New York");

    p1r.add(cb1);

    p1r.add(new JLabel("To:"));

    JComboBox cb2 = new JComboBox();

    cb2.addItem("London");

    p1r.add(cb2);

    p1.add(p1r);

    ///////////////

    // Variant 2 //

    ///////////////

    // JPanel p11 = new JPanel();

    // p11.setLayout(new BoxLayout(p11, BoxLayout.Y_AXIS));

    //

    // JPanel p12 = new JPanel();

    // p12.setLayout(new BoxLayout(p12, BoxLayout.Y_AXIS));

    //

    // p11.add(new JLabel("Date:"));

    // p12.add(new JTextField());

    //

    // p11.add(new JLabel("From:"));

    // JComboBox cb1 = new JComboBox();

    // cb1.addItem("New York");

    // p12.add(cb1);

    //

    // p11.add(new JLabel("To:"));

    // JComboBox cb2 = new JComboBox();

    // cb2.addItem("London");

    // p12.add(cb2);

    //

    // p1.add(p11);

    // p1.add(Box.createHorizontalStrut(10));

    // p1.add(p12);

    ///////////////

    // Variant 3 //

    ///////////////

    // JPanel p11 = new JPanel();

    // p11.setLayout(new GridLayout(3, 1, 5, 5));

    //

    // JPanel p12 = new JPanel();

    // p12.setLayout(new GridLayout(3, 1, 5, 5));

    //

    // p11.add(new JLabel("Date:"));

    // p12.add(new JTextField());

    //

    // p11.add(new JLabel("From:"));

    // JComboBox cb1 = new JComboBox();

    // cb1.addItem("New York");

    // p12.add(cb1);

    //

    // p11.add(new JLabel("To:"));

    // JComboBox cb2 = new JComboBox();

    // cb2.addItem("London");

    // p12.add(cb2);

    //

    // p1r.setLayout(new BorderLayout());

    // p1r.add(p11, BorderLayout.WEST);

    // p1r.add(p12, BorderLayout.CENTER);

    // p1.add(p1r);

    JPanel p3 = new JPanel();

    p3.setLayout(new BoxLayout(p3, BoxLayout.Y_AXIS));

    p3.setBorder(new TitledBorder(new EtchedBorder(),

      "Options"));

    ButtonGroup group = new ButtonGroup();

    JRadioButton r1 = new JRadioButton("First class");

    group.add(r1);

    p3.add(r1);

    JRadioButton r2 = new JRadioButton("Business");

    group.add(r2);

    p3.add(r2);

    JRadioButton r3 = new JRadioButton("Coach");

    group.add(r3);

    p3.add(r3);

    p1.add(p3);

    getContentPane().add(p1, BorderLayout.NORTH);

    JPanel p2 = new JPanel(new BorderLayout());

    p2.setBorder(new TitledBorder(new EtchedBorder(),

      "Available Flights"));

    JList list = new JList();

    JScrollPane ps = new JScrollPane(list);

    p2.add(ps, BorderLayout.CENTER);

    getContentPane().add(p2, BorderLayout.CENTER);

    JPanel p4 = new JPanel();

    JPanel p4c = new JPanel();

    p4c.setLayout(new GridLayout(1, 3, 5, 5));

    JButton b1 = new JButton("Search");

    p4c.add(b1);

    JButton b2 = new JButton("Purchase");

    p4c.add(b2);

    JButton b3 = new JButton("Exit");

    p4c.add(b3);

    p4.add(p4c);

    getContentPane().add(p4, BorderLayout.SOUTH);

    WindowListener wndCloser = new WindowAdapter() {

      public void windowClosing(WindowEvent e) {

        System.exit(0);

      }

    };

    addWindowListener(wndCloser);

    setVisible(true);

  }

  public static void main(String argv[]) {

    new FlightReservation();

  }

}

Understanding the Code

Class FlightReservation

The constructor of the FlightReservation class creates and positions all necessary GUI components. We will explain step by step how we've chosen intermediate containers and their layouts to fulfill the requirements listed at the beginning of this section.

The frame (more specifically it's contentPane) is managed by a BorderLayout by default. A text field, and the combo boxes and associated labels are added in a separate container to the north along with the radio buttons; push buttons in the south; and the list component is placed in the center. This guarantees that top and bottom (north and south) containers will receive their natural height, and that the central component (the list) will occupy all remaining space.

The intermediate container, JPanel p1r, holds the text field, combo boxes, and their associated labels and is placed in panel p1 which is managed by a horizontally aligned BoxLayout. The p1r panel is surrounded by an EmptyBorder to provide typical surrounding white space.

This example offers three variants of managing p1r and its six child components. The first variant uses a 3x2 GridLayout. This places labels and boxes in two columns opposite one another. Since this panel resides in the north region of the BorderLayout, it receives its natural (preferable) height. In the horizontal direction this layout works satisfactory: it resizes boxes and labels to occupy all available space. The only remaining problem is that GridLayout assigns too much space to the labels (see figure 4.13). We do not need to make labels equal in size to their corresponding input boxes. We need only allow them to occupy their preferred width.

The second variant uses two vertical BoxLayouts so one can hold labels and the other can hold the corresponding text field and combo boxes. If you try recompiling and running the code with this variant you'll find that the labels now occupy only their necessary width, and the boxes occupy all remaining space (see figure 4.14). This is good, but another problem arises: now the labels are aligned exactly opposite with their corresponding components. Instead, they are shifted in the vertical direction!

The third variant offers the best solution. It places the labels and their corresponding components in two columns, but uses 3x1 GridLayouts instead of BoxLayouts. This places all components evenly in the vertical direction. To provide only the minimum width to the labels (the first column) and assign all remaining space to the boxes (the second column) we place these two containers into another intermediate container managed by a BorderLayout: labels in the west, and corresponding components in the center. This solves our problem (see figure 4.15). The only downside to this solution is that it requires the construction of three intermediate containers with different layouts. In the next section we'll show how to build a custom layout manager that simplifies this relatively common layout task.

Now let's return to the remaining components. A group of JRadioButtons seems to be the simplest part of our design. They're placed into an intermediate container, JPanel p3, with a TitledBorder containing the required title: "Options". A vertical BoxLayout is used to place these components in a column and a ButtonGroup is used to coordinate their selection. This container is then added to panel p1 (managed by a horizontal BoxLayout) to sit on the eastern side of panel p1r.

The JList component is added to a JScrollPane to provide scrolling capabilities. It is then placed in an intermediate container, JPanel p2, with a TitledBorder containing the required title "Available Flights".

Note: We do not want to assign a TitledBorder to the JScrollPane itself because this would substitute its natural border, resulting in a quite awkward scroll pane view. So we nest the JScrollPane in its own JPanel with a TitledBorder.

Since the list grows and shrinks when the frame is resized and the group of radio buttons (residing to the right of the list) must occupy only the necessary width, it only makes sense to placed it in the center of the BorderLayout. We can then use the south region for the three remaining buttons.

Since all three buttons must be equal in size, they're added to a JPanel, p4c, with a 1x3 GridLayout. However, this GridLayout will occupy all available width (fortunately it's limited in the vertical direction by parent BorderLayout). This is not exactly the behavior we are looking for. To resolve this problem we use another intermediate container, JPanel p4, with a FlowLayout. This sizes the only added component, p4c, based on its preferred size and centers it both vertically and horizontally.

Running the Code

Figure 4.13, 4.14, and 4.15 show the resulting placement of our components in the parent frame using the first, second, and third variants described above. Note that variant 3's placement satisfies our specification. Note also that components are resized as expected when the frame container is resized.

When the frame is stretched in the horizontal direction, the text field, combo boxes, and list component consume additional space, and the buttons at the bottom are shifted to the center. When the frame is stretched in the vertical direction, the list component and the panel containing the radio buttons consume all additional space and all other components remain unchanged.

UI Guideline : Harnessing the Power of Java Layouts

Layout managers are powerful but awkward to use. In order to maximize the effectiveness of the visual communication we must make extra effort with the code. Making a bad choice of layout or making sloppy use of default settings may lead to designs which look poor or communicate badly.

In this example, we have shown three alternative designs for the same basic specification. Each exhibit pros and cons and highlight the design trade-offs which can be made, reflecting the principles which were discussed in chapter 2.

A sense of balance.

This occurs when there is sufficient white space used to balance the size of the components. An unbalanced panel can be fixed by bordering the components with a compound border including an empty border.

A sense of scale

Balance can be further affected by the extraordinary size of some components such as the combo boxes shown in Fig 4.14. The combo boxes are bit too big for the purpose intended. This affects the sense of scale as well as the balance of the design. Its important to size comboboxes appropriately. Layout managers have a tendency to stretch components to be larger than might be desirable.



[ Return to Swing (Book) ]


Top 10 read Java Articles
 Get free "1000 Java Tips eBook"

 Java Calendar and Date: good to know facts and code examples

 Array vs ArrayList vs LinkedList vs Vector: an excellent overview and examples

 How can I convert any Java Object into byte array? And byte array to file object

 The Java Lesson 1: What is Java?

 How do I compare two dates and times, date between dates, time between times and

 Maven vs Ant or Ant vs Maven?

 How to open, read, write, close file(s) in Java? Examples on move, rename and de

 Java Array

 Java: JLabel font and color


[ More in News Section ]
Java Lessons

The Java Lesson 1:
What is Java?
The Java Lesson 2:
Anatomy of a simple Java program
The Java Lesson 3:
Identifiers and primitive data types
The Java Lesson 4:
Variables, constants, and literals
The Java Lesson 5:
Arithmetic operations, conversions, and casts
The Java Lesson 6:
Boolean expressions and operations
The Java Lesson 7:
Bitwise operations
The Java Lesson 8:
Flow control with if and else
The Java Lesson 9:
switch statements
The Java Lesson 10:
for, while, and do-while statements
The Java Lesson 11:
Using break and continue
The Java Lesson 12:
Class methods and how they are called
The Java Lesson 13:
Using the Math class
The Java Lesson 14:
Creating and calling custom class methods
The Java Lesson 15:
Overloading class methods
The Java Lesson 16:
An introduction to objects and object references
The Java Lesson 17:
The String class
The Java Lesson 18:
The StringBuffer class
The Java Lesson 19:
Initializing and processing arrays of primitives
The Java Lesson 20:
Initializing and processing arrays of objects
The Java Lesson 23:
Inheritance and overriding inherited methods
The Java Lesson 24:
abstract classes and polymorphism
The Java Lesson 25:
Interfaces, instanceof, and object conversion and casting
The Java Lesson 26:
Introduction to graphical programming and the java.awt packa
The Java Lesson 27:
The Component class
The Java Lesson 28:
Containers and simple layout managers
The Java Lesson 29:
The Color and Font classes
The Java Lesson 30:
Drawing geometric shapes
The Java Lesson 31:
Choice, List, and Checkbox controls
The Java Lesson 32:
Using the Scrollbar graphical control
The Java Lesson 33:
Menus and submenus
The Java Lesson 34:
An introduction to applets and the Applet class
The Java Lesson 35:
Essential HTML to launch an applet and pass it parameters
The Java Lesson 36:
Mouse event processing
Java Lesson 37:
Menus and submenus
Java Lesson 38:
The WindowListener interface and the WindowAdapter class
Java Lesson 39:
An introduction to GridBagLayout
Java Lesson 40:
An introduction to the Java Collections API
Java Lesson 41:
Exception handling with try, catch, and finally blocks
Java Lesson 42:
Claiming and throwing exceptions
Java Lesson 43:
Multithreading, the Thread class, and the Runnable interface
Java Lesson 44:
An introduction to I/O and the File and FileDialog classes
Java Lesson 45:
Low-level and high-level stream classes
Java Lesson 46:
Using the RandomAccessFile class
Java Lessons by
Joh Huhtala: Update

Latest articles
 Java Profiler JProbe to Resolve Performance Problems Faster

 SSL with GlassFish v2, page 5

 SSL with GlassFish v2, page 4

 SSL with GlassFish v2, page 3

 SSL with GlassFish v2, page 2

 The Java Lesson 2: Anatomy of a simple Java program, page 2

 New site about Java for robots and robotics: both software and hardware.

 Exceptions -III: What's an exception and why do I care?

 Exceptions -II: What's an exception and why do I care?

 Exceptions: What's an exception and why do I care?

 Double your Java code quality in 10 minutes, here is receipt

 Murach's Java Servlets and JSP

 How to get ascii code from a char in Java?

 Can we just try without catch? Yes!

 Make Tomcat page load faster

 Make your Tomcat More secure - limit network address for certain IP addresses

 New Java book online starts now here...

 Implementing RESTful Web Services in Java

 Firefox trimming from 1 GB to 40 Mb with many tabs opened

 SSL with GlassFish v2

 My request to replublish Tech Tips

 Search JavaFAQ.nu site here

 New Advanced Installer for Java 6.0 brings XML updates and imports 3rd party MSI

 EJB programming restrictions

 Maven vs Ant or Ant vs Maven?

 Why Java does not use default value which it should?

 How to unsign signed bytes in Java - your guide is here

 The Java Lesson 3: Identifiers and primitive data types. Page 2

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 4

 The Java Lesson 7: Bitwise operations with good examples, click here! Page 3


[ More in News Section ]


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy