Home : Course Map : Chapter 7 : Java : Supplements :
Enhancements to UI Components and Layout: Part 1
JavaTech
Course Map
Chapter 7

Introduction
Event Overview
Event Processing
Button Events
  Demo 1
 Demo 2
Mouse Events
  Demo3

More Components
  Demo 4  Demo 5
  Demo 6  Demo 7

LayoutManagers-1
  Demo 8     Demo 9
  Demo 10  Demo 11
  Demo 12

LayoutManagers-2
  Demo 13  Demo 14
  Demo 15  Demo 16
  Demo 17

Inner Classes
Anonymous Class
Adapter Classes
  Demo 18  Demo 19
Frames & Menus
  Demo 20  Demo 21
Exercises

    Supplements
AWT Components
  Button
     Demo 1
  Canvas
     Demo 2
  AWT GUI Demo
     Demo 3
Swing Dialogs
JOptionPane Dialog
  Demo 1
JDialog
  Demo 2
UI Enhancement: P1
  Demo 1   Demo 2
  Demo 3

UI Enhancement: P2
  Demo 1
     About JavaTech
     Codes List
     Exercises
     Feedback
     References
     Resources
     Tips
     Topic Index
     Course Guide
     What's New
The Swing collection of components is quite large (see this visual index) and they offer a wide range of functions and features. The various layout managers discussed in Chapter 7: Java provide for a great diversity of arrangements of these components. Panels can hold multiple sub-panels, each with its own layout manager and set of components. So with these Swing tools you can build very elaborate and feature rich user interfaces for your programs.

Howerver, the appearance of the interfaces displayed in the various examples so far may appear somewhat boring. We will give a brief introduction here to some of the techniques available for modifying the appearance of the components and the border areas between the components. See the references below for links to tutorials that provide more information and examples for these techniques. We also briefly mention some functionality enhancements as well.

For the four demonstration programs below, we started with the GridBagLayout example from Chapter 7: Java: Layouts.

Insets

The dimensions of the border area of a container component are found from its Insets object. The border values are given by the integer fields top, left, bottom, right. An insets object can be created by passing the border values as follows:

  Insets(int top, int left, int bottom, int right)

In our first example, GridBagLayoutV1, we create a static Insets object in

  static final Insets fInsets = new Insets(2,2,2,2);

and then set the appropriate field in the GridBagConstraints object:

  constraints.insets = fInsets;

Comparing this interface with the original demo, we see that this puts a border gap around the components in the layout. You can vary this gap by modifiying the constraints insets value before adding each component.

For the component in the top right corner the border area is much larger. For that one we decided to manipulate its border directly. We created a panel with a wide border and then added the button to it. The button will be constrained within the thicker border area.

The method getInsets(), inherited from Container, returns an Insets object with the current border values for that component.

   Insets insets = myContainer.getInsets ();

It might seem logical that if you want to change the border dimensions, you would create an Insets object with the desired dimensions and pass it via a setInsets() method. However, there is no a setInsets() method. (We will show in the next example how to set a border explicitly.) For this case, we modify the Insets for the panel by creating a subclass of panel (called MyNewInsetsPanel ) that overrides the getInsets() method and returns an Insets object with the desired dimensions. The layout manager will invoke this method when it is calculating how to layout the component.

The source code for GridBagAppletV1 and its panel class GridBagPanel is shown below. The sections of code that differ from GridBagApplet are shown in red.

 

GridBagLayoutV1

/** First modification of GridBagLayout involves using insets to put
  * space around the components.
**/
public class GridBagAppletV1 extends JApplet {

  public void init () {
    Container content_pane = getContentPane ();

    // Create an instance of the GridBagPanel
    GridBagPanelV1 grid_bag_panel = new GridBagPanelV1 ();

    // And add it to the applet's panel.
    content_pane.add (grid_bag_panel);
  } // init

} // GridBagAppletV1

/** Create a JPanel with 5 buttons and use GridBagLayout manager.**/
class GridBagPanelV1 extends JPanel {
  GridBagConstraints constraints = new GridBagConstraints ();

  // The Insets constructor setting are passed as follows:
  // Insets(int top, int left, int bottom, int right)
  static final Insets fInsets = new Insets(2,2,2,2);


  GridBagPanelV1 () {

    setLayout (new GridBagLayout ());

    // Create a 3 row grid

    // Fill the grid squares with the component
    // in both x and y directions
    constraints.fill = GridBagConstraints.BOTH;

    // Keep same weight in vertical dimension
    constraints.weighty = 1.0;

  // Top row will include three  components, each
  // weighted differently in x
    // 0,0
    constraints.weightx = 1.0;
    constraints.gridx = 0;  constraints.gridy = 0;

    // We will use the same Insets object for the constraints
    // for each component.
    constraints.insets = fInsets;


    add (new JButton ("0,0"), constraints);

    // 0,1
    constraints.weightx = 0.5;
    constraints.gridx = 1;  constraints.gridy = 0;
    add (new JButton ("1,0"), constraints);

    // 0,2
    constraints.weightx = 0.1;
    constraints.gridx = 2;  constraints.gridy = 0;
    JButton button20 = new JButton ("2,0");
    JPanel button20_panel =
       new MyNewInsetsPanel (new BorderLayout ());
    button20_panel.add (button20);
    add (button20_panel, constraints);


  // Middle row has two components. First takes up two
  // rows, second takes up two columns
    // The first component on second row will span
    // vertically to third row

    // 0,1 to 0,2
    constraints.weightx = 1.0;
    constraints.gridx = 0;  constraints.gridy = 1;
    constraints.gridheight = 2;
    add (new JButton ("0,1 to 0,2"), constraints);

    // The second component on second row will span
    // horizontally to third column
    // 1,1 to 2,1
    constraints.weightx = 1.0;
    constraints.gridx = 1;  constraints.gridy = 1;
    constraints.gridheight = 1;
    constraints.gridwidth  = 2;
    add (new JButton ("1,1 to 2,1"), constraints);

  // Bottom row has 2 components with fill set to NONE
  // Use anchor.
    constraints.fill = GridBagConstraints.NONE;

    // 1,2
    constraints.anchor = GridBagConstraints.SOUTHEAST;
    constraints.weightx = 0.5;
    constraints.gridx = 1;  constraints.gridy = 2;
    constraints.gridheight = 1;
    constraints.gridwidth  = 1;
    add (new JButton ("1,2"), constraints);

    // 2,2
    constraints.anchor = GridBagConstraints.WEST;
    constraints.weightx = 0.1;
    constraints.gridx = 2;  constraints.gridy = 2;
    constraints.gridheight = 1;
    constraints.gridwidth  = 1;
    add (new JButton ("2,2"), constraints);
  } // ctor
} // class GridBagPanelV1


/** Simple JPanel subclass to demonstrate how to
  * override getInsets to modify the border size.
 **/
class MyNewInsetsPanel extends JPanel {
   public MyNewInsetsPanel (LayoutManager layout) {
     super (layout);
   }
   public Insets getInsets () {
     return new Insets (5,10,5,10);
   }
} //
MyNewInsetsPanel

 

Border

Swing provides for much more elaborate control of the border than simple modifying the insets dimensions. Decorative and non-decorative borders for Swing components can be created with the Border class and the setBorder() method in the JComponent class.

Note that generally, it is best to manipulate the borders only of panels and labels. You can always add other kinds of components to a panel with the border that you desire.

In the GridBagAppletV2 demo shown below, we show examples of some of the types of borders you can create. See How to Use Borders - Sun Java Tutorial for a more detailed introduction to making borders and for examples of border types not shown here.

Again we show in red the new code. We create seven Border objects using the factory methods in the Border class. The first case is an empty border that provides an empty margin area similar to what could be obtained from the insets technique used above.

Border empty_border = BorderFactory.createEmptyBorder (10,5,10,5);

A panel is created and the border set to this one:

empty_border_panel.setBorder (empty_border);

We next use a similar procedure to create a rasied-bevel border and a red line border. The fourth case adds a title to the red line border. The fifth creates a compound border made from a combination of the red line and raised bevel border.

The final two examples use matte borders created from image icons (Note that we now pass a reference for the applet to the GridBagPanelV2 constructor for the convenience of using the getImage() method available from the applet class for obtaining the image file for icon.)

 

GridBagLayoutV2
Resources: bluebox.jpg, redDot.gif

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.border.*;

/**
  * Our second modification to GridBagLayout involves
  * setting borders for the components..
 **/
public class GridBagAppletV2 extends JApplet{

  public void init () {
    Container content_pane = getContentPane ();

    // Create an instance of the GridBagPanel
    GridBagPanelV2 grid_bag_panel = new GridBagPanelV2 (this);

    // And add it to the applet's panel.
    content_pane.add (grid_bag_panel);
  } // init

} // GridBagAppletV2

/**
  * Create a JPanel with 5 components and use GridBagLayout for the
  * overall layout.
 **/
class GridBagPanelV2 extends JPanel {
  GridBagConstraints constraints = new GridBagConstraints ();

  // The Insets constructor setting are passed as follows:
  // Insets(int top, int left, int bottom, int right)
  static final Insets fInsets = new Insets(2,2,2,2);

  GridBagPanelV2 (JApplet applet) {

    setLayout (new GridBagLayout ());

    // Create a 3 row grid

    // Fill the grid squares with the component
    // in both x and y directions
    constraints.fill = GridBagConstraints.BOTH;

    // Keep same weight in vertical dimension
    constraints.weighty = 1.0;

  // Top row will include three  components, each
  // weighted differently in x
    // 0,0
    constraints.weightx = 1.0;
    constraints.gridx = 0;  constraints.gridy = 0;
    constraints.insets = fInsets;

    // Use the empty border for a panel to put a margin area
    // around the button placed on the panel.
    // The arguments go as
    //  createEmptyBorder(int top, int left, int bottom, int right)
    Border empty_border = BorderFactory.createEmptyBorder (10,5,10,5);
    // User BorderLayout so the button will fill the whole panel area.
    JPanel empty_border_panel = new JPanel (new BorderLayout ());
    // Set the border for the panel
    empty_border_panel.setBorder (empty_border);
    // Add the button to the panel
    empty_border_panel.add (new JButton ("0,0"));
    // Finally, add the panel to the larger GridBagPanel
    add (empty_border_panel, constraints);

    // 0,1
    constraints.weightx = 0.5;
    constraints.gridx = 1;  constraints.gridy = 0;

    // Put a raised bevel border on a panel.
    Border raised_bevel =BorderFactory.createRaisedBevelBorder();
    JPanel raised_bevel_panel = new JPanel (new BorderLayout ());
    raised_bevel_panel.setBorder (raised_bevel);
    // Then place a button on the panel.
    raised_bevel_panel.add (new JButton ("1,0"));
    add  (raised_bevel_panel, constraints);

    // 0,2
    constraints.weightx = 0.1;
    constraints.gridx = 2;  constraints.gridy = 0;

    // Create a red line border for the panel
    Border red_border = BorderFactory.createLineBorder(Color.RED);
    JPanel red_border_panel = new JPanel (new BorderLayout ());
    red_border_panel.setBorder (red_border);
    red_border_panel.add (new JButton ("2,0"));
    add (red_border_panel, constraints);

  // Middle row has two components. First takes up two
  // rows, second takes up two columns
    // The first component on second row will span
    // vertically to third row

    // 0,1 to 0,2
    constraints.weightx = 1.0;
    constraints.gridx = 0;  constraints.gridy = 1;
    constraints.gridheight = 2;

    // Create a title border using the previous red line border.
    TitledBorder title_border = BorderFactory.createTitledBorder(
                                    red_border, "Title Goes Here");

    JPanel title_border_panel = new JPanel (new BorderLayout ());
    title_border_panel.setBorder (title_border);
    title_border_panel.add (new JButton ("0,1 to 0,2"));
    add  (title_border_panel, constraints);

    // The second component on second row will span
    // horizontally to third column
    // 1,1 to 2,1
    constraints.weightx = 1.0;
    constraints.gridx = 1;  constraints.gridy = 1;
    constraints.gridheight = 1;
    constraints.gridwidth  = 2;

    // Create a compound border of the red line and raised bevel borders
    Border compound_border =       BorderFactory.createCompoundBorder(red_border, raised_bevel);
    JPanel compound_border_panel = new JPanel (new BorderLayout ());
    compound_border_panel.setBorder (compound_border);
    compound_border_panel.add (new JButton ("1,1 to 2,1"));
    add  (compound_border_panel, constraints);

  // Bottom row has 2 components with fill set to NONE
  // Use anchor.
    constraints.fill = GridBagConstraints.NONE;

    // 1,2
    constraints.anchor = GridBagConstraints.SOUTHEAST;
    constraints.weightx = 0.5;
    constraints.gridx = 1;  constraints.gridy = 2;
    constraints.gridheight = 1;
    constraints.gridwidth  = 1;

    // Will use a small image to create an matte border.
    try {
      // Read in the image and create and icon.
      ImageIcon icon = new ImageIcon (
        new java.net.URL (applet.getCodeBase (), "redDot.jpg") );
      JPanel matte_panel = new JPanel (new BorderLayout ());
      matte_panel.setBorder (
        BorderFactory.createMatteBorder (20, 20, 20, 20, icon));
      matte_panel.add (new JButton ("1,2"));
      add (matte_panel, constraints);
    }
    catch (java.net.MalformedURLException mue)
    {}

    // 2,2
    constraints.anchor = GridBagConstraints.WEST;
    constraints.weightx = 0.1;
    constraints.gridx = 2;  constraints.gridy = 2;
    constraints.gridheight = 1;
    constraints.gridwidth  = 1;

    // Another matte border with a smaller image.
    try {
      ImageIcon icon =
       new ImageIcon (new java.net.URL (applet.getCodeBase (),
                                        "blueBox.jpg") );
      JPanel matte_panel = new JPanel (new BorderLayout ());
      matte_panel.setBorder (
          BorderFactory.createMatteBorder (10, 10, 10, 10, icon));
      matte_panel.add (new JButton ("2,2"));
      add (matte_panel, constraints);
    }
    catch (java.net.MalformedURLException mue)
    {}

  } // ctor
} // class GridBagPanelV2

 

Icons in Components

Another enhancement for user interfaces is to add icons to buttons and labels. In the first two buttons of GridBagApplet shown below, we pass via the button constructor the icon for the normal, unpressed state. Another icon for the pressed state is passed via the setPressed() method. For the second case we also set the fill parameter to NONE to eliminate the margin space around the icon.

The third component is replaced with a label on which we put an icon and also text. We make the background of the label opaque and then set it to yellow.

For the fourth case we put both an icon and text on the button. The other components are unchanged.

 

GridBagLayoutV3
Resources: bluebox.jpg, picButton.jpg, picButtonPressed.jpg, face.gif, redBall.gif, redDot.gif

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.border.*;


/**
  * Our third modification to GridBagLayout involves adding
  * icons to buttons and labels.
**/
public class GridBagAppletV3 extends JApplet{

  public void init () {
    Container content_pane = getContentPane ();

    // Create an instance of the GridBagPanel
    GridBagPanelV3 grid_bag_panel = new GridBagPanelV3 (this);

    // And add it to the applet's panel.
    content_pane.add (grid_bag_panel);
  } // init

} // GridBagAppletv3

/**
  * Create a JPanel with 5 components and use GridBagLayout
  * for the overall layout.
**/
class GridBagPanelV3 extends JPanel {
  GridBagConstraints constraints = new GridBagConstraints ();

  // The Insets constructor setting are passed as follows:
  // Insets(int top, int left, int bottom, int right)
  static final Insets fInsets = new Insets(2,2,2,2);

  // Need a reference back to the applet to use it for getting images.
  JApplet fApplet;

  GridBagPanelV3 (JApplet applet) {

    fApplet = applet;
    setLayout (new GridBagLayout ());

    // Create a 3 row grid

    // Fill the grid squares with the component
    // in both x and y directions
    constraints.fill = GridBagConstraints.BOTH;

    // Keep same weight in vertical dimension
    constraints.weighty = 1.0;

  // Top row will include three  components, each
  // weighted differently in x
    // 0,0
    constraints.weightx = 1.0;
    constraints.gridx = 0;  constraints.gridy = 0;
    constraints.insets = fInsets;

    // Use the empty border for a panel to put a margin area
    // around the button placed on the panel.
    Border empty_border = BorderFactory.createEmptyBorder (10,5,10,5);
    // User BorderLayout so the button will fill the whole panel area.
    JPanel empty_border_panel = new JPanel ();
    empty_border_panel.setBorder (empty_border);

    // Get an icon for the button in an unpressed state.
    ImageIcon icon = getIcon ("picButton.jpg");
    // Create the button with an icon and no text.
    JButton button00 = new JButton (icon);
    // Get the icon for the pressed button state
    ImageIcon icon_pressed = getIcon ("picButtonPressed.jpg");
    // Now pass the press icon to the button.
    button00.setPressedIcon (icon_pressed);


    empty_border_panel.add (button00);
    add (empty_border_panel, constraints);

    // 0,1
    // To get rid of the gap around the icon, set the fill to NONE.
    constraints.fill = GridBagConstraints.NONE;
    constraints.weightx = 0.5;
    constraints.gridx = 1;  constraints.gridy = 0;

    // Put a raised bevel border on a panel.
    Border raised_bevel =BorderFactory.createRaisedBevelBorder();
    JPanel raised_bevel_panel = new JPanel (new BorderLayout ());
    raised_bevel_panel.setBorder (raised_bevel);

    // Again set the icons for the unpressed and pressed button states.
    JButton button10 = new JButton (icon);
    button10.setPressedIcon (icon_pressed);
    button10.setMargin (new Insets (0,0,0,0));
    // Then place a button on the panel.
    raised_bevel_panel.add (button10);
    add  (raised_bevel_panel, constraints);

    // 0,2
    constraints.weightx = 0.1;
    constraints.fill = GridBagConstraints.BOTH;
    constraints.gridx = 2;  constraints.gridy = 0;
    // Create a red line border for the panel
    Border red_border = BorderFactory.createLineBorder(Color.RED);
    JPanel red_border_panel = new JPanel (new BorderLayout ());
    red_border_panel.setBorder (red_border);

    //
Use a label instead of a button. Pass the text and icon and tell
    // it to center both off them
    icon = getIcon ("redBall.gif");
    // Make the label background to opaque
    JLabel red_ball_label =
       new JLabel ("2,0", icon, SwingConstants.CENTER);
    // Make the label background to opaque
    red_ball_label.setOpaque (true);
    // and then set the color of the background.
    red_ball_label.setBackground (Color.YELLOW);


    red_border_panel.add (red_ball_label);
    add (red_border_panel, constraints);

  // Middle row has two components. First takes up two
  // rows, second takes up two columns
    // The first component on second row will span
    // vertically to third row

    // 0,1 to 0,2
    constraints.weightx = 1.0;
    constraints.gridx = 0;  constraints.gridy = 1;
    constraints.gridheight = 2;

    // Create a title border using the previous red line border.
    TitledBorder title_border = BorderFactory.createTitledBorder(
                                    red_border, "Title Goes Here");

    JPanel title_border_panel = new JPanel (new BorderLayout ());
    title_border_panel.setBorder (title_border);
    icon = getIcon ("face.gif");
    title_border_panel.add (new JButton ("0,1 to 0,2", icon));

    add  (title_border_panel, constraints);

    // The second component on second row will span
    // horizontally to third column
    // 1,1 to 2,1
    constraints.weightx = 1.0;
    constraints.gridx = 1;  constraints.gridy = 1;
    constraints.gridheight = 1;
    constraints.gridwidth  = 2;

    // Create a compound border of the red line and raised bevel borders
    Border compound_border =
      BorderFactory.createCompoundBorder(red_border, raised_bevel);
    JPanel compound_border_panel = new JPanel (new BorderLayout ());
    compound_border_panel.setBorder (compound_border);
    compound_border_panel.add (new JButton ("1,1 to 2,1"));
    add  (compound_border_panel, constraints);

  // Bottom row has 2 components with fill set to NONE
  // Use anchor.
    constraints.fill = GridBagConstraints.NONE;

    // 1,2
    constraints.anchor = GridBagConstraints.SOUTHEAST;
    constraints.weightx = 0.5;
    constraints.gridx = 1;  constraints.gridy = 2;
    constraints.gridheight = 1;
    constraints.gridwidth  = 1;


    icon = getIcon ("redDot.gif");
    JPanel matte_panel = new JPanel (new BorderLayout ());
    matte_panel.setBorder (
      BorderFactory.createMatteBorder (10, 10, 10, 10, icon));
    matte_panel.add (new JButton ("1,2"));
    add (matte_panel, constraints);


    // 2,2
    constraints.anchor = GridBagConstraints.WEST;
    constraints.weightx = 0.1;
    constraints.gridx = 2;  constraints.gridy = 2;
    constraints.gridheight = 1;
    constraints.gridwidth  = 1;


    icon = getIcon ("blueBox.jpg");
    matte_panel = new JPanel (new BorderLayout ());
    matte_panel.setBorder (
      BorderFactory.createMatteBorder (10, 10, 10, 10, icon));
    matte_panel.add (new JButton ("2,2"));
    add (matte_panel, constraints);

  } // ctor

  ImageIcon getIcon (String icon_name) {
    ImageIcon icon;
    try {
      icon = new ImageIcon (new java.net.URL (
                             fApplet.getCodeBase (), icon_name) );
    }
    catch (java.net.MalformedURLException mue)
    {  return null; }
    return icon;
  } // getIcon

} // class GridBagPanelV3

 

 

Continue to UI Enhancements: Part 2...

 

References & Web Resources

Latest update: Nov. 3, 2006

           Tech
Histogram UI
  Demo 1
Probablity Distrib.
  Demo 2 Demo 3
RejectionMethod
Histogram Stats
  Demo 4
Exercises

           Physics
Sim & Randomness
Custom Prob. Dist.
   Demo 1
Histogram Dist.
   Demo 2
Monte Carlo
  Demo 3
Exercises

  Part I Part II Part III
Java Core 1  2  3  4  5  6  7  8  9  10  11  12 13 14 15 16 17
18 19 20
21
22 23 24
Supplements

1  2  3  4  5  6  7  8  9  10  11  12

Tech 1  2  3  4  5  6  7  8  9  10  11  12
Physics 1  2  3  4  5  6  7  8  9  10  11  12

Java is a trademark of Sun Microsystems, Inc.