/***************************************************
*
* cismet GmbH, Saarbruecken, Germany
*
* ... and it just works.
*
****************************************************/
package de.cismet.tools.gui.slideabletree;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Enumeration;
import javax.swing.JTree;
import javax.swing.plaf.TreeUI;
import javax.swing.plaf.basic.BasicTreeUI;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
/**
* DOCUMENT ME!
*
* @author dmeiers
* @version $Revision$, $Date$
*/
public class SlideableSubTree extends JTree {
//~ Instance fields --------------------------------------------------------
private boolean specialSelection = false;
private boolean hasDragGestureRecognizer = false;
//~ Constructors -----------------------------------------------------------
/**
* Creates a new SlideableSubTree object.
*
* @param node the root node of the tree
* @param useSpecialSelection flag to use SpecialSelectionUI
*/
SlideableSubTree(final TreeNode node, final boolean useSpecialSelection) {
super(node);
specialSelection = useSpecialSelection;
if (specialSelection) {
this.setUI(new SpecialSelectionUI(this));
}
}
//~ Methods ----------------------------------------------------------------
@Override
public void setExpandedState(final TreePath path, final boolean state) {
super.setExpandedState(path, state);
}
@Override
public boolean removeDescendantSelectedPaths(final TreePath path, final boolean includePath) {
return super.removeDescendantSelectedPaths(path, includePath);
}
@Override
public void removeDescendantToggledPaths(final Enumeration<TreePath> toRemove) {
super.removeDescendantToggledPaths(toRemove);
}
@Override
public Enumeration<TreePath> getDescendantToggledPaths(final TreePath parent) {
return super.getDescendantToggledPaths(parent);
}
@Override
public void clearToggledPaths() {
super.clearToggledPaths();
}
@Override
public void setUI(final TreeUI ui) {
if (specialSelection) {
super.setUI(new SpecialSelectionUI(this));
} else {
super.setUI(ui);
}
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public boolean hasDragGestureRecognizer() {
return hasDragGestureRecognizer;
}
/**
* DOCUMENT ME!
*
* @param hasDragGestureRecognizer DOCUMENT ME!
*/
public void setHasDragGestureRecognizer(final boolean hasDragGestureRecognizer) {
this.hasDragGestureRecognizer = hasDragGestureRecognizer;
}
@Override
public void setEditable(final boolean flag) {
super.setEditable(false);
}
/**
* DOCUMENT ME!
*
* @param path DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public boolean isPathValid(final TreePath path) {
if (path != null) {
final TreeModel model = this.getModel();
if (path.getPathCount() == 0) {
// Pfad representiert Wurzel
return model.getRoot().equals(path.getPathComponent(0));
}
for (int i = 1; i < path.getPathCount(); i++) {
final int childIndex = model.getIndexOfChild(path.getPathComponent(i - 1),
path.getPathComponent(i - 1));
if (childIndex == -1) {
// parent oder childknoten null oder nicht vorhanden...
return false;
}
}
}
return true;
}
//~ Inner Classes ----------------------------------------------------------
/**
* This class is used for an improved selection behavior on muliple selections To remove an node from an mulitple
* selection, this class use the mouseRelease event instead the mousePressed event.
*
* @version $Revision$, $Date$
*/
protected class SpecialSelectionUI extends BasicTreeUI {
//~ Instance fields ----------------------------------------------------
protected JTree tree;
private boolean releasedAction;
//~ Constructors -------------------------------------------------------
/**
* Creates a new SpecialSelectionUI object.
*
* @param t a reference to a JTree
*/
public SpecialSelectionUI(final JTree t) {
tree = t;
}
//~ Methods ------------------------------------------------------------
@Override
protected MouseListener createMouseListener() {
return new MouseListener() {
@Override
public void mouseClicked(final MouseEvent e) {
}
@Override
public void mousePressed(final MouseEvent e) {
final int selCount = tree.getSelectionCount();
final TreePath clickPath = tree.getPathForLocation(e.getX(), e.getY());
if (selCount > 1) {
if (tree.getSelectionModel().isPathSelected(clickPath)) {
releasedAction = true;
return;
}
}
SpecialSelectionUI.super.createMouseListener().mousePressed(e);
}
@Override
public void mouseReleased(final MouseEvent e) {
final TreePath clickPath = tree.getPathForLocation(e.getX(), e.getY());
if (releasedAction && tree.getSelectionModel().isPathSelected(clickPath)) {
releasedAction = false;
SpecialSelectionUI.super.createMouseListener().mousePressed(e);
}
}
@Override
public void mouseEntered(final MouseEvent e) {
SpecialSelectionUI.super.createMouseListener().mouseEntered(e);
}
@Override
public void mouseExited(final MouseEvent e) {
SpecialSelectionUI.super.createMouseListener().mouseExited(e);
}
};
}
}
}