import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

/** DemoSizeControl - program to demonstrate size control during layout.<p>
*
* Usage:<p>
*
* <pre>
*     java DemoSizeControl arg1
*
*     where 'arg1' specifies the layout manager as follows:
*        1 = BorderLayout
*        2 = FlowLayout
*        3 = GridLayout
*        4 = BoxLayout
* </pre>
*
* Four buttons are instantiated with embedded labels.  Although each
* button assumes a preferred size, minimum size, and maximum size
* property, we can overrided these by explicitly setting the property.
* This is done
* using the <code>setPreferredSize</code>, <code>setMinimumSize</code>,
* or <code>setMaximumSize</code> methods of the <code>JComponent</code>
* class.<p>
*
* Button 3 has
* its maximum size set to the preferred size of button 1:<p>
*
* <pre>
*     b3.setMaximumSize(b1.getPreferredSize());
* </pre>
*
* Button 4 has its preferred size and maximum size set to hard-coded values:<p>
*
* <pre>
*     b4.setPreferredSize(new Dimension(150, 50));
*     b4.setMaximumSize(new Dimension(150, 50));
* </pre>
*
* The program prints the size propertes on the console, shown as follows:<p>
*
*
*<pre>
*     b1 preferred size: 95 x 27
*     b1 minimum size:   95 x 27
*     b1 maximum size:   95 x 27
*     b1 properties explicitly set: false false false
*     -----
*     b2 preferred size: 49 x 27
*     b2 minimum size:   49 x 27
*     b2 maximum size:   49 x 27
*     b2 properties explicitly set: false false false
*     -----
*     b3 preferred size: 49 x 27
*     b3 minimum size:   49 x 27
*     b3 maximum size:   95 x 27
*     b3 properties explicitly set: false false true
*     -----
*     b4 preferred size: 150 x 50
*     b4 minimum size:   49 x 27
*     b4 maximum size:   150 x 50
*     b4 properties explicitly set: true false true
*     -----
*     panel preferred size: 150 x 104
*     panel minimum size:   98 x 81
*     panel maximum size:   2147483647 x 2147483647
*     panel properties explicitly set: false false false
*     -----
* </pre>
*
* The three booleans at the end of each group indicate if a
* <code><i>set...Size</i></code> method was used to explicitly set the preferred,
* minimum, or maximum size property, respectively.
* Retrieving this information is simply a matter of invoking a
* <code><i>is...SizeSet</i></code> method on the component.
* If <code>true</code> is returned, the property held by the component
* is that explicitly set by the program.
* If <code>false</code> is returned, the property
* held is that given to, or assumed by,
* the component when it was instantiated.
* As seen, <code>b3</code>
* has its maximum size property explicilty
* set and <code>b4</code>
* has its preferred and maximum size properties explicitly set.  All other
* size properties are assumed.<p>
*
* Given that each button has size properties which are either explicitly
* or implicitly set, we then invesitigate how the various layout managers
* use these properties during component layout or when a container
* (e.g., the application window) is resized.  To faciliate the comparisons,
* this demo uses a 
* command-line argument to determine the layout manager
* (see "usage" above):<p>
*
* Using <code>BorderLayout</code>...<br>
* <center><img src="DemoSizeControl-1.gif"></center><p>
*
* Using <code>FlowLayout</code>...<br>
* <center><img src="DemoSizeControl-2.gif"></center><p>
*
* Using <code>GridLayout</code>...<br>
* <center><img src="DemoSizeControl-3.gif"></center><p>
*
* Using <code>BoxLayout</code>...<br>
* <center><img src="DemoSizeControl-4.gif"></center><p>
*
* Using <code>BoxLayout</code> (resized)...<br>
* <center><img src="DemoSizeControl-5.gif"></center><p>
*
* @see <a href="DemoSizeControl.java">source code</a>
* @author Scott MacKenzie, 2002
*/
public class DemoSizeControl
{
   public static void main(String[] args)
   {
      if (args.length != 1)
      {
         usage();
         return;
      }

      int layout = Integer.parseInt(args[0]);

      // use look and feel for my system (Win32)
      try {
         UIManager.setLookAndFeel(
            UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {}

      DemoSizeControlFrame frame = new DemoSizeControlFrame(layout);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setTitle("DemoSizeControl");
      frame.pack();
      frame.show();
   }

   public static void usage()
   {
      System.out.println(
         "usage: java DemoSizeControl arg1\n\n" +
         "where 'arg1' specifies the layout manager as follows:\n" +
         "   1 = BorderLayout\n" +
         "   2 = FlowLayout\n" +
         "   3 = GridLayout\n" +
         "   4 = BoxLayout\n"
      );
      return;
   }
}

class DemoSizeControlFrame extends JFrame
{
   final int BORDER_LAYOUT = 1;
   final int FLOW_LAYOUT = 2;
   final int GRID_LAYOUT = 3;
   final int BOX_LAYOUT = 4;

   public DemoSizeControlFrame(int layoutArg)
   {
      // ----------------------------------
      // construct and configure components
      // ----------------------------------

      JButton b1 = new JButton("Button One");
      JButton b2 = new JButton("B2");
      JButton b3 = new JButton("B3");
      JButton b4 = new JButton("B4");

      b1.setName("b1");
      b2.setName("b2");
      b3.setName("b3");
      b4.setName("b4");

      // set a few of the size properties, just for the demo

      b3.setMaximumSize(b1.getPreferredSize());
      b4.setPreferredSize(new Dimension(150, 50));
      b4.setMaximumSize(new Dimension(150, 50));

      // -----------------
      // layout components
      // -----------------

      JPanel panel = new JPanel();
      panel.setName("panel");

      if (layoutArg == BORDER_LAYOUT)
      {
         panel.setLayout(new BorderLayout());
         panel.add(b1, "North");
         panel.add(b2, "West");
         panel.add(b3, "East");
         panel.add(b4, "South");
      }
      else if (layoutArg == FLOW_LAYOUT)
      {
         panel.setLayout(new FlowLayout(FlowLayout.LEFT));
         panel.add(b1);
         panel.add(b2);
         panel.add(b3);
         panel.add(b4);
      }
      else if (layoutArg == GRID_LAYOUT)
      {
         panel.setLayout(new GridLayout(1, 4));
         panel.add(b1);
         panel.add(b2);
         panel.add(b3);
         panel.add(b4);
      }
      else if (layoutArg == BOX_LAYOUT)
      {
         panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
         panel.add(b1);
         panel.add(b2);
         panel.add(b3);
         panel.add(b4);
      }
      else
      {
         System.out.println("Invalid argument");
         System.exit(0);
      }

      // make panel this JFrame's content pane

      this.setContentPane(panel);

      // print the properties on the console

      JComponent[] c = { b1, b2, b3, b4, panel };
      dumpSizeProperties(c); 
   }

   private void dumpSizeProperties(JComponent[] c)
   {
      for (int i = 0; i < c.length; ++i)
      {
   
         String name = c[i].getName();
         Dimension d1 = c[i].getPreferredSize();
         Dimension d2 = c[i].getMinimumSize();
         Dimension d3 = c[i].getMaximumSize();
         boolean preSet = c[i].isPreferredSizeSet();
         boolean minSet = c[i].isMinimumSizeSet();
         boolean maxSet = c[i].isMaximumSizeSet();
   
         System.out.println(
            name + " preferred size: " + d1.width + " x " + d1.height + "\n" +
            name + " minimum size:   " + d2.width + " x " + d2.height + "\n" +
            name + " maximum size:   " + d3.width + " x " + d3.height + "\n" +
            name + " properties explicitly set: " +
               preSet + " " + minSet + " " + maxSet + "\n" +
            "-----");
      }
   }

}

