TreeTableCellEditor.java
上传用户:zhengdagz
上传日期:2014-03-06
资源大小:1956k
文件大小:7k
源码类别:

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: TreeTableCellEditor.java,v 1.5 2005/10/13 08:59:59 kleopatra Exp $
  3.  *
  4.  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
  5.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  */
  21. package org.jdesktop.swingx.treetable;
  22. import java.util.EventObject;
  23. import java.awt.Component;
  24. import java.awt.Rectangle;
  25. import java.awt.event.MouseEvent;
  26. import javax.swing.DefaultCellEditor;
  27. import javax.swing.Icon;
  28. import javax.swing.JTable;
  29. import javax.swing.JTextField;
  30. import javax.swing.JTree;
  31. import javax.swing.tree.DefaultTreeCellRenderer;
  32. import javax.swing.tree.TreeCellRenderer;
  33. /**
  34.  * An editor that can be used to edit the tree column. This extends
  35.  * DefaultCellEditor and uses a JTextField (actually, TreeTableTextField)
  36.  * to perform the actual editing.
  37.  * <p>To support editing of the tree column we can not make the tree
  38.  * editable. The reason this doesn't work is that you can not use
  39.  * the same component for editing and renderering. The table may have
  40.  * the need to paint cells, while a cell is being edited. If the same
  41.  * component were used for the rendering and editing the component would
  42.  * be moved around, and the contents would change. When editing, this
  43.  * is undesirable, the contents of the text field must stay the same,
  44.  * including the caret blinking, and selections persisting. For this
  45.  * reason the editing is done via a TableCellEditor.
  46.  * <p>Another interesting thing to be aware of is how tree positions
  47.  * its render and editor. The render/editor is responsible for drawing the
  48.  * icon indicating the type of node (leaf, branch...). The tree is
  49.  * responsible for drawing any other indicators, perhaps an additional
  50.  * +/- sign, or lines connecting the various nodes. So, the renderer
  51.  * is positioned based on depth. On the other hand, table always makes
  52.  * its editor fill the contents of the cell. To get the allusion
  53.  * that the table cell editor is part of the tree, we don't want the
  54.  * table cell editor to fill the cell bounds. We want it to be placed
  55.  * in the same manner as tree places it editor, and have table message
  56.  * the tree to paint any decorations the tree wants. Then, we would
  57.  * only have to worry about the editing part. The approach taken
  58.  * here is to determine where tree would place the editor, and to override
  59.  * the <code>reshape</code> method in the JTextField component to
  60.  * nudge the textfield to the location tree would place it. Since
  61.  * JXTreeTable will paint the tree behind the editor everything should
  62.  * just work. So, that is what we are doing here. Determining of
  63.  * the icon position will only work if the TreeCellRenderer is
  64.  * an instance of DefaultTreeCellRenderer. If you need custom
  65.  * TreeCellRenderers, that don't descend from DefaultTreeCellRenderer,
  66.  * and you want to support editing in JXTreeTable, you will have
  67.  * to do something similiar.
  68.  *
  69.  * @author Scott Violet
  70.  * @author Ramesh Gupta
  71.  */
  72. public class TreeTableCellEditor extends DefaultCellEditor {
  73.     public TreeTableCellEditor(JTree tree) {
  74.         super(new TreeTableTextField());
  75.         if (tree == null) {
  76.             throw new IllegalArgumentException("null tree");
  77.         }
  78.         this.tree = tree; // immutable
  79.     }
  80.     /**
  81.      * Overriden to determine an offset that tree would place the
  82.      * editor at. The offset is determined from the
  83.      * <code>getRowBounds</code> JTree method, and additionaly
  84.      * from the icon DefaultTreeCellRenderer will use.
  85.      * <p>The offset is then set on the TreeTableTextField component
  86.      * created in the constructor, and returned.
  87.      */
  88.     public Component getTableCellEditorComponent(JTable table, Object value,
  89.                                                  boolean isSelected, int row,
  90.                                                  int column) {
  91.         Component component = super.getTableCellEditorComponent(table, value,
  92.             isSelected, row, column);
  93.         Rectangle bounds = tree.getRowBounds(row);
  94.         int offset = bounds.x;
  95.         TreeCellRenderer tcr = tree.getCellRenderer();
  96.         if (tcr instanceof DefaultTreeCellRenderer) {
  97.             Object node = tree.getPathForRow(row).getLastPathComponent();
  98.             Icon icon;
  99.             if (tree.getModel().isLeaf(node))
  100.                 icon = ((DefaultTreeCellRenderer) tcr).getLeafIcon();
  101.             else if (tree.isExpanded(row))
  102.                 icon = ((DefaultTreeCellRenderer) tcr).getOpenIcon();
  103.             else
  104.                 icon = ((DefaultTreeCellRenderer) tcr).getClosedIcon();
  105.             if (icon != null) {
  106.                 offset += ((DefaultTreeCellRenderer) tcr).getIconTextGap() +
  107.                     icon.getIconWidth();
  108.             }
  109.         }
  110.         ((TreeTableTextField) getComponent()).offset = offset;
  111.         return component;
  112.     }
  113.     /**
  114.      * This is overriden to forward the event to the tree. This will
  115.      * return true if the click count >= clickCountToStart, or the event is null.
  116.      */
  117.     public boolean isCellEditable(EventObject e) {
  118.         if (e == null) {
  119.             return true;
  120.         }
  121.         else if (e instanceof MouseEvent) {
  122.             return (((MouseEvent) e).getClickCount() >= clickCountToStart);
  123.         }
  124. // e is some other type of event...
  125.         return false;
  126.     }
  127.     /**
  128.      * Component used by TreeTableCellEditor. The only thing this does
  129.      * is to override the <code>reshape</code> method, and to ALWAYS
  130.      * make the x location be <code>offset</code>.
  131.      */
  132.     static class TreeTableTextField extends JTextField {
  133.         int offset; // changed to package private instead of public
  134.         public void reshape(int x, int y, int width, int height) {
  135.             // Allows precise positioning of text field in the tree cell.
  136.             //Border border = this.getBorder(); // get this text field's border
  137.             //Insets insets = border == null ? null : border.getBorderInsets(this);
  138.             //int newOffset = offset - (insets == null ? 0 : insets.left);
  139.             int newOffset = offset - getInsets().left;
  140.             super.reshape(x + newOffset, y, width - newOffset, height);
  141.         }
  142.     }
  143.     private final JTree tree; // immutable
  144. }