📄 tgpanel.java
字号:
/*
* TouchGraph LLC. Apache-Style Software License
*
*
* Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* TouchGraph LLC (http://www.touchgraph.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse
* or promote products derived from this software without prior written
* permission. For written permission, please contact
* alex@touchgraph.com
*
* 5. Products derived from this software may not be called "TouchGraph",
* nor may "TouchGraph" appear in their name, without prior written
* permission of alex@touchgraph.com.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 TOUCHGRAPH OR ITS 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 com.touchgraph.graphlayout;
import com.touchgraph.graphlayout.interaction.*;
import com.touchgraph.graphlayout.graphelements.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
/** TGPanel contains code for drawing the graph, and storing which nodes
* are selected, and which ones the mouse is over.
*
* It houses methods to activate TGLayout, which performs dynamic layout.
* Whenever the graph is moved, or repainted, TGPanel fires listner
* methods on associated objects.
*
* <p><b>
* Parts of this code build upon Sun's Graph Layout example.
* http://java.sun.com/applets/jdk/1.1/demo/GraphLayout/Graph.java
* </b></p>
*
* @author Alexander Shapiro
* @author Murray Altheim (2001-11-06; 2002-01-14 cleanup)
* @version 1.21 $Id: TGPanel.java,v 1.59 2002/04/01 05:51:55 x_ander Exp $
*/
public class TGPanel extends JPanel {
// static variables for use within the package
public static Color BACK_COLOR = Color.white;
// ....
private GraphEltSet completeEltSet;
private VisibleLocality visibleLocality;
private LocalityUtils localityUtils;
public TGLayout tgLayout;
protected BasicMouseMotionListener basicMML;
protected Edge mouseOverE; //mouseOverE is the edge the mouse is over
protected Node mouseOverN; //mouseOverN is the node the mouse is over
protected boolean maintainMouseOver = false; //If true, then don't change mouseOverN or mouseOverE
protected Node select;
Node dragNode; //Node currently being dragged
protected Point mousePos; //Mouse location, updated in the mouseMotionListener
Image offscreen;
Dimension offscreensize;
Graphics offgraphics;
private Vector graphListeners;
private Vector paintListeners;
TGLensSet tgLensSet; // Converts between a nodes visual position (drawx, drawy),
// and its absolute position (x,y).
AdjustOriginLens adjustOriginLens;
SwitchSelectUI switchSelectUI;
// ............
/** Default constructor.
*/
public TGPanel()
{
setLayout(null);
setGraphEltSet(new GraphEltSet());
addMouseListener(new BasicMouseListener());
basicMML = new BasicMouseMotionListener();
addMouseMotionListener(basicMML);
graphListeners=new Vector();
paintListeners=new Vector();
adjustOriginLens = new AdjustOriginLens();
switchSelectUI = new SwitchSelectUI();
TGLayout tgLayout = new TGLayout(this);
setTGLayout(tgLayout);
tgLayout.start();
setGraphEltSet(new GraphEltSet());
}
public void setLensSet( TGLensSet lensSet ) {
tgLensSet = lensSet;
}
public void setTGLayout( TGLayout tgl ) {
tgLayout = tgl;
}
public void setGraphEltSet( GraphEltSet ges ) {
completeEltSet = ges;
visibleLocality = new VisibleLocality(completeEltSet);
localityUtils = new LocalityUtils(visibleLocality, this);
}
public AdjustOriginLens getAdjustOriginLens() {
return adjustOriginLens;
}
public SwitchSelectUI getSwitchSelectUI() {
return switchSelectUI;
}
// color and font setters ......................
public void setBackColor( Color color ) { BACK_COLOR = color; }
// Node manipulation ...........................
/** Returns an Iterator over all nodes in the complete graph. */
public Iterator getAllNodes() {
return completeEltSet.getNodes();
}
/** Return the current visible locality. */
public ImmutableGraphEltSet getGES() {
return visibleLocality;
}
/** Returns the current node count. */
public int getNodeCount() {
return completeEltSet.nodeCount();
}
/** Returns the current node count within the VisibleLocality.
* @deprecated this method has been replaced by the <tt>visibleNodeCount()</tt> method.
*/
public int nodeNum() {
return visibleLocality.nodeCount();
}
/** Returns the current node count within the VisibleLocality. */
public int visibleNodeCount() {
return visibleLocality.nodeCount();
}
/** Return the Node whose ID matches the String <tt>id</tt>, null if no match is found.
*
* @param id The ID identifier used as a query.
* @return The Node whose ID matches the provided 'id', null if no match is found.
*/
public Node findNode( String id ) {
if ( id == null ) return null; // ignore
return completeEltSet.findNode(id);
}
/** Return a Collection of all Nodes whose label matches the String <tt>label</tt>,
* null if no match is found. */
public Collection findNodesByLabel( String label ) {
if ( label == null ) return null; // ignore
return completeEltSet.findNodesByLabel(label);
}
/** Return the first Nodes whose label contains the String <tt>substring</tt>,
* null if no match is found.
* @param substring The Substring used as a query.
*/
public Node findNodeLabelContaining( String substring ) {
if ( substring == null ) return null; //ignore
return completeEltSet.findNodeLabelContaining(substring);
}
/** Adds a Node, with its ID and label being the current node count plus 1.
* @see com.touchgraph.graphlayout.Node
*/
public Node addNode() throws TGException {
String id = String.valueOf(getNodeCount()+1);
return addNode(id,null,0, false);
}
/** Adds a Node, provided its label. The node is assigned a unique ID.
* @see com.touchgraph.graphlayout.graphelements.GraphEltSet
*/
public Node addNode( String label, Point p, int lab, boolean c ) throws TGException {
return addNode(null,label, p, lab, c);
}
/** Adds a Node, provided its ID and label.
* @see com.touchgraph.graphlayout.Node
*/
public Node addNode( String id, String label, Point p, int lab, boolean c ) throws TGException {
Node node;
if (label==null) {
node = new Node(id);
}
else {
node = new Node(id, label);
}
updateDrawPos(node); // The addNode() call should probably take a position, this just sets it at 0,0
node.setLocation(p);
node.label = lab;
node.centre = true;
addNode(node);
return node;
}
public Node addNode( String id, String label, Color col, Point p, int lab, boolean c ) throws TGException {
Node node;
if (label==null)
node = new Node(id, col);
else
node = new Node(id, label, col);
updateDrawPos(node); // The addNode() call should probably take a position, this just sets it at 0,0
node.setLocation(p);
node.label = lab;
node.centre = true;
addNode(node);
return node;
}
/** Add the Node <tt>node</tt> to the visibleLocality, checking for ID uniqueness. */
public void addNode( final Node node ) throws TGException {
synchronized (localityUtils) {
visibleLocality.addNode(node);
resetDamper();
}
}
/** Remove the Node object matching the ID <code>id</code>, returning true if the
* deletion occurred, false if a Node matching the ID does not exist (or if the ID
* value was null).
*
* @param id The ID identifier used as a query.
* @return true if the deletion occurred.
*/
public boolean deleteNodeById( String id )
{
if ( id == null ) return false; // ignore
Node node = findNode(id);
if ( node == null ) return false;
else return deleteNode(node);
}
public boolean deleteNode( Node node ) {
synchronized (localityUtils) {
if (visibleLocality.deleteNode(node)) { // delete from visibleLocality, *AND completeEltSet
if ( node == select ) clearSelect();
resetDamper();
return true;
}
return false;
}
}
public void clearAll() {
synchronized (localityUtils) {
visibleLocality.clearAll();
}
}
public Node getSelect() {
return select;
}
public Node getMouseOverN() {
return mouseOverN;
}
public synchronized void setMouseOverN( Node node ) {
if ( dragNode != null || maintainMouseOver ) return; // So you don't accidentally switch nodes while dragging
if ( mouseOverN != node ) {
Node oldMouseOverN = mouseOverN;
mouseOverN=node;
}
}
// Edge manipulation ...........................
/** Returns an Iterator over all edges in the complete graph. */
public Iterator getAllEdges() {
return completeEltSet.getEdges();
}
public void deleteEdge( Edge edge ) {
synchronized (localityUtils) {
visibleLocality.deleteEdge(edge);
resetDamper();
}
}
public void deleteEdge( Node from, Node to ) {
synchronized (localityUtils) {
visibleLocality.deleteEdge(from,to);
}
}
/** Returns the current edge count in the complete graph.
*/
public int getEdgeCount() {
return completeEltSet.edgeCount();
}
/** Return the number of Edges in the Locality.
* @deprecated this method has been replaced by the <tt>visibleEdgeCount()</tt> method.
*/
public int edgeNum() {
return visibleLocality.edgeCount();
}
/** Return the number of Edges in the Locality.
*/
public int visibleEdgeCount() {
return visibleLocality.edgeCount();
}
public Edge findEdge( Node f, Node t ) {
return visibleLocality.findEdge(f, t);
}
public void addEdge(Edge e) {
synchronized (localityUtils) {
visibleLocality.addEdge(e); resetDamper();
}
}
public void addEdge( Node f, Node t, int tens ) {
synchronized (localityUtils) {
visibleLocality.addEdge(f, t, tens);
}
}
public void addEdge2( Node f, Node t, int tens, Color color ) {
synchronized (localityUtils) {
visibleLocality.addEdge2(f, t, tens, color);
}
}
public Edge getMouseOverE() {
return mouseOverE;
}
public synchronized void setMouseOverE( Edge edge ) {
if ( dragNode != null || maintainMouseOver ) return; // No funny business while dragging
if ( mouseOverE != edge ) {
Edge oldMouseOverE = mouseOverE;
mouseOverE = edge;
}
}
// miscellany ..................................
protected class AdjustOriginLens extends TGAbstractLens {
protected void applyLens(TGPoint2D p) {
p.x=p.x+TGPanel.this.getSize().width/2;
p.y=p.y+TGPanel.this.getSize().height/2;
}
protected void undoLens(TGPoint2D p) {
p.x=p.x-TGPanel.this.getSize().width/2;
p.y=p.y-TGPanel.this.getSize().height/2;
}
}
public class SwitchSelectUI extends TGAbstractClickUI {
public void mouseClicked(MouseEvent e) {
if ( mouseOverN != null ) {
if ( mouseOverN != select )
setSelect(mouseOverN);
else
clearSelect();
}
}
}
void fireMovedEvent() {
Vector listeners;
synchronized(this) {
listeners = (Vector)graphListeners.clone();
}
for (int i=0;i<listeners.size();i++){
GraphListener gl = (GraphListener) listeners.elementAt(i);
gl.graphMoved();
}
}
public void fireResetEvent() {
Vector listeners;
synchronized(this) {
listeners = (Vector)graphListeners.clone();
}
for (int i=0;i<listeners.size();i++){
GraphListener gl = (GraphListener) listeners.elementAt(i);
gl.graphReset();
}
}
public synchronized void addGraphListener(GraphListener gl){
graphListeners.addElement(gl);
}
public synchronized void removeGraphListener(GraphListener gl){
graphListeners.removeElement(gl);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -