basictreeui.java

来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 2,297 行 · 第 1/5 页

JAVA
2,297
字号
  /**   * Install all listeners for this   */  protected void installListeners()  {    tree.addPropertyChangeListener(propertyChangeListener);    tree.addFocusListener(focusListener);    tree.addTreeSelectionListener(treeSelectionListener);    tree.addMouseListener(mouseListener);    tree.addKeyListener(keyListener);    tree.addPropertyChangeListener(selectionModelPropertyChangeListener);    tree.addComponentListener(componentListener);    tree.addTreeExpansionListener(treeExpansionListener);    if (treeModel != null)      treeModel.addTreeModelListener(treeModelListener);  }  /**   * Install the UI for the component   *    * @param c   *          the component to install UI for   */  public void installUI(JComponent c)  {    tree = (JTree) c;    prepareForUIInstall();    super.installUI(c);    installDefaults();    installComponents();    installKeyboardActions();    installListeners();    setCellEditor(createDefaultCellEditor());    createdCellEditor = true;    isEditing = false;    setModel(tree.getModel());    treeSelectionModel = tree.getSelectionModel();    completeUIInstall();  }  /**   * Uninstall the defaults for the tree   */  protected void uninstallDefaults()  {    tree.setFont(null);    tree.setForeground(null);    tree.setBackground(null);  }  /**   * Uninstall the UI for the component   *    * @param c   *          the component to uninstall UI for   */  public void uninstallUI(JComponent c)  {    prepareForUIUninstall();    uninstallDefaults();    uninstallKeyboardActions();    uninstallListeners();    tree = null;    uninstallComponents();    completeUIUninstall();  }  /**   * Paints the specified component appropriate for the look and feel. This   * method is invoked from the ComponentUI.update method when the specified   * component is being painted. Subclasses should override this method and use   * the specified Graphics object to render the content of the component.   *    * @param g   *          the Graphics context in which to paint   * @param c   *          the component being painted; this argument is often ignored, but   *          might be used if the UI object is stateless and shared by multiple   *          components   */  public void paint(Graphics g, JComponent c)  {    JTree tree = (JTree) c;    updateCurrentVisiblePath();    Rectangle clip = g.getClipBounds();    Insets insets = tree.getInsets();    if (clip != null && treeModel != null && currentVisiblePath != null)      {        int startIndex = tree.getClosestRowForLocation(clip.x, clip.y);        int endIndex = tree.getClosestRowForLocation(clip.x + clip.width,                                                     clip.y + clip.height);        paintVerticalPartOfLeg(g, clip, insets, currentVisiblePath);        for (int i = startIndex; i <= endIndex; i++)          {            Object curr = currentVisiblePath.getPathComponent(i);            boolean isLeaf = treeModel.isLeaf(curr);            TreePath path = new TreePath(getPathToRoot(curr, 0));            boolean isExpanded = tree.isExpanded(path);            Rectangle bounds = getPathBounds(tree, path);            paintHorizontalPartOfLeg(g, clip, insets, bounds, path, i,                                     isExpanded, false, isLeaf);            paintRow(g, clip, insets, bounds, path, i, isExpanded, false,                     isLeaf);          }      }  }  /**   * Ensures that the rows identified by beginRow through endRow are visible.   *    * @param beginRow   *          is the first row   * @param endRow   *          is the last row   */  protected void ensureRowsAreVisible(int beginRow, int endRow)  {    if (beginRow < endRow)      {        int temp = endRow;        endRow = beginRow;        beginRow = temp;      }    for (int i = beginRow; i < endRow; i++)      {        TreePath path = getPathForRow(tree, i);        if (!tree.isVisible(path))          tree.makeVisible(path);      }  }  /**   * Sets the preferred minimum size.   *    * @param newSize   *          is the new preferred minimum size.   */  public void setPreferredMinSize(Dimension newSize)  {    preferredMinSize = newSize;  }  /**   * Gets the preferred minimum size.   *    * @returns the preferred minimum size.   */  public Dimension getPreferredMinSize()  {    return preferredMinSize;  }  /**   * Returns the preferred size to properly display the tree, this is a cover   * method for getPreferredSize(c, false).   *    * @param c   *          the component whose preferred size is being queried; this argument   *          is often ignored but might be used if the UI object is stateless   *          and shared by multiple components   * @return the preferred size   */  public Dimension getPreferredSize(JComponent c)  {    return getPreferredSize(c, false);  }  /**   * Returns the preferred size to represent the tree in c. If checkConsistancy   * is true, checkConsistancy is messaged first.   *    * @param c   *          the component whose preferred size is being queried.   * @param checkConsistancy   *          if true must check consistancy   * @return the preferred size   */  public Dimension getPreferredSize(JComponent c, boolean checkConsistancy)  {    // FIXME: checkConsistancy not implemented, c not used    if (!validCachedPreferredSize)      updateCachedPreferredSize();    return preferredSize;  }  /**   * Returns the minimum size for this component. Which will be the min   * preferred size or (0,0).   *    * @param c   *          the component whose min size is being queried.   * @returns the preferred size or null   */  public Dimension getMinimumSize(JComponent c)  {    Dimension min = getPreferredMinSize();    if (min == null)      return new Dimension();    return min;  }  /**   * Returns the maximum size for the component, which will be the preferred   * size if the instance is currently in JTree or (0,0).   *    * @param c   *          the component whose preferred size is being queried   * @return the max size or null   */  public Dimension getMaximumSize(JComponent c)  {    if (c instanceof JTree)      return ((JTree) c).getPreferredSize();    return new Dimension();  }  /**   * Messages to stop the editing session. If the UI the receiver is providing   * the look and feel for returns true from   * <code>getInvokesStopCellEditing</code>, stopCellEditing will be invoked   * on the current editor. Then completeEditing will be messaged with false,   * true, false to cancel any lingering editing.   */  protected void completeEditing()  {    completeEditing(false, true, false);  }  /**   * Stops the editing session. If messageStop is true, the editor is messaged   * with stopEditing, if messageCancel is true the editor is messaged with   * cancelEditing. If messageTree is true, the treeModel is messaged with   * valueForPathChanged.   *    * @param messageStop   *          message to stop editing   * @param messageCancel   *          message to cancel editing   * @param messageTree   *          message to treeModel   */  protected void completeEditing(boolean messageStop, boolean messageCancel,                                 boolean messageTree)  {    if (messageStop)      {        getCellEditor().stopCellEditing();        stopEditingInCompleteEditing = true;      }    if (messageCancel)      {        getCellEditor().cancelCellEditing();        stopEditingInCompleteEditing = true;      }    if (messageTree)      {        TreeCellEditor editor = getCellEditor();        if (editor != null)          {            Object value = editor.getCellEditorValue();            treeModel.valueForPathChanged(tree.getLeadSelectionPath(), value);          }      }  }  /**   * Will start editing for node if there is a cellEditor and shouldSelectCall   * returns true. This assumes that path is valid and visible.   *    * @param path   *          is the path to start editing   * @param event   *          is the MouseEvent performed on the path   * @return true if successful   */  protected boolean startEditing(TreePath path, MouseEvent event)  {    // Force to recalculate the maximal row height.    maxHeight = 0;    // Force to recalculate the cached preferred size.    validCachedPreferredSize = false;    updateCellEditor();    TreeCellEditor ed = getCellEditor();    if (ed != null        && (event == EDIT || ed.shouldSelectCell(event))         && ed.isCellEditable(event))      {        Rectangle bounds = getPathBounds(tree, path);        // Extend the right boundary till the tree width.        bounds.width = tree.getWidth() - bounds.x;        editingPath = path;        editingRow = tree.getRowForPath(editingPath);        Object value = editingPath.getLastPathComponent();        stopEditingInCompleteEditing = false;        boolean expanded = tree.isExpanded(editingPath);        isEditing = true;        editingComponent = ed.getTreeCellEditorComponent(tree, value, true,                                                         expanded,                                                         isLeaf(editingRow),                                                         editingRow);        // Remove all previous components (if still present). Only one        // container with the editing component inside is allowed in the tree.        tree.removeAll();        // The editing component must be added to its container. We add the        // container, not the editing component itself.        Component container = editingComponent.getParent();        container.setBounds(bounds);        tree.add(container);        editingComponent.requestFocus();        return true;      }    return false;  }  /**   * If the <code>mouseX</code> and <code>mouseY</code> are in the expand or   * collapse region of the row, this will toggle the row.   *    * @param path   *          the path we are concerned with   * @param mouseX   *          is the cursor's x position   * @param mouseY   *          is the cursor's y position   */  protected void checkForClickInExpandControl(TreePath path, int mouseX,                                              int mouseY)  {    if (isLocationInExpandControl(path, mouseX, mouseY))      toggleExpandState(path);  }  /**   * Returns true if the <code>mouseX</code> and <code>mouseY</code> fall in   * the area of row that is used to expand/collpse the node and the node at row   * does not represent a leaf.   *    * @param path   *          the path we are concerned with   * @param mouseX   *          is the cursor's x position   * @param mouseY   *          is the cursor's y position   * @return true if the <code>mouseX</code> and <code>mouseY</code> fall in   *         the area of row that is used to expand/collpse the node and the   *         node at row does not represent a leaf.   */  protected boolean isLocationInExpandControl(TreePath path, int mouseX,                                              int mouseY)  {    boolean cntlClick = false;    int row = getRowForPath(tree, path);    if (!isLeaf(row))      {        Rectangle bounds = getPathBounds(tree, path);        if (hasControlIcons()            && (mouseX < bounds.x)            && (mouseX > (bounds.x - getCurrentControlIcon(path).getIconWidth() - gap)))          cntlClick = true;      }    return cntlClick;  }  /**   * Messaged when the user clicks the particular row, this invokes   * toggleExpandState.   *    * @param path   *          the path we are concerned with   * @param mouseX   *          is the cursor's x position   * @param mouseY   *          is the cursor's y position   */  protected void handleExpandControlClick(TreePath path, int mouseX, int mouseY)  {    toggleExpandState(path);  }  /**   * Expands path if it is not expanded, or collapses row if it is expanded. If   * expanding a path and JTree scroll on expand, ensureRowsAreVisible is   * invoked to scroll as many of the children to visible as possible (tries to   * scroll to last visible descendant of path).   *    * @param path   *          the path we are concerned with   */  protected void toggleExpandState(TreePath path)  {    if (tree.isExpanded(path))      tree.collapsePath(path);    else      tree.expandPath(path);  }  /**   * Returning true signifies a mouse event on the node should toggle the   * selection of only the row under the mouse.   *    * @param event   *          is the MouseEvent performed on the row.   * @return true signifies a mouse event on the node should toggle the   *         selection of only the row under the mouse.   */  protected boolean isToggleSelectionEvent(MouseEvent event)  {    return (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.SINGLE_TREE_SELECTION);  }  /**   * Returning true signifies a mouse event on the node should select from the   * anchor point.   *    * @param event   *          is the MouseEvent performed on the node.   * @return true signifies a mouse event on the node should select from the   *         anchor point.   */  protected boolean isMultiSelectEvent(MouseEvent event)  {    return (tree.getSelectionModel().getSelectionMode() == TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);  }  /**   * Returning true indicates the row under the mouse should be toggled based on   * the event. This is invoked after checkForClickInExpandControl, implying the   * location is not in the expand (toggle) control.   *    * @param event   *          is the MouseEvent performed on the row.   * @return true indicates the row under the mouse should be toggled based on   *         the event.   */  protected boolean isToggleEvent(MouseEvent event)  {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?