| 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 |