com.mxgraph.view.mxSwimlaneManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jgraphx Show documentation
Show all versions of jgraphx Show documentation
JGraphX Swing Component - Java Graph Visualization Library
This is a binary & source redistribution of the original, unmodified JGraphX library originating from:
"https://github.com/jgraph/jgraphx/archive/v3.4.1.3.zip".
The purpose of this redistribution is to make the library available to other Maven projects.
/**
* $Id: mxSwimlaneManager.java,v 1.8 2011/01/14 15:21:10 gaudenz Exp $
* Copyright (c) 2007, Gaudenz Alder
*/
package com.mxgraph.view;
import java.util.Map;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxEvent;
import com.mxgraph.util.mxEventObject;
import com.mxgraph.util.mxEventSource;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.util.mxUtils;
/**
* Manager for swimlanes and nested swimlanes that sets the size of newly added
* swimlanes to that of their siblings, and propagates changes to the size of a
* swimlane to its siblings, if siblings is true, and its ancestors, if
* bubbling is true.
*/
public class mxSwimlaneManager extends mxEventSource
{
/**
* Defines the type of the source or target terminal. The type is a string
* passed to mxCell.is to check if the rule applies to a cell.
*/
protected mxGraph graph;
/**
* Optional string that specifies the value of the attribute to be passed
* to mxCell.is to check if the rule applies to a cell.
*/
protected boolean enabled;
/**
* Optional string that specifies the attributename to be passed to
* mxCell.is to check if the rule applies to a cell.
*/
protected boolean horizontal;
/**
* Specifies if newly added cells should be resized to match the size of their
* existing siblings. Default is true.
*/
protected boolean addEnabled;
/**
* Specifies if resizing of swimlanes should be handled. Default is true.
*/
protected boolean resizeEnabled;
/**
*
*/
protected mxIEventListener addHandler = new mxIEventListener()
{
public void invoke(Object source, mxEventObject evt)
{
if (isEnabled() && isAddEnabled())
{
cellsAdded((Object[]) evt.getProperty("cells"));
}
}
};
/**
*
*/
protected mxIEventListener resizeHandler = new mxIEventListener()
{
public void invoke(Object source, mxEventObject evt)
{
if (isEnabled() && isResizeEnabled())
{
cellsResized((Object[]) evt.getProperty("cells"));
}
}
};
/**
*
*/
public mxSwimlaneManager(mxGraph graph)
{
setGraph(graph);
}
/**
* @return the enabled
*/
public boolean isEnabled()
{
return enabled;
}
/**
* @param value the enabled to set
*/
public void setEnabled(boolean value)
{
enabled = value;
}
/**
* @return the bubbling
*/
public boolean isHorizontal()
{
return horizontal;
}
/**
* @param value the bubbling to set
*/
public void setHorizontal(boolean value)
{
horizontal = value;
}
/**
* @return the addEnabled
*/
public boolean isAddEnabled()
{
return addEnabled;
}
/**
* @param value the addEnabled to set
*/
public void setAddEnabled(boolean value)
{
addEnabled = value;
}
/**
* @return the resizeEnabled
*/
public boolean isResizeEnabled()
{
return resizeEnabled;
}
/**
* @param value the resizeEnabled to set
*/
public void setResizeEnabled(boolean value)
{
resizeEnabled = value;
}
/**
* @return the graph
*/
public mxGraph getGraph()
{
return graph;
}
/**
* @param graph the graph to set
*/
public void setGraph(mxGraph graph)
{
if (this.graph != null)
{
this.graph.removeListener(addHandler);
this.graph.removeListener(resizeHandler);
}
this.graph = graph;
if (this.graph != null)
{
this.graph.addListener(mxEvent.ADD_CELLS, addHandler);
this.graph.addListener(mxEvent.CELLS_RESIZED, resizeHandler);
}
}
/**
* Returns true if the given swimlane should be ignored.
*/
protected boolean isSwimlaneIgnored(Object swimlane)
{
return !getGraph().isSwimlane(swimlane);
}
/**
* Returns true if the given cell is horizontal. If the given cell is not a
* swimlane, then the value is returned.
*/
protected boolean isCellHorizontal(Object cell)
{
if (graph.isSwimlane(cell))
{
mxCellState state = graph.getView().getState(cell);
Map style = (state != null) ? state.getStyle()
: graph.getCellStyle(cell);
return mxUtils.isTrue(style, mxConstants.STYLE_HORIZONTAL, true);
}
return !isHorizontal();
}
/**
* Called if any cells have been added. Calls swimlaneAdded for all swimlanes
* where isSwimlaneIgnored returns false.
*/
protected void cellsAdded(Object[] cells)
{
if (cells != null)
{
mxIGraphModel model = getGraph().getModel();
model.beginUpdate();
try
{
for (int i = 0; i < cells.length; i++)
{
if (!isSwimlaneIgnored(cells[i]))
{
swimlaneAdded(cells[i]);
}
}
}
finally
{
model.endUpdate();
}
}
}
/**
* Called for each swimlane which has been added. This finds a reference
* sibling swimlane and applies its size to the newly added swimlane. If no
* sibling can be found then the parent swimlane is resized so that the
* new swimlane fits into the parent swimlane.
*/
protected void swimlaneAdded(Object swimlane)
{
mxIGraphModel model = getGraph().getModel();
Object parent = model.getParent(swimlane);
int childCount = model.getChildCount(parent);
mxGeometry geo = null;
// Finds the first valid sibling swimlane as reference
for (int i = 0; i < childCount; i++)
{
Object child = model.getChildAt(parent, i);
if (child != swimlane && !this.isSwimlaneIgnored(child))
{
geo = model.getGeometry(child);
if (geo != null)
{
break;
}
}
}
// Applies the size of the refernece to the newly added swimlane
if (geo != null)
{
resizeSwimlane(swimlane, geo.getWidth(), geo.getHeight());
}
}
/**
* Called if any cells have been resizes. Calls swimlaneResized for all
* swimlanes where isSwimlaneIgnored returns false.
*/
protected void cellsResized(Object[] cells)
{
if (cells != null)
{
mxIGraphModel model = this.getGraph().getModel();
model.beginUpdate();
try
{
// Finds the top-level swimlanes and adds offsets
for (int i = 0; i < cells.length; i++)
{
if (!this.isSwimlaneIgnored(cells[i]))
{
mxGeometry geo = model.getGeometry(cells[i]);
if (geo != null)
{
mxRectangle size = new mxRectangle(0, 0, geo.getWidth(), geo.getHeight());
Object top = cells[i];
Object current = top;
while (current != null)
{
top = current;
current = model.getParent(current);
mxRectangle tmp = (graph.isSwimlane(current)) ?
graph.getStartSize(current) :
new mxRectangle();
size.setWidth(size.getWidth() + tmp.getWidth());
size.setHeight(size.getHeight() + tmp.getHeight());
}
this.resizeSwimlane(top, size.getWidth(), size.getHeight());
}
}
}
}
finally
{
model.endUpdate();
}
}
}
/**
* Sets the width or height of the given swimlane to the given value depending
* on . If is true, then the width is set, otherwise,
* the height is set.
*/
protected void resizeSwimlane(Object swimlane, double w, double h)
{
mxIGraphModel model = getGraph().getModel();
model.beginUpdate();
try
{
if (!this.isSwimlaneIgnored(swimlane))
{
mxGeometry geo = model.getGeometry(swimlane);
if (geo != null)
{
boolean horizontal = isCellHorizontal(swimlane);
if ((horizontal && geo.getHeight() != h)
|| (!horizontal && geo.getWidth() != w))
{
geo = (mxGeometry) geo.clone();
if (horizontal)
{
geo.setHeight(h);
}
else
{
geo.setWidth(w);
}
model.setGeometry(swimlane, geo);
}
}
}
mxRectangle tmp = (graph.isSwimlane(swimlane)) ? graph
.getStartSize(swimlane) : new mxRectangle();
w -= tmp.getWidth();
h -= tmp.getHeight();
int childCount = model.getChildCount(swimlane);
for (int i = 0; i < childCount; i++)
{
Object child = model.getChildAt(swimlane, i);
resizeSwimlane(child, w, h);
}
}
finally
{
model.endUpdate();
}
}
/**
*
*/
public void destroy()
{
setGraph(null);
}
}