1241
1242 private boolean isDropLine(JTree.DropLocation loc) {
1243 return loc != null && loc.getPath() != null && loc.getChildIndex() != -1;
1244 }
1245
1246 private void paintDropLine(Graphics g) {
1247 JTree.DropLocation loc = tree.getDropLocation();
1248 if (!isDropLine(loc)) {
1249 return;
1250 }
1251
1252 Color c = UIManager.getColor("Tree.dropLineColor");
1253 if (c != null) {
1254 g.setColor(c);
1255 Rectangle rect = getDropLineRect(loc);
1256 g.fillRect(rect.x, rect.y, rect.width, rect.height);
1257 }
1258 }
1259
1260 private Rectangle getDropLineRect(JTree.DropLocation loc) {
1261 Rectangle rect = null;
1262 TreePath path = loc.getPath();
1263 int index = loc.getChildIndex();
1264 boolean ltr = leftToRight;
1265
1266 Insets insets = tree.getInsets();
1267
1268 if (tree.getRowCount() == 0) {
1269 rect = new Rectangle(insets.left,
1270 insets.top,
1271 tree.getWidth() - insets.left - insets.right,
1272 0);
1273 } else {
1274 TreeModel model = getModel();
1275 Object root = model.getRoot();
1276
1277 if (path.getLastPathComponent() == root
1278 && index >= model.getChildCount(root)) {
1279
1280 rect = tree.getRowBounds(tree.getRowCount() - 1);
1281 rect.y = rect.y + rect.height;
2116 editingComponent.setBounds(nodeBounds.x, nodeBounds.y,
2117 nodeBounds.width,
2118 nodeBounds.height);
2119 editingPath = path;
2120 if (editingComponent instanceof JComponent) {
2121 ((JComponent)editingComponent).revalidate();
2122 } else {
2123 editingComponent.validate();
2124 }
2125 editingComponent.repaint();
2126 if(cellEditor.shouldSelectCell(event)) {
2127 stopEditingInCompleteEditing = false;
2128 tree.setSelectionRow(row);
2129 stopEditingInCompleteEditing = true;
2130 }
2131
2132 Component focusedComponent = SwingUtilities2.
2133 compositeRequestFocus(editingComponent);
2134 boolean selectAll = true;
2135
2136 if(event != null && event instanceof MouseEvent) {
2137 /* Find the component that will get forwarded all the
2138 mouse events until mouseReleased. */
2139 Point componentPoint = SwingUtilities.convertPoint
2140 (tree, new Point(event.getX(), event.getY()),
2141 editingComponent);
2142
2143 /* Create an instance of BasicTreeMouseListener to handle
2144 passing the mouse/motion events to the necessary
2145 component. */
2146 // We really want similar behavior to getMouseEventTarget,
2147 // but it is package private.
2148 Component activeComponent = SwingUtilities.
2149 getDeepestComponentAt(editingComponent,
2150 componentPoint.x, componentPoint.y);
2151 if (activeComponent != null) {
2152 MouseInputHandler handler =
2153 new MouseInputHandler(tree, activeComponent,
2154 event, focusedComponent);
2155
2156 if (releaseEvent != null) {
3113 removeFromSource();
3114 }
3115
3116 protected void removeFromSource() {
3117 if(source != null) {
3118 source.removeMouseListener(this);
3119 source.removeMouseMotionListener(this);
3120 if (focusComponent != null &&
3121 focusComponent == destination && !dispatchedEvent &&
3122 (focusComponent instanceof JTextField)) {
3123 ((JTextField)focusComponent).selectAll();
3124 }
3125 }
3126 source = destination = null;
3127 }
3128
3129 } // End of class BasicTreeUI.MouseInputHandler
3130
3131 private static final TransferHandler defaultTransferHandler = new TreeTransferHandler();
3132
3133 static class TreeTransferHandler extends TransferHandler implements UIResource, Comparator {
3134
3135 private JTree tree;
3136
3137 /**
3138 * Create a Transferable to use as the source for a data transfer.
3139 *
3140 * @param c The component holding the data to be transfered. This
3141 * argument is provided to enable sharing of TransferHandlers by
3142 * multiple components.
3143 * @return The representation of the data to be transfered.
3144 *
3145 */
3146 protected Transferable createTransferable(JComponent c) {
3147 if (c instanceof JTree) {
3148 tree = (JTree) c;
3149 TreePath[] paths = tree.getSelectionPaths();
3150
3151 if (paths == null || paths.length == 0) {
3152 return null;
3153 }
3154
3155 StringBuffer plainBuf = new StringBuffer();
3156 StringBuffer htmlBuf = new StringBuffer();
3157
3158 htmlBuf.append("<html>\n<body>\n<ul>\n");
3159
3160 TreeModel model = tree.getModel();
3161 TreePath lastPath = null;
3162 TreePath[] displayPaths = getDisplayOrderPaths(paths);
3163
3164 for (int i = 0; i < displayPaths.length; i++) {
3165 TreePath path = displayPaths[i];
3166
3167 Object node = path.getLastPathComponent();
3168 boolean leaf = model.isLeaf(node);
3169 String label = getDisplayString(path, true, leaf);
3170
3171 plainBuf.append(label + "\n");
3172 htmlBuf.append(" <li>" + label + "\n");
3173 }
3174
3175 // remove the last newline
3176 plainBuf.deleteCharAt(plainBuf.length() - 1);
3177 htmlBuf.append("</ul>\n</body>\n</html>");
3178
3179 tree = null;
3180
3181 return new BasicTransferable(plainBuf.toString(), htmlBuf.toString());
3182 }
3183
3184 return null;
3185 }
3186
3187 public int compare(Object o1, Object o2) {
3188 int row1 = tree.getRowForPath((TreePath)o1);
3189 int row2 = tree.getRowForPath((TreePath)o2);
3190 return row1 - row2;
3191 }
3192
3193 String getDisplayString(TreePath path, boolean selected, boolean leaf) {
3194 int row = tree.getRowForPath(path);
3195 boolean hasFocus = tree.getLeadSelectionRow() == row;
3196 Object node = path.getLastPathComponent();
3197 return tree.convertValueToText(node, selected, tree.isExpanded(row),
3198 leaf, row, hasFocus);
3199 }
3200
3201 /**
3202 * Selection paths are in selection order. The conversion to
3203 * HTML requires display order. This method resorts the paths
3204 * to be in the display order.
3205 */
3206 TreePath[] getDisplayOrderPaths(TreePath[] paths) {
3207 // sort the paths to display order rather than selection order
3208 ArrayList selOrder = new ArrayList();
3209 for (int i = 0; i < paths.length; i++) {
3210 selOrder.add(paths[i]);
3211 }
3212 Collections.sort(selOrder, this);
3213 int n = selOrder.size();
3214 TreePath[] displayPaths = new TreePath[n];
3215 for (int i = 0; i < n; i++) {
3216 displayPaths[i] = (TreePath) selOrder.get(i);
3217 }
3218 return displayPaths;
3219 }
3220
3221 public int getSourceActions(JComponent c) {
3222 return COPY;
3223 }
3224
3225 }
3226
3227
3228 private class Handler implements CellEditorListener, FocusListener,
3229 KeyListener, MouseListener, MouseMotionListener,
3230 PropertyChangeListener, TreeExpansionListener,
3231 TreeModelListener, TreeSelectionListener,
3232 BeforeDrag {
3233 //
3234 // KeyListener
3235 //
3236 private String prefix = "";
3309 public void keyPressed(KeyEvent e) {
3310 if ( isNavigationKey(e) ) {
3311 prefix = "";
3312 typedString = "";
3313 lastTime = 0L;
3314 }
3315 }
3316
3317 public void keyReleased(KeyEvent e) {
3318 }
3319
3320 /**
3321 * Returns whether or not the supplied key event maps to a key that is used for
3322 * navigation. This is used for optimizing key input by only passing non-
3323 * navigation keys to the first letter navigation mechanism.
3324 */
3325 private boolean isNavigationKey(KeyEvent event) {
3326 InputMap inputMap = tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
3327 KeyStroke key = KeyStroke.getKeyStrokeForEvent(event);
3328
3329 if (inputMap != null && inputMap.get(key) != null) {
3330 return true;
3331 }
3332 return false;
3333 }
3334
3335
3336 //
3337 // PropertyChangeListener
3338 //
3339 public void propertyChange(PropertyChangeEvent event) {
3340 if (event.getSource() == treeSelectionModel) {
3341 treeSelectionModel.resetRowSelection();
3342 }
3343 else if(event.getSource() == tree) {
3344 String changeName = event.getPropertyName();
3345
3346 if (changeName == JTree.LEAD_SELECTION_PATH_PROPERTY) {
3347 if (!ignoreLAChange) {
3348 updateLeadRow();
3349 repaintPath((TreePath)event.getOldValue());
3350 repaintPath((TreePath)event.getNewValue());
3351 }
3352 }
|
1241
1242 private boolean isDropLine(JTree.DropLocation loc) {
1243 return loc != null && loc.getPath() != null && loc.getChildIndex() != -1;
1244 }
1245
1246 private void paintDropLine(Graphics g) {
1247 JTree.DropLocation loc = tree.getDropLocation();
1248 if (!isDropLine(loc)) {
1249 return;
1250 }
1251
1252 Color c = UIManager.getColor("Tree.dropLineColor");
1253 if (c != null) {
1254 g.setColor(c);
1255 Rectangle rect = getDropLineRect(loc);
1256 g.fillRect(rect.x, rect.y, rect.width, rect.height);
1257 }
1258 }
1259
1260 private Rectangle getDropLineRect(JTree.DropLocation loc) {
1261 Rectangle rect;
1262 TreePath path = loc.getPath();
1263 int index = loc.getChildIndex();
1264 boolean ltr = leftToRight;
1265
1266 Insets insets = tree.getInsets();
1267
1268 if (tree.getRowCount() == 0) {
1269 rect = new Rectangle(insets.left,
1270 insets.top,
1271 tree.getWidth() - insets.left - insets.right,
1272 0);
1273 } else {
1274 TreeModel model = getModel();
1275 Object root = model.getRoot();
1276
1277 if (path.getLastPathComponent() == root
1278 && index >= model.getChildCount(root)) {
1279
1280 rect = tree.getRowBounds(tree.getRowCount() - 1);
1281 rect.y = rect.y + rect.height;
2116 editingComponent.setBounds(nodeBounds.x, nodeBounds.y,
2117 nodeBounds.width,
2118 nodeBounds.height);
2119 editingPath = path;
2120 if (editingComponent instanceof JComponent) {
2121 ((JComponent)editingComponent).revalidate();
2122 } else {
2123 editingComponent.validate();
2124 }
2125 editingComponent.repaint();
2126 if(cellEditor.shouldSelectCell(event)) {
2127 stopEditingInCompleteEditing = false;
2128 tree.setSelectionRow(row);
2129 stopEditingInCompleteEditing = true;
2130 }
2131
2132 Component focusedComponent = SwingUtilities2.
2133 compositeRequestFocus(editingComponent);
2134 boolean selectAll = true;
2135
2136 if(event != null) {
2137 /* Find the component that will get forwarded all the
2138 mouse events until mouseReleased. */
2139 Point componentPoint = SwingUtilities.convertPoint
2140 (tree, new Point(event.getX(), event.getY()),
2141 editingComponent);
2142
2143 /* Create an instance of BasicTreeMouseListener to handle
2144 passing the mouse/motion events to the necessary
2145 component. */
2146 // We really want similar behavior to getMouseEventTarget,
2147 // but it is package private.
2148 Component activeComponent = SwingUtilities.
2149 getDeepestComponentAt(editingComponent,
2150 componentPoint.x, componentPoint.y);
2151 if (activeComponent != null) {
2152 MouseInputHandler handler =
2153 new MouseInputHandler(tree, activeComponent,
2154 event, focusedComponent);
2155
2156 if (releaseEvent != null) {
3113 removeFromSource();
3114 }
3115
3116 protected void removeFromSource() {
3117 if(source != null) {
3118 source.removeMouseListener(this);
3119 source.removeMouseMotionListener(this);
3120 if (focusComponent != null &&
3121 focusComponent == destination && !dispatchedEvent &&
3122 (focusComponent instanceof JTextField)) {
3123 ((JTextField)focusComponent).selectAll();
3124 }
3125 }
3126 source = destination = null;
3127 }
3128
3129 } // End of class BasicTreeUI.MouseInputHandler
3130
3131 private static final TransferHandler defaultTransferHandler = new TreeTransferHandler();
3132
3133 static class TreeTransferHandler extends TransferHandler implements UIResource, Comparator<TreePath> {
3134
3135 private JTree tree;
3136
3137 /**
3138 * Create a Transferable to use as the source for a data transfer.
3139 *
3140 * @param c The component holding the data to be transfered. This
3141 * argument is provided to enable sharing of TransferHandlers by
3142 * multiple components.
3143 * @return The representation of the data to be transfered.
3144 *
3145 */
3146 protected Transferable createTransferable(JComponent c) {
3147 if (c instanceof JTree) {
3148 tree = (JTree) c;
3149 TreePath[] paths = tree.getSelectionPaths();
3150
3151 if (paths == null || paths.length == 0) {
3152 return null;
3153 }
3154
3155 StringBuffer plainBuf = new StringBuffer();
3156 StringBuffer htmlBuf = new StringBuffer();
3157
3158 htmlBuf.append("<html>\n<body>\n<ul>\n");
3159
3160 TreeModel model = tree.getModel();
3161 TreePath lastPath = null;
3162 TreePath[] displayPaths = getDisplayOrderPaths(paths);
3163
3164 for (TreePath path : displayPaths) {
3165 Object node = path.getLastPathComponent();
3166 boolean leaf = model.isLeaf(node);
3167 String label = getDisplayString(path, true, leaf);
3168
3169 plainBuf.append(label + "\n");
3170 htmlBuf.append(" <li>" + label + "\n");
3171 }
3172
3173 // remove the last newline
3174 plainBuf.deleteCharAt(plainBuf.length() - 1);
3175 htmlBuf.append("</ul>\n</body>\n</html>");
3176
3177 tree = null;
3178
3179 return new BasicTransferable(plainBuf.toString(), htmlBuf.toString());
3180 }
3181
3182 return null;
3183 }
3184
3185 public int compare(TreePath o1, TreePath o2) {
3186 int row1 = tree.getRowForPath(o1);
3187 int row2 = tree.getRowForPath(o2);
3188 return row1 - row2;
3189 }
3190
3191 String getDisplayString(TreePath path, boolean selected, boolean leaf) {
3192 int row = tree.getRowForPath(path);
3193 boolean hasFocus = tree.getLeadSelectionRow() == row;
3194 Object node = path.getLastPathComponent();
3195 return tree.convertValueToText(node, selected, tree.isExpanded(row),
3196 leaf, row, hasFocus);
3197 }
3198
3199 /**
3200 * Selection paths are in selection order. The conversion to
3201 * HTML requires display order. This method resorts the paths
3202 * to be in the display order.
3203 */
3204 TreePath[] getDisplayOrderPaths(TreePath[] paths) {
3205 // sort the paths to display order rather than selection order
3206 ArrayList<TreePath> selOrder = new ArrayList<TreePath>();
3207 for (TreePath path : paths) {
3208 selOrder.add(path);
3209 }
3210 Collections.sort(selOrder, this);
3211 int n = selOrder.size();
3212 TreePath[] displayPaths = new TreePath[n];
3213 for (int i = 0; i < n; i++) {
3214 displayPaths[i] = selOrder.get(i);
3215 }
3216 return displayPaths;
3217 }
3218
3219 public int getSourceActions(JComponent c) {
3220 return COPY;
3221 }
3222
3223 }
3224
3225
3226 private class Handler implements CellEditorListener, FocusListener,
3227 KeyListener, MouseListener, MouseMotionListener,
3228 PropertyChangeListener, TreeExpansionListener,
3229 TreeModelListener, TreeSelectionListener,
3230 BeforeDrag {
3231 //
3232 // KeyListener
3233 //
3234 private String prefix = "";
3307 public void keyPressed(KeyEvent e) {
3308 if ( isNavigationKey(e) ) {
3309 prefix = "";
3310 typedString = "";
3311 lastTime = 0L;
3312 }
3313 }
3314
3315 public void keyReleased(KeyEvent e) {
3316 }
3317
3318 /**
3319 * Returns whether or not the supplied key event maps to a key that is used for
3320 * navigation. This is used for optimizing key input by only passing non-
3321 * navigation keys to the first letter navigation mechanism.
3322 */
3323 private boolean isNavigationKey(KeyEvent event) {
3324 InputMap inputMap = tree.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
3325 KeyStroke key = KeyStroke.getKeyStrokeForEvent(event);
3326
3327 return inputMap != null && inputMap.get(key) != null;
3328 }
3329
3330
3331 //
3332 // PropertyChangeListener
3333 //
3334 public void propertyChange(PropertyChangeEvent event) {
3335 if (event.getSource() == treeSelectionModel) {
3336 treeSelectionModel.resetRowSelection();
3337 }
3338 else if(event.getSource() == tree) {
3339 String changeName = event.getPropertyName();
3340
3341 if (changeName == JTree.LEAD_SELECTION_PATH_PROPERTY) {
3342 if (!ignoreLAChange) {
3343 updateLeadRow();
3344 repaintPath((TreePath)event.getOldValue());
3345 repaintPath((TreePath)event.getNewValue());
3346 }
3347 }
|