JDK 1.1 was formally released on February 18, 1997. This lesson was originally written on March 6, 1997 using the software and documentation in the JDK 1.1 download package.
This lesson looks at the first of several different approaches designed to place components in a container while minimizing cross-platform compatibility problems. This is accomplished using layout manager classes. In this lesson, we will concentrate on the BorderLayout class.
With the BorderLayout class, you can place up to five different components in a container. If you place all five components in the container, four of the components will be positioned along the edges of the container and the fifth will be in the center.
You specify the position of each component when you add the component to the container using the strings "North", "South", "East", "West" and "Center".
For example, the following three statements would
//create a Panel container object
Panel p = new Panel(); //specify use of the BorderLayout manager
//add a button at the bottom p.add(new Button("Okay"), "South"); |
The "North", "South", "East" and "West" components get sized and positioned according to their preferred sizes and the constraints of the container's size. The "Center" component gets any space left over.
Regarding the preferred size mentioned
above, according to Exploring Java by Niemeyer & Peck:
"Every component has two important pieces of information used by the layout manager in placing and sizing it: a preferred size and a minimum size. ... For example, a plain Button object can be resized to any proportions. However, the button's designer can provide a preferred size for a good-looking button. The layout manager might use this size when there are no other constraints, or it might ignore it, depending on its scheme. Now, if we give the button a label, the button may need a minimum size in order to display itself properly. The layout manager might show more respect for the button's minimum size and guarantee that it has at least that much space." |
"The getPreferredSize() method returns the Dimension (width and height) for the preferred size of the components within the container. The container determines its preferred size by calling the preferredLayoutSize() method of the current LayoutManager, which says how much space the layout manager needs to arrange the components. If you override this method, you are overriding the default preferred size." |
//This method defines the preferred display size of the // bean object. public synchronized Dimension getPreferredSize(){ return new Dimension(50,50); }//end getPreferredSize() |
The most straightforward way to specify a layout manager is to invoke the setLayout() method on the Container object passing an object of a class that implements the LayoutManager interface as a parameter.
BorderLayout is a class that extends Object and implements LayoutManager2. (If you are curious about the minimal difference between LayoutManager and LayoutManager2, it would be a good exercise to look it up in the JDK 1.1 documentation.)
The documentation defines the setLayout()
method as follows:
public void setLayout(LayoutManager mgr)
Parameters: mgr - the specified layout manager |
BorderLayout() -- Constructs a new BorderLayout
with no gaps between components.
BorderLayout(int, int) -- Constructs a BorderLayout with the specified gaps. |
One of the buttons is given a long label to force the layout manager to allocate space according to the minimum size requirement of that particular button.
You will also note that not all of the possible problems are eliminated. It is still possible to make the frame sufficiently small that
Another thing to notice is the way in which the larger minimum size requirement of the button on the "East" (caused by a longer label) is accommodated automatically with the extra space needed being taken from the button in the "Center".
Frame myFrame = new Frame( "Copyright 1997, R.G.Baldwin"); myFrame.add(new Button("South"),"South"); myFrame.add(new Button("West"),"West"); myFrame.add(new Button("North"),"North"); myFrame.add(new Button( "East with a long label"),"East"); myFrame.add(new Button("Center"),"Center"); myFrame.setSize(250,150); myFrame.setVisible(true); |
Then the size of the frame is established, and frame and its components are made visible.
The label on the button in the "East" position was made longer than the others to cause the minimum size of that button to be larger than the minimum size of each of the other buttons.
/*File Layout02.java Copyright 1997, R.G.Baldwin Revised 10/27/97 to better fit within the space. This program is designed to be compiled and run under JDK 1.1 This program creates a "Plain Vanilla" visual object by placing five non-functional Button objects on a Frame object using the default BorderLayout manager. One of the buttons is given a long label in order to force the layout manager to allocate space according to the minimum size requirement of that particular button. The program was tested using JDK 1.1 running under Win95. */ //=======================================================// import java.awt.*; import java.awt.event.*; //=======================================================// public class Layout02 { public static void main(String[] args){ //instantiate a Graphical User Interface object GUI gui = new GUI(); }//end main }//end class Layout02 //=======================================================// class GUI { public GUI(){//constructor Frame myFrame = new Frame( "Copyright 1997, R.G.Baldwin"); myFrame.add(new Button("South"),"South"); myFrame.add(new Button("West"),"West"); myFrame.add(new Button("North"),"North"); myFrame.add(new Button( "East with a long label"),"East"); myFrame.add(new Button("Center"),"Center"); myFrame.setSize(250,150); myFrame.setVisible(true); }//end constructor }//end class GUI definition //=======================================================// |
An action listener object is instantiated and registered to listen for action events on all five of the buttons, with all five buttons sharing the same action event handler.
The behavior of the action event handler is to increase the spacing between components by five pixels whenever any of the buttons is pressed. This is accomplished by
If you click the buttons repeatedly, three of the buttons will shrink entirely out of sight. They can be made to reappear by physically enlarging the frame.
A windowClosing() event listener object is instantiated and registered on the frame to terminate the program when the frame is closed.
The program was tested using JDK 1.1 running under Win95.
Frame myFrame = new Frame( "Copyright 1997, R.G.Baldwin"); BorderLayout myBorderLayout = new BorderLayout(3,3); myFrame.setLayout(myBorderLayout); |
Button button1 = new Button("South"); |
myFrame.add(button1,"South"); |
MyActionListener myActionListener = new MyActionListener(myBorderLayout,myFrame); button1.addActionListener(myActionListener); |
Then the modified BorderLayout() object is used in conjunction with setLayout() to cause the modified BorderLayout object to become the layout manager for the Frame object. (Note that the layout manager for the Frame object is being modified at runtime.)
Then the validate() method is used to force the Frame
object to readjust the size and locations of its components and to display
the modified version of itself.
public void actionPerformed(ActionEvent e){ myBorderLayoutObject.setHgap( myBorderLayoutObject.getHgap() + 5 ); myBorderLayoutObject.setVgap( myBorderLayoutObject.getVgap() + 5 ); myFrameObject.setLayout(myBorderLayoutObject); myFrameObject.validate(); }//end actionPerformed() |
.
/*File Layout03.java Copyright 1997, R.G.Baldwin Revised 10/26/97 to cause the source code to better fit in the allocated space in the lesson. This program is designed to be compiled and run under JDK 1.1 This program has more substance that the previous one in this lesson, although it doesn't do anything particularly useful. Five buttons are added to a frame using a BorderLayout object as the layout manager with a three-pixel gap between components in both the horizontal and vertical direction. An action listener object is instantiated and registered to listen for action events on all five of the buttons, with all five buttons sharing the same event handler. The behavior of the action event handler is to increase the spacing between components whenever any of the buttons is pressed. This is accomplished by increasing the Vgap and Hgap attributes of the BorderLayout object, setting the layout manager of the frame to the modified BorderLayout object, and validating the frame. The validation step is required in order for the change to become visible. If you continue to click the buttons long enough, three of the buttons will shrink entirely out of sight. They can be made to reappear by manually enlarging the frame. A windowClosing() event listener object is instantiated and registered on the frame to terminate the program when the frame is closed. The program was tested using JDK 1.1.3 running under Win95. */ //=======================================================// import java.awt.*; import java.awt.event.*; //=======================================================// public class Layout03 { public static void main(String[] args){ //instantiate a Graphical User Interface object GUI gui = new GUI(); }//end main }//end class Layout03 //=======================================================// class GUI { public GUI(){//constructor Frame myFrame = new Frame( "Copyright 1997, R.G.Baldwin"); //Instantiate a BorderLayout object with default Center // alignment and a Vgap and Hgap of 3 pixels. BorderLayout myBorderLayout = new BorderLayout(3,3); //Set the layout manager for the frame to be the // BorderLayout object. myFrame.setLayout(myBorderLayout); //Instantiate five Button objects Button button1 = new Button("South"); Button button2 = new Button("West"); Button button3 = new Button("North"); Button button4 = new Button("East"); Button button5 = new Button("Center"); //Add the five Button objects to the Frame object in // the positions specified. myFrame.add(button1,"South"); myFrame.add(button2,"West"); myFrame.add(button3,"North"); myFrame.add(button4,"East"); myFrame.add(button5,"Center"); myFrame.setSize(250,150); myFrame.setVisible(true); //Instantiate an action listener object and register // it on all five buttons. MyActionListener myActionListener = new MyActionListener(myBorderLayout,myFrame); button1.addActionListener(myActionListener); button2.addActionListener(myActionListener); button3.addActionListener(myActionListener); button4.addActionListener(myActionListener); button5.addActionListener(myActionListener); //Instantiate and register a window listener to // terminate the program when the Frame is closed. myFrame.addWindowListener(new Terminate()); }//end constructor }//end class GUI definition //=======================================================// class MyActionListener implements ActionListener{ BorderLayout myBorderLayoutObject; Frame myFrameObject; //constructor MyActionListener( BorderLayout layoutObject,Frame inFrame){ myBorderLayoutObject = layoutObject;//save references myFrameObject = inFrame; }//end constructor //When an action event occurs, increase the horizontal // and vertical gap between components in the // BorderLayout object. Then set the layout manager for // the frame to be the newly-modified BorderLayout // object. Then validate the frame to ensure a valid // layout so that the new visual will take effect. public void actionPerformed(ActionEvent e){ myBorderLayoutObject.setHgap( myBorderLayoutObject.getHgap() + 5 ); myBorderLayoutObject.setVgap( myBorderLayoutObject.getVgap() + 5 ); myFrameObject.setLayout(myBorderLayoutObject); myFrameObject.validate(); }//end actionPerformed() }//end class MyActionListener //=======================================================// class Terminate extends WindowAdapter{ public void windowClosing(WindowEvent e){ //terminate the program when the window is closed System.exit(0); }//end windowClosing }//end class Terminate //=======================================================// |
As in the program named Layout03, five buttons are added to a Frame object using a BorderLayout object as the layout manager with a one-pixel gap between components in both the horizontal and vertical direction. There are no captions on any of the buttons.
When the program starts, the buttons in the East and West positions are each approximately 100 pixels wide and the button in the Center is approximately 50 pixels wide.
Each time you click on any of the buttons, the horizontal gap between buttons increases by five pixels. However, the widths of the East and West buttons don't change appreciably. In other words, the increase in horizontal gap is accommodated almost entirely as a result of the Center button becoming narrower.
If you continue to click the buttons long enough, the Center button will shrink entirely out of sight but the other four buttons will continue to be visible with no apparent change in size. The Center button can be made to reappear by manually enlarging the Frame.
If you manually increase the width of the Frame, the widths of the East and West buttons don't change appreciably. Rather, the Center button increases in width to accommodate the change in the width of the Frame object.
If you start the program running and then manually decrease the width of the Frame object, the Center button decreases in width to accommodate the reduction in overall width. Eventually the Center button will shrink completely out of sight and then the East and West buttons will collide and begin to change width.
A - See the solution below.
/*File SampProg135.java Copyright 1997, R.G.Baldwin Without viewing the solution that follows, rewrite the program named Layout03 with the following changes: As in the program named Layout03, five buttons are added to a Frame object using a BorderLayout object as the layout manager with a one-pixel gap between components in both the horizontal and vertical direction. There are no captions on any of the buttons. When the program starts, the buttons in the East and West positions are each approximately 100 pixels wide and the button in the Center is approximately 50 pixels wide. Each time you click on any of the buttons, the horizontal gap between buttons increases by five pixels. However, the widths of the East and West buttons don't change appreciably. In other words, the increase in horizontal gap is accommodated almost entirely as a result of the Center button becoming narrower. If you continue to click the buttons long enough, the Center button will shrink entirely out of sight but the other four buttons will continue to be visible with no apparent change in size. The Center button can be made to reappear by manually enlarging the Frame. If you manually increase the width of the Frame, the widths of the East and West buttons don't change appreciably. Rather, the Center button increases in width to accommodate the change in the width of the Frame object. If you start the program running and then manually decrease the width of the Frame object, the Center button decreases in width to accommodate the reduction in overall width. Eventually the Center button will shrink completely out of sight and then the East and West buttons will collide and begin to change width. A windowClosing() event listener object is instantiated and registered on the frame to terminate the program when the frame is closed. The program was tested using JDK 1.1.3 running under Win95. */ //=======================================================// import java.awt.*; import java.awt.event.*; //=======================================================// public class SampProg135 { public static void main(String[] args){ //instantiate a Graphical User Interface object GUI gui = new GUI(); }//end main }//end class SampProg135 //=======================================================// class GUI { public GUI(){//constructor Frame myFrame = new Frame( "Copyright 1997, R.G.Baldwin"); //Instantiate a BorderLayout object with a Vgap // and Hgap of 1 pixel. BorderLayout myBorderLayout = new BorderLayout(1,1); //Set the layout manager for the frame to be the // BorderLayout object. myFrame.setLayout(myBorderLayout); //Instantiate five button-like objects. Note that two // of these objects are of type MyButton instead of // type Button. Button button1 = new Button(); MyButton button2 = new MyButton(); Button button3 = new Button(); MyButton button4 = new MyButton(); Button button5 = new Button(); //Add the five button-like objects to the Frame object // in the positions specified. myFrame.add(button1,"South"); myFrame.add(button2,"West"); myFrame.add(button3,"North"); myFrame.add(button4,"East"); myFrame.add(button5,"Center"); myFrame.setSize(250,150);//set size of frame myFrame.setVisible(true); //Instantiate an action listener object and register // it on all five buttons. MyActionListener myActionListener = new MyActionListener(myBorderLayout,myFrame); button1.addActionListener(myActionListener); button2.addActionListener(myActionListener); button3.addActionListener(myActionListener); button4.addActionListener(myActionListener); button5.addActionListener(myActionListener); //Instantiate and register a window listener to // terminate the program when the Frame is closed. myFrame.addWindowListener(new Terminate()); }//end constructor }//end class GUI definition //=======================================================// class MyActionListener implements ActionListener{ BorderLayout myBorderLayoutObject; Frame myFrameObject; //constructor MyActionListener( BorderLayout layoutObject,Frame inFrame){ myBorderLayoutObject = layoutObject;//save references myFrameObject = inFrame; }//end constructor //When an action event occurs, increase the horizontal // gap between components in the BorderLayout object. // Then set the layout manager for the frame to be the // newly-modified BorderLayout object. Then validate // the frame to ensure a valid layout so that the new // visual will take effect. public void actionPerformed(ActionEvent e){ myBorderLayoutObject.setHgap( myBorderLayoutObject.getHgap() + 5 ); myFrameObject.setLayout(myBorderLayoutObject); myFrameObject.validate(); }//end actionPerformed() }//end class MyActionListener //=======================================================// class Terminate extends WindowAdapter{ public void windowClosing(WindowEvent e){ //terminate the program when the window is closed System.exit(0); }//end windowClosing }//end class Terminate //=======================================================// //This class extends the standard Button class in order // to make it possible to override the getPreferredSize() // method. The BorderLayout manager honors the width of // the preferred size insofar as possible to maintain the // specified preferred width. class MyButton extends Button{ public synchronized Dimension getPreferredSize(){ return new Dimension(100,100); }//end getPreferredSize() }//end class MyButton |