Java Swing Containers by zkg17707

VIEWS: 181 PAGES: 11

									                                                                                        LECTURE 6

                        Java Swing Containers

Contents of lecture 6:

1.   Containers within Java

     •   Overview of Container functionality
     •   Different container types within Java
     •   Layout managers

Definition of a Container
 Containers are on screen windows that contain controls or other sub-
 containers. A container, and all of the objects within that container, can be
 moved, hidden, shown, etc. in a single operation (e.g. whenever the
 setVisible() method is called on a JFrame object, all the components
 within that JFrame are also painted). Top-level containers are defined as
 those which can be displayed directly on the desktop. Non top-level
 containers must be displayed within the context of another top-level container.

Container hierarchy
 The Java AWT and Swing container hierarchies follow. Note, with one exception
 (WindowPopup) all Java containers are prefixed with a ‘J’, e.g. JWindow, JFrame,




     Frame            Dialog                                     Applet

     JFrame           JDialog             JWindow               JApplet            JPanel

 javax.Swing containers

 Containers are mostly derived from one of two superclasses, either java.awt.Window or
 java.awt.Panel. JPanel is an exception to this, and is derived from JComponent. Broadly
 speaking, panels are intended for use within applets, whereas windows are intended for use
 within applications.

                                                  PAGE   74
                                                                                        LECTURE 6

 Evidently, containers inherit all of the methods declared within the component class, entailing
 that they can have their size queried and set, be hidden and shown, etc. However, it is best to
 regard java.awt.Container as being the focal superclass of all containers. It is considered next.

public abstract class Container extends Component
 The Container class provides the following useful methods (in addition to those inherited from
 the Component class).

Adding/removing components
 Components may be added to a container through the public Component add( Component
 comp ) method. Likewise a component can be removed via the use of the public void
 remove( Component comp ) method.
 A few other add/remove methods are available, permitting a component to be added at a
 particular index and/or using a particular set of layout constraints (e.g. someContainer.add(
                          someComponent, BorderLayout.NORTH )). Additionally, the
                          public void removeAll() method can be used to remove all
                          components from a container.
                            A number of methods are provided that enable the components
                            contained within the container to be retrieved. For example the public
                            Component[] getComponents() method returns an array of all the
 components contained within the container, whereas the public Component getComponent(
 int n ) returns the nth component and the public Component getComponentAt( int x, int y )
 returns the component that touches point (x,y).
 Note, public void addContainerListener( ContainerListener listener)
 and public void removeContainerListener( ContainerListener listener)
 methods are available. However, a container listener should only be used for
 notification purposes. Finally, the public int getComponentCount() returns
 the number of components within the container.

Layout managers
 Each container possesses a layout manager that determines how components are sized and
 positioned within the container (the various layout managers are explored later).
 The particular layout manager that is in effect can be obtained via the public LayoutManager
 getLayout() method and likewise set using the public void setLayout( LayoutManager mgr
 ) method. The layout manager can be forced to layout all the components by
 calling the public void doLayout() method. Note, it is recommended that the
 programmer does not call doLayout() directly, instead they should call public
 void validate() which, when invoked, results in the doLayout() method being
 called if an update is necessary.
 The related method public void invalidate() should be called whenever the
 programmer needs to inform the AWT that the container should be reformed
 (i.e. all components are repositioned and redrawn).

                                                  PAGE   75
                                                                                          LECTURE 6

Painting and drawing on Containers
 Whilst a container inherits the paint/update, etc. methods of the component class, within the
 Container class refined versions of these methods are made available.
 In particular, the public void update( Graphics g ) and public void paint( Graphics g )
 methods ensure that any lightweight components (i.e. Swing components) contained within the
 container are told to render themselves (i.e. the component should
 draw itself on the screen). Should the programmer override the
 containers paint method, then it is important they call
 super.paint(g) to ensure lightweight components will be
 correctly drawn inside the container.

Swing Containers
 In what follows the different types of Swing container will be explored. Before this, it is
 necessary to highlight the differences between an AWT container and a Swing container.
 Principally, a Swing container is intended to store lightweight components, whereas an AWT
 container is intended to store heavyweight components.
 In order to ensure components can be displayed in a flexible manner, Swing containers define
 several different layers (in contrast AWT containers contain a single layer). An overview

       JFrame          JWindow           JApplet               JDialog         JPanel




 JFrame, JWindow, JApplet and JDialog are top-level containers (i.e. can appear on their own
 on the screen). This is not true of JPanel and JInternalFrame, which must appear within the
 confines of a top-level container.

                                                   PAGE   76
                                                                                          LECTURE 6

 Starting from the top down, the various layers within a Swing container are as follows:

 •   JGlassPane. This pane overlays all the other panes and is intended to permit the
     programmer to draw over the entire container without getting distracted by the
     components within the container.
 •   JContentPane. Components are added to this pane, e.g.
     mySwingContainer.getContentPane().add( someComponent), etc. The
     layout manager also operates within the confines of the content pane, determining
     how components should be sized and positioned within this pane (by default a
     border layout is assumed).
 •   JMenuBar. This pane is used for displaying any menus associated with the Swing
 •   JLayeredPane. This pane resides under the content and menubar panes. Many complex
     graphical applications will contain a number of layers (e.g. one component may be partially
     covering another, etc.). Java uses these layers to track the underlying components, and
     automatically ensures that the correct components are shown.
 •   JRootPane. This is the fundamental Swing container, and forms the foundation onto which
     the other layers can be placed.
 The JPanel class does not possess a contents pane, etc., i.e. it is not a top level container and
 offers limited functionality (it is a basic container).
 The JFrame, JWindow, JApplet and JDialog classes provide public Container
 getContentPane(), public Component getGlassPane(), public JMenuBar
 getJMenuBar(), public JLayeredPane getLayeredPane() and public JRootPane
 getRootPane() methods. Corresponding set methods are provided for the content, glass, menu
 bar and layered panes (it is not possible to change the root pane).
 Also note, that whilst the menubar pane is optional, the layered pane, content pane and glass
 pane always exist. In what follows each of the different types of Swing container are

public class JFrame extends Frame
 A JFrame is a window that contains a
 title bar, menubar and a border.
 Furthermore, frames are reduced to an
 icon if minimised.
 The JFrame class extends the normal
 AWT Frame by simply adding various
 methods for setting and retrieving the
 different panes. In turn the Frame class
 defines a number of useful methods,
 including public void setIconImage(
 Image image ), public Image
 getIconImage(), public boolean
 isResizable() and public void
 setResizable( boolean resizable ).

                                                   PAGE   77
                                                                                          LECTURE 6

 Whenever a frame object is declared it is not assigned a default size, nor is it visible. Hence,
 before a frame can be displayed the public void setSize( int width, int height ) and public
 void setVisible( boolean b ) methods should be called (sometimes the depreciated show()
 method is used instead of the correct setVisible()).
 The code for creating a simple frame object, and adding some components is as follows:

             public class myFrame extends JFrame
                      public myFrame()
                              // Set the title of the frame
                              setTitle( “myFrame Example” );

                               // Specify the layout manager
                               getContentPane().setLayout( new BorderLayout());

                               // Place a button in the middle of the frame
                               add( someButton, BorderLayout.CENTER );

                               // Define the menu bar to be used
                               setJMenuBar( myMenuBar );

                               // Define the frame’s size and make it visible
                               setSize(500,250);         setVisible(true);

public class JDialog extends Dialog
 Dialog windows are suited to those instances where some information must be
 gleamed from the user (often in situations where the program cannot continue until it
 receives further instructions). Some example dialog windows follows

 A dialog can be made modal, entailing that the user cannot interact with any other displayed
 windows (belonging to the program) until the dialog window has been dismissed (i.e. useful
 when the program cannot continue without user guidance). In contrast, non-modal dialogs can
 be freely selected and deselected by the user.
 A number of constructors are provided for the JDialog class, the most general is the public
 JDialog( Frame owner, String title, boolean modal), which permits the dialog to be
 associated with its parent frame, and the title and modal/non-modal nature of the dialog to be
 As with all the top-level Swing containers, a number of methods are provided for
 setting/retrieving the various panes/layout manager, etc. Apart from this, the JDialog class
 provides no extra functionality (i.e. dialogs are associated with a frame, components added, and
 event handlers setup).

                                                   PAGE   78
                                                                                      LECTURE 6

Example of JFrame/JDialog usage
 The following example will develop a JFrame application that can spawn any number of
 JDialog children. Each child dialog will contain a JSlider, which the user can vary between 0
 and 100. Any changes in the slider’s value will be output by the JFrame parent, e.g.:

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

 public class MyFrame extends JFrame
          int iNumFrames=0; JLabel outputLabel; JButton startButton;

         // Construct GUI, add action listener
         public MyFrame()
                 outputLabel = new JLabel();
                 startButton = new JButton( "Start" );
                 startButton.addActionListener( new ActionListener()
                          { public void actionPerformed( ActionEvent event )
                                    { createDialog(); }
                          } );

                  getContentPane().add( outputLabel, BorderLayout.CENTER );
                  getContentPane().add( startButton, BorderLayout.SOUTH );
                  setSize( 300, 100 ); setVisible( true );

         // Create and display a new dialog box
         private void createDialog()
                   String dialogTitle = "Dialog [" + (iNumFrames++) + "]";
                   MyDialog newDialog = new MyDialog( this, dialogTitle, false, outputLabel );
         // Start the application and add a window close handler
         public static void main( String args[] )
                   MyFrame frameInstance = new MyFrame();
                            new WindowAdapter()
                                      public void windowClosing(WindowEvent e )
                                      { System.exit( 0 ); }

                                                  PAGE   79
                                                                                         LECTURE 6

 The above defines the JFrame class, the JDialog class now follows:

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

   public class MyDialog extends JDialog
            JSlider slider; JLabel dialogOutput; String dialogTitle;

            // Provide a general constructor
            public MyDialog( Frame owner, String title, boolean modal, JLabel output )
                     super( owner, title, modal );

                     // Store needed passed parameters
                     dialogOutput = output; dialogTitle = title.toString();

                     // Create dialog controls
                     slider = new JSlider( JSlider.HORIZONTAL, 0,100,50 );
                     slider.addChangeListener( new ChangeListener()
                                                public void stateChanged( ChangeEvent e )
                                                { dialogOutput.setText( dialogTitle +
                                                         " : " + slider.getValue() ); }
                                       } );

                     // Add them to the dialog
                     getContentPane().add( slider ); setSize( 300, 50 ); setVisible( true );

 The above example illustrates how a JFrame object may create any number of
 JDialog child windows, with each dialog sending information back to the frame
 Java also offers a number of JOptionPane classes, providing a means of easily and
 quickly constructing dialogs. However, in those cases where the option pane offer
 too simple a degree of functionality, it is necessary to extend the JDialog class.

public class JWindow extends Window
 A JWindow is a container that can be displayed anywhere on the screen (i.e. it is a top level
 container). However, unlike a frame, a window does not have a title bar,
 window-management buttons, or the other attractive features of a frame.
 Hence, a JFrame should be used whenever a fully featured window
 (including menu, close buttons, etc.) is needed. A JDialog should be used
 whenever some input is needed from the user. A JWindow object is really
 only suited to those few applications where some simple, additional
 information needs to be displayed to the user (e.g. pop-up menus).

JApplets and JPanels
 JApplets and JPanels are not considered here. It is assumed the earlier Java programming
 course has explored them in sufficient detail.

                                                    PAGE   80
                                                                                         LECTURE 6

Layout Managers
 By default, each container has a layout manager; an object that determines where
 and how components will be displayed within the container. Whilst components
 can provide size and alignment hints, it is the layout manager that has the final say
 on how they are positioned (however, certain layout managers will try to
 accommodate the preferred size specified by the component).
 The Java platform supplies five default layout managers: BorderLayout,
 BoxLayout, FlowLayout, GridBagLayout, and GridLayout. An overview of each
 type of layout manager follows:

Border Layout
 BorderLayout is the default layout manager for all content panes (i.e. JContentPane). A
 BorderLayout has five areas available for holding components, namely, NORTH, SOUTH,
 EAST, WEST and CENTER. All extra space is placed in the center area.

 A BorderLayout can be employed as follows:
                    Panel p = new Panel();
                    p.setLayout( new BorderLayout() );
                    p.add( new JButton( “Ok” ), BorderLayout.SOUTH );

Box Layout
 The BoxLayout manager puts components in a single row or column. The manager will ensure
 that components are not sized beyond their requested maximum size.
                         The BoxLayout scheme can be used within a program as follows:
                           JFrame f = new JFrame();
                           p.getContentPane().setLayout( new
                                   BoxLayout(p, BoxLayout.Y_AXIS));

                           p.add( new JButton( “Okay” );

Flow Layout
 FlowLayout is the default layout manager for all JPanel objects, simply setting out components
 from left to right, starting new rows when necessary, e.g.
                       Container contentPane = getContentPane();
                       contentPane.setLayout(new FlowLayout());
                       contentPane.add(new JButton("1"));

                                                   PAGE   81
                                                                                         LECTURE 6

Grid Layout
 The GridLayout manager resizes the components so that they are all equal in size, and then
 displays the components in the requested number of rows and columns, e.g.:
 A GridLayout can be employed as follows:

                     contentPane.setLayout(new GridLayout(2,2));

 Components are added in a left to right fashion, filling each row before moving onto the next

Grid Bag Layout
 This is the most sophisticated layout manager, permitting a grid to be formed (a number of rows
 and columns), inside which components can be aligned and permitted to span more than one cell:
                                                 The GridBagLayout class requires that a
                                                 corresponding GridBagConstraints object be
                                                 created, defining how components are to be
                                                 placed within the container. Further details can
                                                 be found on Sun’s Java site.

Absolute Positioning
 The examples above made use of the setLayout method to change the layout
 manager used within a container. Should a null value be passed to the
 setLayout method then no layer manager will be used within the container.
 Instead, absolute positioning is assumed.
 Absolute positioning simply entails that the programmer specifies the size
 and position of a component when it is added to the container (i.e. as no layout manager is being
 used, the programmer must determine where components are placed).
 In general, layout managers should be used whenever possible (as they adapt to
 changing font sizes, window resizes, etc.). Absolute positioning is only really
 suited to those instances where the container will not be resized, nor will any of
 the components within the container change (Note, as will be seen later, due to
 the fact layout managers are presently incomplete, the use of absolute
 positioning is widespread).
 A code example follows:       Container contentPane = getContentPane();

                               b1 = new JButton("one");

                               b1.setBounds( 25, 5, 75, 20);

                                                   PAGE   82
                                                                                       LECTURE 6

Combining Layout Managers
 The real power of using layout managers arises when they are combined together. Consider the
 following GUI:

 Which can be constructed as follows:
                      JFrame object using FlowLayout and containing two
                      JPanel objects

                 JPanel using GridLayout, containing           JPanel using BorderLayout,
                 3 JCheckBox objects                           containing a JTextArea and a JButton

 In the above, a number of different layout managers and containers have been employed to
 produce the desired arrangement.

Providing hints about a component’s size
 Sometimes it is necessary to provide ‘hints’ to the layout manager as to how components should
 be set out (to ensure the desired arrangement is formed). Java provides a number of methods
 towards accomplishing this, namely:

 •  setMinimumSize, setPreferredSize, and setMaximumSize can be used to specify the
    component’s minimum, preferred and maximum size.
 • setAlignmentX and setAlignmentY methods can be used to control where the component
    should be located.
 Note, presently, only the BoxLayout manager pays any attention to alignment hints.

Practical 6

 After this lecture you should explore the sixth practical pack which should enable you to
 investigate the material in this lecture.

                                                 PAGE   83
                                                                                      LECTURE 6

Learning Outcomes

 Once you have explored and reflected upon the material presented within this lecture and the
 practical pack, you should:

     •   Have knowledge of Java’s container class hierarchy, including the
         functionality offered by each Swing container and the roles for which
         individual Swing container are particularly suited.

     •   Be capable of writing Java code that makes appropriate use of Swing containers
         given a straightforward GUI problem description.

     •   Have knowledge of the different layout managers on offer within Java, including
         an understanding of how they may be appropriately used to layout components.

     •   Be capable of writing Java code that successfully arranges components given a
         straightforward component layout design.
 More comprehensive details can be found in the CSC735 Learning Outcomes document.

                                                 PAGE   84

To top