?? basictreeui.java
字號:
if (lineX >= clipLeft && lineX <= clipRight) { int clipTop = clipBounds.y; int clipBottom = clipBounds.y + clipBounds.height; Rectangle parentBounds = getPathBounds(tree, path); Rectangle lastChildBounds = getPathBounds(tree, getLastChildPath(path)); if(lastChildBounds == null) // This shouldn't happen, but if the model is modified // in another thread it is possible for this to happen. // Swing isn't multithreaded, but I'll add this check in // anyway. return; int top; if(parentBounds == null) { top = Math.max(insets.top + getVerticalLegBuffer(), clipTop); } else top = Math.max(parentBounds.y + parentBounds.height + getVerticalLegBuffer(), clipTop); if(depth == 0 && !isRootVisible()) { TreeModel model = getModel(); if(model != null) { Object root = model.getRoot(); if(model.getChildCount(root) > 0) { parentBounds = getPathBounds(tree, path. pathByAddingChild(model.getChild(root, 0))); if(parentBounds != null) top = Math.max(insets.top + getVerticalLegBuffer(), parentBounds.y + parentBounds.height / 2); } } } int bottom = Math.min(lastChildBounds.y + (lastChildBounds.height / 2), clipBottom); if (top <= bottom) { g.setColor(getHashColor()); paintVerticalLine(g, tree, lineX, top, bottom); } } } /** * Paints the expand (toggle) part of a row. The receiver should * NOT modify <code>clipBounds</code>, or <code>insets</code>. */ protected void paintExpandControl(Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf) { Object value = path.getLastPathComponent(); // Draw icons if not a leaf and either hasn't been loaded, // or the model child count is > 0. if (!isLeaf && (!hasBeenExpanded || treeModel.getChildCount(value) > 0)) { int middleXOfKnob; if (leftToRight) { middleXOfKnob = bounds.x - (getRightChildIndent() - 1); } else { middleXOfKnob = bounds.x + bounds.width + getRightChildIndent(); } int middleYOfKnob = bounds.y + (bounds.height / 2); if (isExpanded) { Icon expandedIcon = getExpandedIcon(); if(expandedIcon != null) drawCentered(tree, g, expandedIcon, middleXOfKnob, middleYOfKnob ); } else { Icon collapsedIcon = getCollapsedIcon(); if(collapsedIcon != null) drawCentered(tree, g, collapsedIcon, middleXOfKnob, middleYOfKnob); } } } /** * Paints the renderer part of a row. The receiver should * NOT modify <code>clipBounds</code>, or <code>insets</code>. */ protected void paintRow(Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf) { // Don't paint the renderer if editing this row. if(editingComponent != null && editingRow == row) return; int leadIndex; if(tree.hasFocus()) { leadIndex = getLeadSelectionRow(); } else leadIndex = -1; Component component; component = currentCellRenderer.getTreeCellRendererComponent (tree, path.getLastPathComponent(), tree.isRowSelected(row), isExpanded, isLeaf, row, (leadIndex == row)); rendererPane.paintComponent(g, component, tree, bounds.x, bounds.y, bounds.width, bounds.height, true); } /** * Returns true if the expand (toggle) control should be drawn for * the specified row. */ protected boolean shouldPaintExpandControl(TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf) { if(isLeaf) return false; int depth = path.getPathCount() - 1; if((depth == 0 || (depth == 1 && !isRootVisible())) && !getShowsRootHandles()) return false; return true; } /** * Paints a vertical line. */ protected void paintVerticalLine(Graphics g, JComponent c, int x, int top, int bottom) { if (lineTypeDashed) { drawDashedVerticalLine(g, x, top, bottom); } else { g.drawLine(x, top, x, bottom); } } /** * Paints a horizontal line. */ protected void paintHorizontalLine(Graphics g, JComponent c, int y, int left, int right) { if (lineTypeDashed) { drawDashedHorizontalLine(g, y, left, right); } else { g.drawLine(left, y, right, y); } } /** * The vertical element of legs between nodes starts at the bottom of the * parent node by default. This method makes the leg start below that. */ protected int getVerticalLegBuffer() { return 0; } /** * The horizontal element of legs between nodes starts at the * right of the left-hand side of the child node by default. This * method makes the leg end before that. */ protected int getHorizontalLegBuffer() { return 0; } // // Generic painting methods // // Draws the icon centered at (x,y) protected void drawCentered(Component c, Graphics graphics, Icon icon, int x, int y) { icon.paintIcon(c, graphics, x - icon.getIconWidth()/2, y - icon.getIconHeight()/2); } // This method is slow -- revisit when Java2D is ready. // assumes x1 <= x2 protected void drawDashedHorizontalLine(Graphics g, int y, int x1, int x2){ // Drawing only even coordinates helps join line segments so they // appear as one line. This can be defeated by translating the // Graphics by an odd amount. x1 += (x1 % 2); for (int x = x1; x <= x2; x+=2) { g.drawLine(x, y, x, y); } } // This method is slow -- revisit when Java2D is ready. // assumes y1 <= y2 protected void drawDashedVerticalLine(Graphics g, int x, int y1, int y2) { // Drawing only even coordinates helps join line segments so they // appear as one line. This can be defeated by translating the // Graphics by an odd amount. y1 += (y1 % 2); for (int y = y1; y <= y2; y+=2) { g.drawLine(x, y, x, y); } } // // Various local methods // /** * Returns the location, along the x-axis, to render a particular row * at. The return value does not include any Insets specified on the JTree. * This does not check for the validity of the row or depth, it is assumed * to be correct and will not throw an Exception if the row or depth * doesn't match that of the tree. * * @param row Row to return x location for * @param depth Depth of the row * @return amount to indent the given row. * @since 1.5 */ protected int getRowX(int row, int depth) { return totalChildIndent * (depth + depthOffset); } /** * Makes all the nodes that are expanded in JTree expanded in LayoutCache. * This invokes updateExpandedDescendants with the root path. */ protected void updateLayoutCacheExpandedNodes() { if(treeModel != null && treeModel.getRoot() != null) updateExpandedDescendants(new TreePath(treeModel.getRoot())); } /** * Updates the expanded state of all the descendants of <code>path</code> * by getting the expanded descendants from the tree and forwarding * to the tree state. */ protected void updateExpandedDescendants(TreePath path) { completeEditing(); if(treeState != null) { treeState.setExpandedState(path, true); Enumeration descendants = tree.getExpandedDescendants(path); if(descendants != null) { while(descendants.hasMoreElements()) { path = (TreePath)descendants.nextElement(); treeState.setExpandedState(path, true); } } updateLeadRow(); updateSize(); } } /** * Returns a path to the last child of <code>parent</code>. */ protected TreePath getLastChildPath(TreePath parent) { if(treeModel != null) { int childCount = treeModel.getChildCount (parent.getLastPathComponent()); if(childCount > 0) return parent.pathByAddingChild(treeModel.getChild (parent.getLastPathComponent(), childCount - 1)); } return null; } /** * Updates how much each depth should be offset by. */ protected void updateDepthOffset() { if(isRootVisible()) { if(getShowsRootHandles()) depthOffset = 1; else depthOffset = 0; } else if(!getShowsRootHandles()) depthOffset = -1; else depthOffset = 0; } /** * Updates the cellEditor based on the editability of the JTree that * we're contained in. If the tree is editable but doesn't have a * cellEditor, a basic one will be used. */ protected void updateCellEditor() { TreeCellEditor newEditor; completeEditing(); if(tree == null) newEditor = null; else { if(tree.isEditable()) { newEditor = tree.getCellEditor(); if(newEditor == null) { newEditor = createDefaultCellEditor(); if(newEditor != null) { tree.setCellEditor(newEditor); createdCellEditor = true; } } } else newEditor = null; } if(newEditor != cellEditor) { if(cellEditor != null && cellEditorListener != null) cellEditor.removeCellEditorListener(cellEditorListener); cellEditor = newEditor; if(cellEditorListener == null) cellEditorListener = createCellEditorListener(); if(newEditor != null && cellEditorListener != null) newEditor.addCellEditorListener(cellEditorListener); createdCellEditor = false; } } /** * Messaged from the tree we're in when the renderer has changed. */ protected void updateRenderer() { if(tree != null) { TreeCellRenderer newCellRenderer; newCellRenderer = tree.getCellRenderer(); if(newCellRenderer == null) { tree.setCellRenderer(createDefaultCellRenderer()); createdRenderer = true; } else { createdRenderer = false; currentCellRenderer = newCellRenderer; if(createdCellEditor) { tree.setCellEditor(null); } } } else { createdRenderer = false; currentCellRenderer = null; } updateCellEditor(); } /** * Resets the TreeState instance based on the tree we're providing the * look and feel for. */ protected void configureLayoutCache() { if(treeState != null && tree != null) { if(nodeDimensions == null) nodeDimensions = createNodeDimensions(); treeState.setNodeDimensions(nodeDimensions); treeState.setRootVisible(tree.isRootVisible()); treeState.setRowHeight(tree.getRowHeight()); treeState.setSelectionModel(getSelectionModel()); // Only do this if necessary, may loss state if call with // same model as it currently has. if(treeState.getModel() != tree.getModel()) treeState.setModel(tree.getModel()); updateLayoutCacheExpandedNodes(); // Create a listener to update preferred size when bounds // changes, if necessary. if(isLargeModel()) { if(componentListener == null) { componentListener = createComponentListener(); if(componentListener != null) tree.addComponentListener(componentListener); } } else if(componentListener != null) { tree.removeComponentListener(componentListener); componentListener = null; } } else if(componentListener != null) { tree.removeComponentListener(componentListener); componentListener = null; } } /** * Marks the cached size as being invalid, and messages the * tree with <code>treeDidChange</code>. */ protected void updateSize() { validCachedPreferredSize = false; tree.treeDidChange(); } /** * Updates the <code>preferredSize</code> instance variable, * which is returned from <code>getPreferredSize()</code>.<p> * For left to right orientations, the size is determined from the * current AbstractLayoutCache. For RTL orientations, the preferred size * becomes the width minus the minimum x position. */ protected void updateCachedPreferredSize() { if(treeState != null) { Insets i = tree.getInsets(); if(isLargeModel()) { Rectangle visRect = tree.getVisibleRect(); if(i != null) { visRect.x -= i.left; visRect.y -= i.top; } if (leftToRight) { preferredSize.width = treeState.getPreferredWidth(visRect); }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -