31.7. Table Model Events

 
[Page 938 ( continued )]

28.4. Creating Custom Layout Managers

In addition to the layout managers provided in Java, you can create your own layout managers. To do so, you need to understand how a layout manager lays out components . A container's setLayout method specifies a layout manager for the container. The layout manager is responsible for laying out the components and displaying them in a desired location with an appropriate size . Every layout manager must directly or indirectly implement the LayoutManager interface. For instance, FlowLayout directly implements LayoutManager , and BorderLayout implements LayoutManager2 , a subclass of LayoutManager . The LayoutManager interface provides the following methods for laying out components in a container:

  •    public void   addLayoutComponent(String name , Component comp) 

    Adds the specified component with the specified name to the container.

  •    public void   layoutContainer(Container parent) 

    Lays out the components in the specified container. In this method, you should provide concrete instructions that specify where the components are to be placed.

  •    public   Dimension minimumLayoutSize(Container parent) 

    Calculates the minimum size dimensions for the specified panel, given the components in the specified parent container.


    [Page 939]
  •    public   Dimension preferredLayoutSize(Container parent) 

    Calculates the preferred size dimensions for the specified panel, given the components in the specified parent container.

  •    public void   removeLayoutComponent(Component comp) 

    Removes the specified component from the layout.

These methods in LayoutManager are invoked by the methods in the java.awt.Container class through the layout manager in the container. Container contains a property named layout (an instance of LayoutManager ) and the methods for adding and removing components from the container. There are five overloading add methods defined in Container for adding components with various options. The remove method removes a component from the container. The add method invokes addImpl , which then invokes the addLayoutComponent method defined in the LayoutManager interface. The layoutContainer method in the LayoutManager interface is indirectly invoked by validate through several calls. The remove method invokes removeLayoutComponent in LayoutManager . The validate method is invoked to refresh the container after the components it contains have been added to or modified. The relationship of Container and LayoutManager is shown in Figure 28.14.

Figure 28.14. The add , remove , and validate methods in Container invoke the methods defined in the LayoutManager interface.


Let us declare a custom layout manager named DiagonalLayout that places the components in a diagonal. To test DiagonalLayout , the example creates an applet with radio buttons named "FlowLayout," "GridLayout," and "DiagonalLayout," as shown in Figure 28.15. You can dynamically select one of these three layouts in the panel.

Figure 28.15. The DiagonalLayout manager places the components in a diagonal in the container.



[Page 940]

The DiagonalLayout class is similar to FlowLayout . DiagonalLayout arranges components along a diagonal using each component's natural preferredSize . It contains three constraints, gap , lastFill , and majorDiagonal , as shown in Figure 28.16. The source code for DiagonalLayout is given in Listing 28.7.

Figure 28.16. The DiagonalLayout manager has three properties with the supporting accessor and mutator methods.

Listing 28.7. DiagonalLayout.java
(This item is displayed on pages 940 - 942 in the print version)
 1   import   java.awt.*; 2 3   public      class   DiagonalLayout   implements   LayoutManager,  4  java.io.Serializable  { 5  /** Vertical gap between the components */  6   private int   gap =   10   ; 7 8  /** True if components are placed along the major diagonal */  9   private boolean   majorDiagonal =   true   ; 10 11  /* True if the last component is stretched to fill the space */  12   private boolean   lastFill =   false   ; 13 14  /** Constructor */  15   public   DiagonalLayout() { 16 } 17 18   public void   addLayoutComponent(String name, Component comp) { 19  // TODO: implement this java.awt.LayoutManager method  20 } 21 22   public void   removeLayoutComponent(Component comp) { 23  // TODO: implement this java.awt.LayoutManager method  24 } 25 26   public   Dimension preferredLayoutSize(Container parent) { 27  // TODO: implement this java.awt.LayoutManager method  28   return   minimumLayoutSize(parent); 29 } 30 31   public   Dimension minimumLayoutSize(Container parent) { 32  // TODO: implement this java.awt.LayoutManager method;  

[Page 941]
 33   return new   Dimension(     ,     ); 34 } 35 36    public void   layoutContainer(Container parent)  { 37  // TODO: implement this java.awt.LayoutManager method;  38   int   numberOfComponents = parent.getComponentCount(); 39 40 Insets insets = parent.getInsets(); 41   int   w = parent.getSize().width - insets.left - insets.right; 42   int   h = parent.getSize().height - insets.bottom - insets.top; 43 44   if   (majorDiagonal) { 45   int   x =   10   , y =   10   ; 46 47   for   (   int   j =     ; j < numberOfComponents; j++) { 48 Component c = parent.getComponent(j); 49 Dimension d = c.getPreferredSize(); 50 51   if   (c.isVisible()) 52   if   (lastFill && (j == numberOfComponents -   1   )) 53 c.setBounds(x, y, w - x, h - y); 54   else   55 c.setBounds(x, y, d.width, d.height); 56 x += d.height + gap; 57 y += d.height + gap; 58 } 59 } 60   else   {  // It is subdiagonal  61   int   x = w -   10   , y =   10   ; 62 63   for   (   int   j =     ; j < numberOfComponents; j++) { 64 Component c = parent.getComponent(j); 65 Dimension d = c.getPreferredSize(); 66 67   if   (c.isVisible()) 68   if   (lastFill & (j == numberOfComponents -   1   )) 69 c.setBounds(     , y, x, h - y); 70   else   71 c.setBounds(x, d.width, y, d.height); 72 73 x -= (d.height + gap); 74 y += d.height + gap; 75 } 76 } 77 } 78 79   public int   getGap() { 80   return   gap; 81 } 82 83   public void   setGap(   int   gap) { 84   this   .gap = gap; 85 } 86 87   public void   setMajorDiagonal(   boolean   newMajorDiagonal) { 88 majorDiagonal = newMajorDiagonal; 89 } 90 91   public boolean   isMajorDiagonal() { 92   return   majorDiagonal; 

[Page 942]
 93 } 94 95   public void   setLastFill(   boolean   newLastFill) { 96 lastFill = newLastFill; 97 } 98 99   public boolean   isLastFill() { 100   return   lastFill; 101 } 102 } 

The DiagonalLayout class implements the LayoutManger and Serializable interfaces (lines 3 “4). The reason to implement Serializable is to make it a JavaBeans component.

The Insets class describes the size of the borders of a container. It contains the variables left , right , bottom , and top , which correspond to the measurements for the left border , right border , top border , and bottom border (lines 40 “42).

The Dimension class used in DiagonalLayout encapsulates the width and height of a component in a single object. The class is associated with certain properties of components. Several methods defined by the Component class and the LayoutManager interface return a Dimension object.

Listing 28.8 gives a test program that uses DiagonalLayout .

Listing 28.8. ShowDiagonalLayout.java
(This item is displayed on pages 942 - 943 in the print version)
 1   import   javax.swing.*; 2   import   javax.swing.border.*; 3   import   java.awt.*; 4   import   java.awt.event.*; 5 6   public class   ShowDiagonalLayout   extends   JApplet { 7   private   FlowLayout flowLayout =   new   FlowLayout(); 8   private   GridLayout gridLayout =   new   GridLayout(   2   ,   2   ); 9    private   DiagonalLayout diagonalLayout =   new   DiagonalLayout();  10 11   private   JButton jbt1 =   new   JButton(   "Button 1"   ); 12   private   JButton jbt2 =   new   JButton(   "Button 2"   ); 13   private   JButton jbt3 =   new   JButton(   "Button 3"   ); 14   private   JButton jbt4 =   new   JButton(   "Button 4"   ); 15 16   private   JRadioButton jrbFlowLayout = 17   new   JRadioButton(   "FlowLayout"   ); 18   private   JRadioButton jrbGridLayout = 19   new   JRadioButton(   "GridLayout"   ); 20   private   JRadioButton jrbDiagonalLayout = 21   new   JRadioButton(   "DiagonalLayout"   ,   true   ); 22 23   private   JPanel jPanel2 =   new   JPanel(); 24 25   public   ShowDiagonalLayout() { 26  // Set default layout in jPanel2  27  jPanel2.setLayout(diagonalLayout);  28 jPanel2.add(jbt1); 29 jPanel2.add(jbt2); 30 jPanel2.add(jbt3); 31 jPanel2.add(jbt4); 32 jPanel2.setBorder(   new   LineBorder(Color.black)); 

[Page 943]
 33 34 JPanel jPanel1 =   new   JPanel(); 35 jPanel1.setBorder(   new   TitledBorder(   "Select a Layout Manager"   )); 36 jPanel1.add(jrbFlowLayout); 37 jPanel1.add(jrbGridLayout); 38 jPanel1.add(jrbDiagonalLayout); 39 40 ButtonGroup buttonGroup1 =   new   ButtonGroup(); 41 buttonGroup1.add(jrbFlowLayout); 42 buttonGroup1.add(jrbGridLayout); 43 buttonGroup1.add(jrbDiagonalLayout); 44 45 add(jPanel1, BorderLayout.SOUTH); 46 add(jPanel2, BorderLayout.CENTER); 47 48  jrbFlowLayout.addActionListener(  new  ActionListener() {  49   public void   actionPerformed(ActionEvent e) { 50 jPanel2.setLayout(flowLayout); 51 jPanel2.validate(); 52 } 53 }); 54  jrbGridLayout.addActionListener(  new  ActionListener() {  55   public void   actionPerformed(ActionEvent e) { 56 jPanel2.setLayout(gridLayout); 57 jPanel2.validate(); 58 } 59 }); 60  jrbDiagonalLayout.addActionListener(  new  ActionListener() {  61   public void   actionPerformed(ActionEvent e) { 62 jPanel2.setLayout(diagonalLayout); 63 jPanel2.validate(); 64 } 65 }); 66 } 67 } 

The TestDiagonalLayout class enables you to dynamically set the layout in jPanel2 . When you select a new layout, the layout manager is set in jPanel2 , and the validate() method is invoked (lines 51, 57, 63), which in turn invokes the layoutContainer method in the LayoutManager interface to display the components in the container.

 


Introduction to Java Programming-Comprehensive Version
Introduction to Java Programming-Comprehensive Version (6th Edition)
ISBN: B000ONFLUM
EAN: N/A
Year: 2004
Pages: 503

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net