📄 jxtree.java
字号:
public void stateChanged(ChangeEvent e) { repaint(); } }; } return highlighterChangeListener; } /** * Property to enable/disable rollover support. This can be enabled * to show "live" rollover behaviour, f.i. the cursor over LinkModel cells. * Default is disabled. * @param rolloverEnabled */ public void setRolloverEnabled(boolean rolloverEnabled) { boolean old = isRolloverEnabled(); if (rolloverEnabled == old) return; if (rolloverEnabled) { rolloverProducer = createRolloverProducer(); addMouseListener(rolloverProducer); addMouseMotionListener(rolloverProducer); linkController = new LinkController(); addPropertyChangeListener(linkController); } else { removeMouseListener(rolloverProducer); removeMouseMotionListener(rolloverProducer); rolloverProducer = null; removePropertyChangeListener(linkController); linkController = null; } firePropertyChange("rolloverEnabled", old, isRolloverEnabled()); } /** * creates and returns the RolloverProducer to use with this tree. * A "hit" for rollover is covering the total width of the tree. * Additionally, a pressed to the right (but outside of the label bounds) * is re-dispatched as a pressed just inside the label bounds. This * is a first go for #166-swingx. * * @return */ protected RolloverProducer createRolloverProducer() { RolloverProducer r = new RolloverProducer() { @Override public void mousePressed(MouseEvent e) { JXTree tree = (JXTree) e.getComponent(); Point mousePoint = e.getPoint(); int labelRow = tree.getRowForLocation(mousePoint.x, mousePoint.y); // default selection if (labelRow >= 0) return; int row = tree.getClosestRowForLocation(mousePoint.x, mousePoint.y); Rectangle bounds = tree.getRowBounds(row); if (bounds == null) { row = -1; } else { if ((bounds.y + bounds.height < mousePoint.y) || bounds.x > mousePoint.x) { row = -1; } } // no hit if (row < 0) return; tree.dispatchEvent(new MouseEvent(tree, e.getID(), e.getWhen(), e.getModifiers(), bounds.x + bounds.width - 2, mousePoint.y, e.getClickCount(), e.isPopupTrigger(), e.getButton())); } protected void updateRolloverPoint(JComponent component, Point mousePoint) { JXTree tree = (JXTree) component; int row = tree.getClosestRowForLocation(mousePoint.x, mousePoint.y); Rectangle bounds = tree.getRowBounds(row); if (bounds == null) { row = -1; } else { if ((bounds.y + bounds.height < mousePoint.y) || bounds.x > mousePoint.x) { row = -1; } } int col = row < 0 ? -1 : 0; rollover.x = col; rollover.y = row; } }; return r; } /** * returns the rolloverEnabled property. * @return */ public boolean isRolloverEnabled() { return rolloverProducer != null; } /** * listens to rollover properties. * Repaints effected component regions. * Updates link cursor. * * @author Jeanette Winzenburg */ public class LinkController implements PropertyChangeListener { private Cursor oldCursor; public void propertyChange(PropertyChangeEvent evt) { if (RolloverProducer.ROLLOVER_KEY.equals(evt.getPropertyName())) { rollover((JXTree) evt.getSource(), (Point) evt.getOldValue(), (Point) evt.getOldValue()); } } // -------------------------------------JTree rollover private void rollover(JXTree tree, Point oldLocation, Point newLocation) { //setLinkCursor(list, newLocation); // JW: conditional repaint not working? tree.repaint();// if (oldLocation != null) {// Rectangle r = tree.getRowBounds(oldLocation.y);//// r.x = 0;//// r.width = table.getWidth();// if (r != null)// tree.repaint(r);// }// if (newLocation != null) {// Rectangle r = tree.getRowBounds(newLocation.y);//// r.x = 0;//// r.width = table.getWidth();// if (r != null)// tree.repaint(r);// } } } private DelegatingRenderer getDelegatingRenderer() { if (delegatingRenderer == null) { // only called once... to get hold of the default? delegatingRenderer = new DelegatingRenderer(); delegatingRenderer.setDelegateRenderer(super.getCellRenderer()); } return delegatingRenderer; } public TreeCellRenderer getCellRenderer() { return getDelegatingRenderer(); } public void setCellRenderer(TreeCellRenderer renderer) { // PENDING: do something against recursive setting // == multiple delegation... getDelegatingRenderer().setDelegateRenderer(renderer); super.setCellRenderer(delegatingRenderer); } /** * sets the icon for the handle of an expanded node. * * Note: this will only succeed if the current ui delegate is * a BasicTreeUI otherwise it will do nothing. * * @param expanded */ public void setExpandedIcon(Icon expanded) { if (getUI() instanceof BasicTreeUI) { ((BasicTreeUI) getUI()).setExpandedIcon(expanded); } } /** * sets the icon for the handel of a collapsed node. * * Note: this will only succeed if the current ui delegate is * a BasicTreeUI otherwise it will do nothing. * * @param collapsed */ public void setCollapsedIcon(Icon collapsed) { if (getUI() instanceof BasicTreeUI) { ((BasicTreeUI) getUI()).setCollapsedIcon(collapsed); } } /** * set the icon for a leaf node. * * Note: this will only succeed if current renderer is a * DefaultTreeCellRenderer. * * @param leafIcon */ public void setLeafIcon(Icon leafIcon) { getDelegatingRenderer().setLeafIcon(leafIcon); } /** * set the icon for a open non-leaf node. * * Note: this will only succeed if current renderer is a * DefaultTreeCellRenderer. * * @param openIcon */ public void setOpenIcon(Icon openIcon) { getDelegatingRenderer().setOpenIcon(openIcon); } /** * set the icon for a closed non-leaf node. * * Note: this will only succeed if current renderer is a * DefaultTreeCellRenderer. * * @param closedIcon */ public void setClosedIcon(Icon closedIcon) { getDelegatingRenderer().setClosedIcon(closedIcon); } /** * Property to control whether per-tree icons should be * copied to the renderer on setCellRenderer. * * the default is false for backward compatibility. * * PENDING: should update the current renderer's icons when * setting to true? * * @param overwrite */ public void setOverwriteRendererIcons(boolean overwrite) { if (overwriteIcons == overwrite) return; boolean old = overwriteIcons; this.overwriteIcons = overwrite; firePropertyChange("overwriteRendererIcons", old, overwrite); } public boolean isOverwriteRendererIcons() { return overwriteIcons; } public class DelegatingRenderer implements TreeCellRenderer { private Icon closedIcon = null; private Icon openIcon = null; private Icon leafIcon = null; private TreeCellRenderer delegate; public DelegatingRenderer() { initIcons(new DefaultTreeCellRenderer()); } /** * initially sets the icons to the defaults as given * by a DefaultTreeCellRenderer. * * @param renderer */ private void initIcons(DefaultTreeCellRenderer renderer) { closedIcon = renderer.getDefaultClosedIcon(); openIcon = renderer.getDefaultOpenIcon(); leafIcon = renderer.getDefaultLeafIcon(); } /** * Set the delegate renderer. * Updates the folder/leaf icons. * * THINK: how to update? always override with this.icons, only * if renderer's icons are null, update this icons if they are not, * update all if only one is != null.... ?? * * @param delegate */ public void setDelegateRenderer(TreeCellRenderer delegate) { if (delegate == null) { delegate = new DefaultTreeCellRenderer(); } this.delegate = delegate; updateIcons(); } /** * tries to set the renderers icons. Can succeed only if the * delegate is a DefaultTreeCellRenderer. * THINK: how to update? always override with this.icons, only * if renderer's icons are null, update this icons if they are not, * update all if only one is != null.... ?? * */ private void updateIcons() { if (!isOverwriteRendererIcons()) return; setClosedIcon(closedIcon); setOpenIcon(openIcon); setLeafIcon(leafIcon); } public void setClosedIcon(Icon closedIcon) { if (delegate instanceof DefaultTreeCellRenderer) { ((DefaultTreeCellRenderer) delegate).setClosedIcon(closedIcon); } this.closedIcon = closedIcon; } public void setOpenIcon(Icon openIcon) { if (delegate instanceof DefaultTreeCellRenderer) { ((DefaultTreeCellRenderer) delegate).setOpenIcon(openIcon); } this.openIcon = openIcon; } public void setLeafIcon(Icon leafIcon) { if (delegate instanceof DefaultTreeCellRenderer) { ((DefaultTreeCellRenderer) delegate).setLeafIcon(leafIcon); } this.leafIcon = leafIcon; } public TreeCellRenderer getDelegateRenderer() { return delegate; } public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { Component result = delegate.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); if (highlighters != null) { getComponentAdapter().row = row; result = highlighters.apply(result, getComponentAdapter()); } return result; } } protected ComponentAdapter getComponentAdapter() { return dataAdapter; } private final ComponentAdapter dataAdapter = new TreeAdapter(this); protected static class TreeAdapter extends ComponentAdapter { private final JXTree tree; /** * Constructs a <code>TableCellRenderContext</code> for the specified * target component. * * @param component the target component */ public TreeAdapter(JXTree component) { super(component); tree = component; } public JXTree getTree() { return tree; } public boolean hasFocus() { return tree.isFocusOwner() && (tree.getLeadSelectionRow() == row); } public Object getValueAt(int row, int column) { TreePath path = tree.getPathForRow(row); return path.getLastPathComponent(); } public Object getFilteredValueAt(int row, int column) { /** @todo Implement filtering */ return getValueAt(row, column); } public boolean isSelected() { return tree.isRowSelected(row); } public boolean isExpanded() { return tree.isExpanded(row); } public boolean isLeaf() { return tree.getModel().isLeaf(getValue()); } public boolean isCellEditable(int row, int column) { return false; /** @todo */ } public void setValueAt(Object aValue, int row, int column) { /** @todo */ } public String getColumnName(int columnIndex) { return "Column_" + columnIndex; } public String getColumnIdentifier(int columnIndex) { return null; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -