package org.jcon.test;

import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

/**
 * Test JTree for custom CellEditor. java org.jcon.test.TestJTree
 *
 * Bug - Double right click to edit. Notice that left side
 * of JTextField is mispositioned. Also the last word is
 * always selected, regardless of where clicked. Also we
 * need the field to grow as the text becomes too large.
 *
 * Bug - Edit a node and then press ENTER. Click the node
 * and notice that the object class has changed. This means
 * the UserObject has changed from Datum to String, which
 * makes JTree unusable for editing.
 *
 * NOTE - See Sun's answer at end. Not yet tried.
 *
 * @author Jack Harich
 */
public class TestJTree implements MouseListener {

//---------- Private Fields ------------------------------
private JTree  tree;
private JFrame frame = new JFrame("TestJTree");

//---------- Initialization ------------------------------
public static void main(String args[]) {
    new TestJTree().runUnitTest();
}
//---------- MouseListener Implementation ----------------
// See org.jcon.ba.tree.TreeView for cautions on use of MouseListener
public void mouseClicked(MouseEvent evt) { }
public void mousePressed(MouseEvent evt) { }

public void mouseReleased(MouseEvent evt) {
    Object object = getSelectedUserObject();
    print("class = " + object.getClass().getName());
}
public void mouseEntered(MouseEvent evt) { }
public void mouseExited(MouseEvent evt) { }

//---------- Public Methods ------------------------------
public void runUnitTest() {
    // Set Look and Feel
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch(Exception ex) {
        print("runUnitTest() - Failed to set Look and Feel");
    }
    // frame prep
    frame.setBackground(Color.lightGray);
    frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

    // JTree prep
    tree = new JTree(createRootNode(), false);
    tree.setEditable(true);
    tree.addMouseListener(this);
    frame.getContentPane().add("Center", tree);

    // Left is left of icon, right is correct,
    // No slow click to edit, right double click to edit
    // ***tree.setCellEditor(new DefaultCellEditor(new JTextField()));

    frame.setSize(360, 400);
    frame.setVisible(true);
}
//---------- Private Methods -----------------------------
public Object getSelectedUserObject() {
    TreePath path = tree.getSelectionPath();
    if (path == null) {
        return null;
    } else {
        DefaultMutableTreeNode node =
            (DefaultMutableTreeNode)
            path.getLastPathComponent();
        return node.getUserObject();
    }
}
// From the Java Tutorial with mods - Simple test data
private DefaultMutableTreeNode createRootNode() {

      DefaultMutableTreeNode top = createNode("The Java Series");
      DefaultMutableTreeNode category;
      DefaultMutableTreeNode book;

      category = createNode("Books for Java Programmers");
      top.add(category);

      //Tutorial
      book = createNode("The Java Tutorial: Object-Oriented Programming for the Internet");
      book.add(createNode("Mary Campione"));
      book.add(createNode("Kathy Walrath"));
      category.add(book);

      //Arnold/Gosling
      book = createNode("The Java Programming Language");
      book.add(createNode("Ken Arnold"));
      book.add(createNode("James Gosling"));
      category.add(book);

      //FAQ
      book = createNode("The Java FAQ");
      book.add(createNode("Jonni Kanerva"));
      category.add(book);

      //Chan/Lee
      book = createNode("The Java Class Libraries: An Annotated Reference");
      book.add(createNode("Patrick Chan"));
      book.add(createNode("Rosanna Lee"));
      category.add(book);

      //Threads
      book = createNode("Concurrent Programming in Java: Design Principles and Patterns");
      book.add(createNode("Doug Lea"));
      category.add(book);

      category = createNode("Books for Java Implementers");
      top.add(category);

      //VM
      book = createNode("The Java Virtual Machine Specification");
      book.add(createNode("Tim Lindholm"));
      book.add(createNode("Frank Yellin"));
      category.add(book);

      //Language Spec
      book = createNode("The Java Language Specification");
      book.add(createNode("James Gosling"));
      book.add(createNode("Bill Joy"));
      book.add(createNode("Guy Steele"));
      category.add(book);

      return top;
}
private DefaultMutableTreeNode createNode(String text) {
    return new DefaultMutableTreeNode(new Datum(text));
}
//--- Std
private static void print(String text) {
    System.out.println(text);
}
//========== Inner Classes ===============================
// Simulates a UserObject
class Datum {
    private String text;

    Datum(String text) {
        this.text = text;
    }
    public String toString() {
        return text;
    }

} // End inner class

} // End outer class

/**  6/9/98
Jack Harich writes:
> Scott,
>
> Thanks for the reply. I tested without setting a CellEditor but setting
> isEditabl(true). This works. Apparently the reason I did not notice it
> worked before, is with the Windows L&F the cell editor (when it first
> appears) looks _identical_ to a selected node. This, I feel is a bug.

This has been changed. For the windows l&f a black border is drawn
when editing (as windows does).

> Also note the way the UserObject is changed to a String when a cell is
> edited and ENTER is used. I've filed a bug report on this.

The DefaultTreeModel is simply setting the userObject to the value
that is being returned from the editor. And the default editor returns
a String. If you need to customize the value, you can either subclass
an editor to return the right object, or subclass DefaultTreeModel and
do the right thing in valueForPathChanged.

                -Scott Violet (sky@eng.sun.com)

  6/1/98
Hi,
  You submitted the following bug:

> The following test class illustrates the bug, in
> Swing 1.02 on Win95 with JDK 1.1.5.
>
> Double right click on a node name. Note the
> JTextField X location is wrong.

The reason you are getting this behavior is because you are using
DefaultCellEditor. The TreeCellEditor is reponsible for determing when
to start editing, and the default one will start editing on a double
click. The TreeCellEditor is also responsible for drawing the icon,
and as you noticed DefaultCellEditor does not do
this. BasicTreeCellEditor is the preferred cell editor for all this
and you should use that instead. Note that in the next release
BasicTreeCellEditor will be moved into the tree package and be called
DefaultTreeCellEditor. Also note that if you set the tree to editable
you do not have to supply an editor (unless you have a custom renderer
and require a custom editor).

> Also note that the last word is selected,
> regardless of where you clicked.
>
> Also note that the JTextField doesn't grow as the
> text entered become too large to fit, as in the
> Windows Explorer. I'll probably have to provide
> this functionality myself, but since I'd guess
> everyone needs this behavior, it should be built
> in.

Yes, this is a bug and I will file an RFE for it.
Thanks for your bug report,

                -Scott Violet (sky@eng.sun.com) */
