📄 defaultgraphselectionmodel.java
字号:
/* * @(#)DefaultGraphSelectionModel.java 1.0 1/1/02 * * Copyright (c) 2001-2004, Gaudenz Alder * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of JGraph nor the names of its contributors may be used * to endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */package org.jgraph.graph;import java.beans.PropertyChangeListener;import java.io.Serializable;import java.util.ArrayList;import java.util.EventListener;import java.util.Hashtable;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.Stack;import java.util.Vector;import javax.swing.event.EventListenerList;import javax.swing.event.SwingPropertyChangeSupport;import org.jgraph.JGraph;import org.jgraph.event.GraphSelectionEvent;import org.jgraph.event.GraphSelectionListener;/** * Default implementation of GraphSelectionModel. Listeners are notified * * @version 1.0 1/1/02 * @author Gaudenz Alder */public class DefaultGraphSelectionModel implements GraphSelectionModel, Cloneable, Serializable { /** Property name for selectionMode. */ public static final String SELECTION_MODE_PROPERTY = "selectionMode"; /** Value that represents selected state in cellStates. */ public static final int SELECTED = -1; /** Object value that represents the unselected state in cellStates. */ public static final Integer UNSELECTED = new Integer(0); /** Reference to the parent graph. Used to find parents and childs. */ protected JGraph graph; /** Used to message registered listeners. */ protected SwingPropertyChangeSupport changeSupport; /** Event listener list. */ protected EventListenerList listenerList = new EventListenerList(); /** * Mode for the selection, will be either SINGLE_TREE_SELECTION, * CONTIGUOUS_TREE_SELECTION or DISCONTIGUOUS_TREE_SELECTION. */ protected int selectionMode; /** Boolean that indicates if the model allows stepping-into groups. */ protected boolean childrenSelectable = true; /** Maps the cells to their selection state. */ protected Map cellStates = new Hashtable(); /** List that contains the selected items. */ protected List selection = new ArrayList(); /** Constructs a DefaultGraphSelectionModel for the specified graph. */ public DefaultGraphSelectionModel(JGraph graph) { this.graph = graph; } /** * Sets the selection mode, which must be one of SINGLE_TREE_SELECTION, */ public void setSelectionMode(int mode) { int oldMode = selectionMode; selectionMode = mode; if (selectionMode != GraphSelectionModel.MULTIPLE_GRAPH_SELECTION && selectionMode != GraphSelectionModel.SINGLE_GRAPH_SELECTION) selectionMode = GraphSelectionModel.MULTIPLE_GRAPH_SELECTION; if (oldMode != selectionMode && changeSupport != null) changeSupport.firePropertyChange( SELECTION_MODE_PROPERTY, new Integer(oldMode), new Integer(selectionMode)); } /** * Returns the selection mode, one of <code>SINGLE_TREE_SELECTION</code>, * <code>DISCONTIGUOUS_TREE_SELECTION</code> or * <code>CONTIGUOUS_TREE_SELECTION</code>. */ public int getSelectionMode() { return selectionMode; } /** * Sets if the selection model allows the selection * of children. */ public void setChildrenSelectable(boolean flag) { childrenSelectable = flag; } /** * Returns true if the selection model allows the selection * of children. */ public boolean isChildrenSelectable() { return childrenSelectable; } /** * Hook for subclassers for fine-grained control over stepping-into cells. * This implementation returns <code>childrenSelectable</code>. */ protected boolean isChildrenSelectable(Object cell) { return childrenSelectable; } /** * Sets the selection to path. If this represents a change, then * the TreeSelectionListeners are notified. If <code>path</code> is * null, this has the same effect as invoking <code>clearSelection</code>. * * @param path new path to select */ public void setSelectionCell(Object cell) { if (cell == null) setSelectionCells(null); else setSelectionCells(new Object[] { cell }); } /** * Sets the selection to <code>cells</code>. If this represents a * change the GraphSelectionListeners are notified. Potentially * paths will be held by this object; in other words don't change * any of the objects in the array once passed in. * <p>If <code>paths</code> is * null, this has the same effect as invoking <code>clearSelection</code>. * <p>The lead path is set to the last path in <code>pPaths</code>. * <p>If the selection mode is <code>CONTIGUOUS_TREE_SELECTION</code>, * and adding the new paths would make the selection discontiguous, * the selection is reset to the first TreePath in <code>paths</code>. * * @param paths new selection */ public void setSelectionCells(Object[] cells) { if (cells != null) { if (selectionMode == GraphSelectionModel.SINGLE_GRAPH_SELECTION && cells.length > 0) cells = new Object[] { cells[cells.length - 1] }; cellStates.clear(); Vector change = new Vector(); List newSelection = new ArrayList(); for (int i = 0; i < cells.length; i++) { if (cells[i] != null) { change.addElement( new CellPlaceHolder( cells[i], !selection.remove(cells[i]))); select(newSelection, cells[i]); } } Iterator it = selection.iterator(); while (it.hasNext()) change.addElement(new CellPlaceHolder(it.next(), false)); selection = newSelection; if (change.size() > 0) { notifyCellChange(change); } } } /** * Adds path to the current selection. If path is not currently * in the selection the TreeSelectionListeners are notified. This has * no effect if <code>path</code> is null. * * @param path the new path to add to the current selection */ public void addSelectionCell(Object cell) { if (cell != null) addSelectionCells(new Object[] { cell }); } /** * Adds cells to the current selection. If any of the paths in * paths are not currently in the selection the TreeSelectionListeners * are notified. This has * no effect if <code>paths</code> is null. * <p>The lead path is set to the last element in <code>paths</code>. * <p>If the selection mode is <code>CONTIGUOUS_TREE_SELECTION</code>, * and adding the new paths would make the selection discontiguous. * Then two things can result: if the TreePaths in <code>paths</code> * are contiguous, then the selection becomes these TreePaths, * otherwise the TreePaths aren't contiguous and the selection becomes * the first TreePath in <code>paths</code>. * * @param path the new path to add to the current selection */ public void addSelectionCells(Object[] cells) { if (cells != null) { if (selectionMode == GraphSelectionModel.SINGLE_GRAPH_SELECTION) setSelectionCells(cells); else { Vector change = new Vector(); for (int i = 0; i < cells.length; i++) { if (cells[i] != null) { boolean newness = select(selection, cells[i]); if (newness) { change.addElement( new CellPlaceHolder(cells[i], true)); Object parent = graph.getModel().getParent(cells[i]); if (parent != null) change.addElement( new CellPlaceHolder(parent, false)); } } } if (change.size() > 0) notifyCellChange(change); } } } /** * Removes path from the selection. If path is in the selection * The TreeSelectionListeners are notified. This has no effect if * <code>path</code> is null. * * @param path the path to remove from the selection */ public void removeSelectionCell(Object cell) { if (cell != null) removeSelectionCells(new Object[] { cell }); } /** * Removes paths from the selection. If any of the paths in paths * are in the selection the TreeSelectionListeners are notified. * This has no effect if <code>paths</code> is null. * * @param path the path to remove from the selection */ public void removeSelectionCells(Object[] cells) { if (cells != null) { Vector change = new Vector(); for (int i = 0; i < cells.length; i++) { if (cells[i] != null) { boolean removed = deselect(cells[i]); if (removed) { change.addElement(new CellPlaceHolder(cells[i], false)); Object parent = graph.getModel().getParent(cells[i]); if (parent != null) change.addElement( new CellPlaceHolder(parent, false)); } } } if (change.size() > 0) notifyCellChange(change); } } /** * Returns the cells that are currently selectable. */ public Object[] getSelectables() { if (isChildrenSelectable()) { List result = new ArrayList(); // Roots Are Always Selectable Stack s = new Stack(); Object[] cells = graph.getGraphLayoutCache().getCells( graph.getGraphLayoutCache().getRoots()); for (int i = 0; i < cells.length; i++) s.add(cells[i]); GraphModel model = graph.getModel(); // Children of Selected Cells Are Selectable while (!s.isEmpty()) { Object cell = s.pop(); if (!model.isPort(cell)) result.add(cell); if (isChildrenSelectable(cell) && getSelectedChildCount(cell) != 0) { for (int i = 0; i < model.getChildCount(cell); i++) s.add(model.getChild(cell, i)); } } return result.toArray(); } return graph.getRoots(); } /** * Returns the first cell in the selection. This is useful if there * if only one item currently selected. */ public Object getSelectionCell() { if (selection != null && selection.size() > 0) return selection.toArray()[0]; return null; } /** * Returns the cells in the selection. This will return null (or an * empty array) if nothing is currently selected. */ public Object[] getSelectionCells() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -