import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;

/** PC_SizeProperties - programming challenge on size properties<p>
*
* <b>Programming Challenge</b><br>
* Rework <code>DemoSizeProperties</code> to display the
* size properties in a <code>JTable</code> rather than outputting them
* to the console.  Include columns for the component's name, class,
* preferred size, minimum size, and maximum size.
* Name the program <code>PC_SizeProperties.java</code>.<p>
*
* Screen snap...<br>
* <center><img src="PC_SizeProperties-1.gif"></center><p>
*
* @see <a href="PC_SizeProperties.java">source code</a>
* @author Scott MacKenzie, 2002
*/
public class PC_SizeProperties
{
   public static void main(String[] args)
   {
      // use look and feel for my system (Win32)
      try {
         UIManager.setLookAndFeel(
            UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {}

      PC_SizePropertiesFrame frame = new PC_SizePropertiesFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setTitle("PC_SizeProperties");
      frame.pack();
      frame.show();
   }
}

class PC_SizePropertiesFrame extends JFrame
{
   public PC_SizePropertiesFrame()
   {
      // ----------------------------------
      // construct and configure components
      // ----------------------------------

      JButton b1 = new JButton("Button One");
      JButton b2 = new JButton("B2");
      JLabel label = new JLabel("Hello");
      JTextField tf1 = new JTextField();
      JTextField tf2 = new JTextField("Hello");
      JTextField tf3 = new JTextField("Hello", 10);
      JTextArea ta = new JTextArea(5, 10);
      JPanel panel = new JPanel();

      b1.setName("b1");
      b2.setName("b2");
      label.setName("label");
      tf1.setName("tf1");
      tf2.setName("tf2");
      tf3.setName("tf3");
      ta.setName("ta");
      panel.setName("panel");

      // put components in panel

      panel.add(b1);
      panel.add(b2);
      panel.add(label);
      panel.add(tf1);
      panel.add(tf2);
      panel.add(tf3);
      panel.add(ta); 

      // build a vector containing column names

      Vector columnNames = new Vector();
      columnNames.add("Component");
      columnNames.add("Class");
      columnNames.add("Preferred Size");
      columnNames.add("Minimum Size");
      columnNames.add("Maximum Size");

      // build a vector containing row data

      Vector rowData = new Vector();
      Vector tmp;
      Dimension d;

      JComponent[] c = { b1, b2, label, tf1, tf2, tf3, ta, panel };

      for (int i = 0; i < c.length; ++i)
      {
         tmp = new Vector();

         tmp.add(c[i].getName());

         String s = c[i].getClass().getName();
         tmp.add(s.substring("javax.swing.".length()));

         d = c[i].getPreferredSize();
         tmp.add(d.width + " x " + d.height);

         d = c[i].getMinimumSize();
         tmp.add(d.width + " x " + d.height);

         d = c[i].getMaximumSize();
         tmp.add(d.width + " x " + d.height);

         rowData.add(tmp);
      }

      // construct and configure the table

      CustomTableModel dataModel = new CustomTableModel(rowData, columnNames);
      JTable t = new JTable(dataModel);
      t.setPreferredScrollableViewportSize(t.getPreferredSize());
      JScrollPane sp = new JScrollPane(t);

      // put demo components and table/scrollpane component in a panel

      JPanel p = new JPanel(new BorderLayout());
      p.add(panel, "North");
      p.add(sp, "Center");   

      // make panel this JFrame's content pane

      this.setContentPane(p);
   }

   // -----------
   // inner class
   // -----------

   class CustomTableModel extends AbstractTableModel
   {
      Vector rowData, columnNames;

      public CustomTableModel(Vector rowData, Vector columnNames)
      {
         this.rowData = rowData;
         this.columnNames = columnNames;
      }

      public int getColumnCount()
      {
         return columnNames.size();
      }

      public int getRowCount()
      {
         return rowData.size();
      }

      public boolean isCellEditable(int row, int col)
      {
         return true;
      }

      public String getColumnName(int idx)
      {
         return (String)columnNames.elementAt(idx);
      }

      public Object getValueAt(int row, int col)
      {
         return ((Vector)rowData.elementAt(row)).elementAt(col);
      }

      public void setValueAt(Object value, int row, int col)
      {
         ((Vector)rowData.elementAt(row)).setElementAt(value, col);
         fireTableCellUpdated(row, col);
      }
   }
}

