package de.javasoft.synthetica.democenter.examples.jycombobox;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.DefaultMutableTreeNode;

import de.javasoft.swing.JYComboBox;

/**
 * TreeComboBox demo application.  
 */
@SuppressWarnings("serial")
public class TreeComboBox extends JFrame
{
  private JYComboBox combo;  
  
  public TreeComboBox()
  {
    super("TreeComboBox Demo");
    setLayout(new FlowLayout());
    
//@highlight
    combo = new JYComboBox();
    // specify initial comboBox width
    combo.setPreferredSize(new Dimension(200, combo.getPreferredSize().height));
    combo.setPopupComponent(new TreePopup(combo));
    combo.setPopupResizable(true);
    // set initial popup size
    combo.setPopupWidth(250);
    combo.setPopupHeight(200);
//@/highlight

    add(new JLabel("TreeComboBox"));
    add(combo);
    ((JComponent)getContentPane()).setBorder(new EmptyBorder(10,10,10,10));

    //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setSize(450, 250);
    setLocationRelativeTo(null);        //center
    setVisible(true);
  }

  //
  // Popup Component Class 
  //  
  public class TreePopup extends JTree implements MouseListener, MouseMotionListener
  {
    private JYComboBox combo;
    
    public TreePopup(JYComboBox combo)
    {
      super();
      this.combo = combo;
      //setRootVisible(false);

      //expand tree
      for (int i = 0; i < getRowCount(); i++)
        expandRow(i);
      setShowsRootHandles(true);
      addMouseListener(this);
      addMouseMotionListener(this);
    }
    
    //
    //MouseMotionListener Implementation - to select nodes on hover
    //
    public void mouseDragged(MouseEvent evt)
    {
    }

    public void mouseMoved(MouseEvent evt)
    {
      Point location = evt.getPoint();
      Rectangle r = new Rectangle();
      computeVisibleRect(r);
      if (r.contains(location)) 
      {
        int index = getClosestRowForLocation(evt.getX(), evt.getY());
        if (index == -1 ) 
          index = evt.getY() < 0 ? 0 : getRowCount() - 1;
        int[] selections = getSelectionRows();
        if (selections == null || selections.length == 0 || selections[0] != index ) 
          setSelectionInterval(index, index);
      }      
    }

    //
    //MouseListener Implementation - sets selected comboBox item
    //
    public void mouseClicked(MouseEvent evt)
    {
    }

    public void mousePressed(MouseEvent evt)
    {
    }

    public void mouseReleased(MouseEvent evt)
    {
      if (getSelectionPath() == null)
        return;      
      DefaultMutableTreeNode node = (DefaultMutableTreeNode) getSelectionPath().getLastPathComponent();
      if (node.isLeaf())
      {  
//@highlight
        //return selected item
        combo.setItem(node.getUserObject());
        combo.closePopup();
//@/highlight
      }  
    }

    public void mouseEntered(MouseEvent evt)
    {
    }

    public void mouseExited(MouseEvent evt)
    {
    }
 }
  
  /**
   * Static main method for application startup. 
   */
  public static void main(String[] args)
  {
    EventQueue.invokeLater(new Runnable()
    {
      public void run()
      {
        try
        {
          UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaStandardLookAndFeel");
          new TreeComboBox();
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
    });
  }  
}
