raplatree.java
来自「Rapla是一个灵活的多用户资源管理系统。它提供的一些功能有:日历GUI」· Java 代码 · 共 399 行
JAVA
399 行
/*--------------------------------------------------------------------------*
| Copyright (C) 2006 Christopher Kohlhaas |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by the |
| Free Software Foundation. A copy of the license has been included with |
| these distribution in the COPYING file, if not go to www.fsf.org |
| |
| As a special exception, you are granted the permissions to link this |
| program with every library, which license fulfills the Open Source |
| Definition as published by the Open Source Initiative (OSI). |
*--------------------------------------------------------------------------*/
package org.rapla.gui.toolkit;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import javax.swing.BorderFactory;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.rapla.components.util.Tools;
/** Encapsulates the complex tree class and provides some basic functionality like
* life model exchanging while keeping the Tree state or the integration of the popup listener.
*/
final public class RaplaTree extends JScrollPane {
private static final long serialVersionUID = 1L;
ArrayList m_popupListeners = new ArrayList();
ArrayList m_changeListeners = new ArrayList();
JTree jTree = new JTree() {
private static final long serialVersionUID = 1L;
public String getToolTipText(MouseEvent evt) {
if (toolTipRenderer == null)
{
return super.getToolTipText(evt);
}
int row = getRowForLocation(evt.getX(),evt.getY());
if (row >=0)
{
return toolTipRenderer.getToolTipText(this,row);
}
return super.getToolTipText(evt);
}
};
Listener listener = new Listener();
private boolean treeSelectionListenerBlocked = false;
private boolean bMultiSelect = false;
TreePath selectedPath = null;
TreeToolTipRenderer toolTipRenderer;
public RaplaTree() {
jTree.setBorder( BorderFactory.createEtchedBorder(Color.white,new Color(178, 178, 178)));
jTree.setRootVisible(false);
jTree.setShowsRootHandles(true);
//jTree.putClientProperty("JTree.lineStyle", "None");
getViewport().add(jTree, null);
jTree.addTreeSelectionListener( listener );
jTree.addMouseListener( listener );
setMultiSelect(bMultiSelect);
}
public void setToolTipRenderer(TreeToolTipRenderer renderer) {
toolTipRenderer = renderer;
}
public void addChangeListener(ChangeListener listener) {
m_changeListeners.add(listener);
}
public void removeChangeListener(ChangeListener listener) {
m_changeListeners.remove(listener);
}
/** An ChangeEvent will be fired to every registered ChangeListener
* when the selection has changed.
*/
protected void fireValueChanged() {
if (m_changeListeners.size() == 0)
return;
ChangeListener[] listeners = getChangeListeners();
ChangeEvent evt = new ChangeEvent(this);
for (int i = 0;i<listeners.length;i++) {
listeners[i].stateChanged(evt);
}
}
public ChangeListener[] getChangeListeners() {
return (ChangeListener[])m_changeListeners.toArray(new ChangeListener[]{});
}
public TreeToolTipRenderer getToolTipRenderer() {
return toolTipRenderer;
}
public void addPopupListener(PopupListener listener) {
m_popupListeners.add(listener);
}
public void removePopupListener(PopupListener listener) {
m_popupListeners.remove(listener);
}
public PopupListener[] getPopupListeners() {
return (PopupListener[])m_popupListeners.toArray(new PopupListener[]{});
}
/** An PopupEvent will be fired to every registered PopupListener
* when the popup is selected
*/
protected void firePopup(MouseEvent me) {
Point p = new Point(me.getX(), me.getY());
if (m_popupListeners.size() == 0)
return;
PopupListener[] listeners = getPopupListeners();
Object selectedObject = null;
TreePath path = getTree().getPathForLocation(p.x,p.y);
if (path != null) {
Object node = path.getLastPathComponent();
if (node != null) {
if (node instanceof RecursiveNode)
selectedObject = ((RecursiveNode)node).getUserObject();
if (node instanceof DefaultMutableTreeNode)
selectedObject = ((DefaultMutableTreeNode)node).getUserObject();
}
}
Point upperLeft = getViewport().getViewPosition();
Point newPoint = new Point(p.x - upperLeft.x + 10
,p.y-upperLeft.y);
PopupEvent evt = new PopupEvent(this, selectedObject, newPoint);
for (int i = 0;i<listeners.length;i++) {
listeners[i].showPopup(evt);
}
}
public JTree getTree() {
return jTree;
}
class Listener implements MouseListener,TreeSelectionListener {
public void valueChanged(TreeSelectionEvent event) {
if ( event.getSource() == jTree && ! treeSelectionListenerBlocked) {
selectedPath = event.getNewLeadSelectionPath();
fireValueChanged();
}
}
public void mouseEntered(MouseEvent me) {
}
public void mouseExited(MouseEvent me) {
}
public void mousePressed(MouseEvent me) {
if (me.isPopupTrigger())
firePopup(me);
}
public void mouseReleased(MouseEvent me) {
if (me.isPopupTrigger())
firePopup(me);
}
public void mouseClicked(MouseEvent evt) {
}
}
public void setEnabled(boolean enabled) {
jTree.setEnabled(enabled);
}
private Object getFromNode(TreeNode node) {
if (node == null) return null;
return getObject(node);
}
private Object getLastSelectedElement() {
if (selectedPath != null) {
TreeNode node = (TreeNode)
selectedPath.getLastPathComponent();
return getFromNode(node);
} else {
return null;
}
}
private static Object getObject(Object treeNode) {
try {
if (treeNode == null)
return null;
if (treeNode instanceof DefaultMutableTreeNode)
return ((DefaultMutableTreeNode) treeNode).getUserObject();
if (treeNode instanceof RecursiveNode)
return ((RecursiveNode) treeNode).getUserObject();
return treeNode.getClass().getMethod("getUserObject",Tools.EMPTY_CLASS_ARRAY).invoke(treeNode, Tools.EMPTY_ARRAY);
} catch (Exception ex) {
return null;
}
}
public void exchangeTreeModel(TreeModel model) {
boolean notifySelection;
try {
treeSelectionListenerBlocked = true;
notifySelection = exchangeTreeModel( model, jTree ) ;
} finally {
treeSelectionListenerBlocked = false;
}
if ( notifySelection ) {
this.fireValueChanged();
}
}
/** Exchanges the tree-model while trying to preserve the selection an expansion state.
* Returns if the selection has been affected by the excahnge.*/
public static boolean exchangeTreeModel(TreeModel model,JTree tree) {
Collection expanded = new HashSet();
Collection selected = new HashSet();
for (int i=0;i<tree.getRowCount();i++) {
if (tree.isExpanded(i)) {
Object obj = getObject( tree.getPathForRow(i).getLastPathComponent() );
if (obj != null )
expanded.add( obj );
}
if (tree.isRowSelected(i)) {
Object obj = getObject( tree.getPathForRow(i).getLastPathComponent() );
if (obj != null )
selected.add( obj );
}
}
tree.setModel(model);
if ( model instanceof DefaultTreeModel ) {
((DefaultTreeModel)model).reload();
}
if (expanded.size() ==0 && selected.size() == 0)
{
TreeNode root = (TreeNode)model.getRoot();
if (root.getChildCount()<2)
{
tree.expandRow(0);
}
}
ArrayList selectedList = new ArrayList();
for (int i=0;i<tree.getRowCount();i++) {
TreePath treePath = tree.getPathForRow(i);
Object obj = getObject( treePath.getLastPathComponent() );
if (obj == null)
continue;
if (expanded.contains( obj )) {
tree.expandRow(i);
}
if (selected.contains( obj )) {
selectedList.add(treePath);
}
}
tree.setSelectionPaths((TreePath[])
selectedList.toArray(new TreePath[selectedList.size()]));
return selectedList.size() != selected.size();
}
public void setMultiSelect(boolean bMultiSelect) {
this.bMultiSelect = bMultiSelect;
if ( bMultiSelect) {
jTree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
} else {
jTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
} // end of else
}
class TreeIterator implements Iterator {
Stack nodeStack = new Stack();
public TreeIterator(TreeNode node) {
nodeStack.push(node);
}
public boolean hasNext() {
return !nodeStack.isEmpty();
}
public Object next() {
TreeNode node = (TreeNode) nodeStack.pop();
int count = node.getChildCount();
for (int i=0;i<count;i++) {
nodeStack.push(node.getChildAt(i));
}
return node;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
private TreePath getPath(TreeNode node) {
if (node.getParent() == null)
return new TreePath(node);
else
return getPath(node.getParent()).pathByAddingChild(node);
}
public void select(Collection selectedObjects) {
Collection selectedNodes = new ArrayList();
Iterator it = new TreeIterator((TreeNode)jTree.getModel().getRoot());
while (it.hasNext()) {
Object node = it.next();
if (!(node instanceof TreeNode)) {
continue;
}
if (node != null && selectedObjects.contains( getObject(node) ))
selectedNodes.add(node);
}
it = selectedNodes.iterator();
TreePath[] path = new TreePath[selectedNodes.size()];
int i=0;
while (it.hasNext()) {
path[i] = getPath((TreeNode)it.next());
jTree.expandPath(path[i]);
i++;
}
jTree.setSelectionPaths(path);
}
public Object getSelectedElement() {
Collection col = getSelectedElements();
if ( col.size()>0) {
return col.iterator().next();
} else {
return null;
} // end of else
}
public List getSelectedElements() {
TreePath[] path = jTree.getSelectionPaths();
int size = 0;
if (path != null)
size = path.length;
List list = new LinkedList();
for (int i=0;i < size;i++) {
TreeNode node = (TreeNode) path[i].getLastPathComponent();
Object obj = getFromNode(node);
if (obj != null)
list.add(obj);
}
return list;
}
public Object getInfoElement() {
if ( bMultiSelect) {
return getLastSelectedElement();
} else {
return getSelectedElement();
} // end of else
}
public void unselectAll() {
jTree.setSelectionInterval(-1,-1);
}
public void requestFocus() {
jTree.requestFocus();
}
public void expandAll() {
int i = 0;
while (i<jTree.getRowCount()) {
jTree.expandRow(i);
i++;
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?