
edu.uci.ics.jung.algorithms.layout.AggregateLayout Maven / Gradle / Ivy
/*
* Copyright (c) 2003, the JUNG Project and the Regents of the University of
* California All rights reserved.
*
* This software is open-source under the BSD license; see either "license.txt"
* or http://jung.sourceforge.net/license.txt for a description.
*
*
*
*/
package edu.uci.ics.jung.algorithms.layout;
import java.awt.Dimension;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.collections15.Transformer;
import edu.uci.ics.jung.algorithms.util.IterativeContext;
import edu.uci.ics.jung.graph.Graph;
/**
* A {@code Layout} implementation that combines
* multiple other layouts so that they may be manipulated
* as one layout. The relaxer thread will step each layout
* in sequence.
*
* @author Tom Nelson - [email protected]
*
* @param the vertex type
* @param the edge type
*/
public class AggregateLayout implements Layout, IterativeContext {
protected Layout delegate;
protected Map,Point2D> layouts = new HashMap,Point2D>();
/**
* Creates an instance backed by the specified {@code delegate}.
* @param delegate
*/
public AggregateLayout(Layout delegate) {
this.delegate = delegate;
}
/**
* @return the delegate
*/
public Layout getDelegate() {
return delegate;
}
/**
* @param delegate the delegate to set
*/
public void setDelegate(Layout delegate) {
this.delegate = delegate;
}
/**
* adds the passed layout as a sublayout, also specifying
* the center of where this sublayout should appear
* @param layout
* @param center
*/
public void put(Layout layout, Point2D center) {
layouts.put(layout,center);
}
/**
* Returns the center of the passed layout.
* @param layout
* @return the center of the passed layout
*/
public Point2D get(Layout layout) {
return layouts.get(layout);
}
/**
* Removes {@code layout} from this instance.
*/
public void remove(Layout layout) {
layouts.remove(layout);
}
/**
* Removes all layouts from this instance.
*/
public void removeAll() {
layouts.clear();
}
/**
* Returns the graph for which this layout is defined.
* @return the graph for which this layout is defined
* @see edu.uci.ics.jung.algorithms.layout.Layout#getGraph()
*/
public Graph getGraph() {
return delegate.getGraph();
}
/**
* Returns the size of the underlying layout.
* @return the size of the underlying layout
* @see edu.uci.ics.jung.algorithms.layout.Layout#getSize()
*/
public Dimension getSize() {
return delegate.getSize();
}
/**
*
* @see edu.uci.ics.jung.algorithms.layout.Layout#initialize()
*/
public void initialize() {
delegate.initialize();
for(Layout layout : layouts.keySet()) {
layout.initialize();
}
}
/**
* Override to test if the passed vertex is locked in
* any of the layouts.
* @param v
* @return true if v is locked in any of the layouts, and false otherwise
* @see edu.uci.ics.jung.algorithms.layout.Layout#isLocked(java.lang.Object)
*/
public boolean isLocked(V v) {
boolean locked = false;
for(Layout layout : layouts.keySet()) {
locked |= layout.isLocked(v);
}
locked |= delegate.isLocked(v);
return locked;
}
/**
* override to lock or unlock this vertex in any layout with
* a subgraph containing it
* @param v
* @param state
* @see edu.uci.ics.jung.algorithms.layout.Layout#lock(java.lang.Object, boolean)
*/
public void lock(V v, boolean state) {
for(Layout layout : layouts.keySet()) {
if(layout.getGraph().getVertices().contains(v)) {
layout.lock(v, state);
}
}
delegate.lock(v, state);
}
/**
*
* @see edu.uci.ics.jung.algorithms.layout.Layout#reset()
*/
public void reset() {
for(Layout layout : layouts.keySet()) {
layout.reset();
}
delegate.reset();
}
/**
* @param graph
* @see edu.uci.ics.jung.algorithms.layout.Layout#setGraph(edu.uci.ics.jung.graph.Graph)
*/
public void setGraph(Graph graph) {
delegate.setGraph(graph);
}
/**
* @param initializer
* @see edu.uci.ics.jung.algorithms.layout.Layout#setInitializer(org.apache.commons.collections15.Transformer)
*/
public void setInitializer(Transformer initializer) {
delegate.setInitializer(initializer);
}
/**
* @param v
* @param location
* @see edu.uci.ics.jung.algorithms.layout.Layout#setLocation(java.lang.Object, java.awt.geom.Point2D)
*/
public void setLocation(V v, Point2D location) {
boolean wasInSublayout = false;
for(Layout layout : layouts.keySet()) {
if(layout.getGraph().getVertices().contains(v)) {
Point2D center = layouts.get(layout);
// transform by the layout itself, but offset to the
// center of the sublayout
Dimension d = layout.getSize();
AffineTransform at =
AffineTransform.getTranslateInstance(-center.getX()+d.width/2,-center.getY()+d.height/2);
Point2D localLocation = at.transform(location, null);
layout.setLocation(v, localLocation);
wasInSublayout = true;
}
}
if(wasInSublayout == false && getGraph().getVertices().contains(v)) {
delegate.setLocation(v, location);
}
}
/**
* @param d
* @see edu.uci.ics.jung.algorithms.layout.Layout#setSize(java.awt.Dimension)
*/
public void setSize(Dimension d) {
delegate.setSize(d);
}
/**
* Returns a map from each {@code Layout} instance to its center point.
*/
public Map,Point2D> getLayouts() {
return layouts;
}
/**
* Returns the location of the vertex. The location is specified first
* by the sublayouts, and then by the base layout if no sublayouts operate
* on this vertex.
* @return the location of the vertex
* @see org.apache.commons.collections15.Transformer#transform(java.lang.Object)
*/
public Point2D transform(V v) {
boolean wasInSublayout = false;
for(Layout layout : layouts.keySet()) {
if(layout.getGraph().getVertices().contains(v)) {
wasInSublayout = true;
Point2D center = layouts.get(layout);
// transform by the layout itself, but offset to the
// center of the sublayout
Dimension d = layout.getSize();
AffineTransform at =
AffineTransform.getTranslateInstance(center.getX()-d.width/2,
center.getY()-d.height/2);
return at.transform(layout.transform(v),null);
}
}
if(wasInSublayout == false) {
return delegate.transform(v);
}
return null;
}
/**
* Check all sublayouts.keySet() and the delegate layout, returning
* done == true iff all are done.
*/
public boolean done() {
boolean done = true;
for(Layout layout : layouts.keySet()) {
if(layout instanceof IterativeContext) {
done &= ((IterativeContext)layout).done();
}
}
if(delegate instanceof IterativeContext) {
done &= ((IterativeContext)delegate).done();
}
return done;
}
/**
* call step on any sublayout that is also an IterativeContext
* and is not done
*/
public void step() {
for(Layout layout : layouts.keySet()) {
if(layout instanceof IterativeContext) {
IterativeContext context = (IterativeContext)layout;
if(context.done() == false) {
context.step();
}
}
}
if(delegate instanceof IterativeContext) {
IterativeContext context = (IterativeContext)delegate;
if(context.done() == false) {
context.step();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy