import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;

/** DemoTree2 - same as <code>DemoTree</code> except using radio
* buttons to change the look and feel.<p>
*
* Screen snap (Metal)...<br>
* <center><img src="DemoTree2-1.gif"></center><p>
*
* Screen snap (CDE/Motif)...<br>
* <center><img src="DemoTree2-2.gif"></center><p>
*
* Screen snap (Windows)...<br>
* <center><img src="DemoTree2-3.gif"></center><p>
*
* @see <a href="DemoTree2.java">source code</a>
* @author Scott MacKenzie, 2002
*/
public class DemoTree2
{
   public static void main(String[] args)
   {
      // use look and feel for my system (Win32)
      try {
         UIManager.setLookAndFeel(
            UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {}

      DemoTree2Frame frame = new DemoTree2Frame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setTitle("DemoTree2");
      frame.pack();
      frame.show();
   }
}

class DemoTree2Frame extends JFrame
implements TreeSelectionListener, ActionListener
{
   private JTree t;

   private JRadioButton[] rb;
   private UIManager.LookAndFeelInfo[] laf;

   public DemoTree2Frame()
   {
      final String[] CATEGORIES = {
         "Letters",
         "Digits",
         "Punctuation"
      };

      final String[] SYMBOLS = {
         "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
         "0123456789",
         "~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./"
      };

      // ----------------------------------
      // construct and configure components
      // ----------------------------------    

      // First, let's work on the L&F buttons...

      laf = UIManager.getInstalledLookAndFeels();
      
      try
      {
         UIManager.setLookAndFeel(laf[0].getClassName());
      } catch (Exception e)
      {
         System.out.println(e);
      }

      rb = new JRadioButton[laf.length];
      ButtonGroup bg = new ButtonGroup();
      for (int i = 0; i < rb.length; ++i)
      {
         rb[i] = new JRadioButton(laf[i].getName());
         rb[i].setActionCommand("" + i);
         rb[i].addActionListener(this);
         bg.add(rb[i]);
      }
      rb[0].setSelected(true);

      // Now let's build the tree structure...

      DefaultMutableTreeNode top = new DefaultMutableTreeNode("Symbols");
      DefaultMutableTreeNode node;
      Character nodeSymbol;

      for (int i = 0; i < CATEGORIES.length; ++i)
      {
         top.add(new DefaultMutableTreeNode(CATEGORIES[i]));
         for (int j = 0; j < SYMBOLS[i].length(); ++j)
         {
            node = (DefaultMutableTreeNode)(top.getChildAt(i));
            nodeSymbol = new Character(SYMBOLS[i].charAt(j));
            node.add(new DefaultMutableTreeNode(nodeSymbol));
         }
      }

      // Create a JTree object, passing the data model as an argument
      // to the constructor.  (Note: The data model is represented
      // by the node at the top of the tree hierarchy.)

      t = new JTree(top);

      // Set the selection mode to "single" (only one node can be
      // selected at a time).

      TreeSelectionModel tsm = t.getSelectionModel();
      tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

      // put the tree in a scroll pane to facilitate viewing

      JScrollPane sp = new JScrollPane(t);
      sp.setPreferredSize(new Dimension(150, 250));

      // -------------
      // add listeners
      // -------------

      t.addTreeSelectionListener(this);

      // ------------------
      // arrange components
      // ------------------

      JPanel p1 = new JPanel();
      p1.setLayout(new BoxLayout(p1, BoxLayout.Y_AXIS));
      p1.add(new JLabel("Select Desired Look and Feel"));
      for (int i = 0; i < rb.length; ++i)
         p1.add(rb[i]);
      p1.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));       

      JPanel p = new JPanel(new BorderLayout(5, 0));
      p.add(sp, "West");
      p.add(p1, "East");
      p.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

      this.setContentPane(p);
   }

   // --------------------------------------
   // implement TreeSelectionListener method
   // --------------------------------------

   public void valueChanged(TreeSelectionEvent tse)
   {
      // get the node that was selected
      DefaultMutableTreeNode node =
         (DefaultMutableTreeNode)t.getLastSelectedPathComponent();

      // Note: Exiting on "node == null" has been added below, because
      // changing the L&F generates a TreeSelectionEvent
      // if a node is selected.  The getLastSelectedPathComponent
      // returns null in this case.

      // for this demo, we're only interested in leaf nodes
      if (node == null || !node.isLeaf())
         return;

      // get the symbol associated with the node and print it
      Object o = node.getUserObject();
      System.out.print(o);
   }

   // -------------------------------
   // implement ActionListener method
   // -------------------------------

   public void actionPerformed(ActionEvent ae)
   {
      JRadioButton b = (JRadioButton)ae.getSource();
      int idx = Integer.parseInt(b.getActionCommand());
      try
      {
         UIManager.setLookAndFeel(laf[idx].getClassName());
      } catch (Exception e)
      {
         System.out.println(e);
      }
      SwingUtilities.updateComponentTreeUI(this); 
   }
}

