/*
* Licensed Materials - Property of Rogue Wave Software, Inc.
* © Copyright Rogue Wave Software, Inc. 2014, 2017
* © Copyright IBM Corp. 2009, 2014
* © Copyright ILOG 1996, 2009
* All Rights Reserved.
*
* Note to U.S. Government Users Restricted Rights:
* The Software and Documentation were developed at private expense and
* are "Commercial Items" as that term is defined at 48 CFR 2.101,
* consisting of "Commercial Computer Software" and
* "Commercial Computer Software Documentation", as such terms are
* used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
* as applicable.
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Locale;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import ilog.views.IlvApplyObject;
import ilog.views.IlvDirection;
import ilog.views.IlvExpandCollapseUtil;
import ilog.views.IlvGrapher;
import ilog.views.IlvGraphic;
import ilog.views.IlvGraphicEnumeration;
import ilog.views.IlvLinkImage;
import ilog.views.IlvManager;
import ilog.views.IlvManagerView;
import ilog.views.IlvPoint;
import ilog.views.IlvRect;
import ilog.views.IlvTransformer;
import ilog.views.graphlayout.IlvGraphLayoutException;
import ilog.views.graphlayout.IlvGraphModel;
import ilog.views.graphlayout.IlvGrapherAdapter;
import ilog.views.graphlayout.IlvNodeSideFilter;
import ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout;
import ilog.views.graphlayout.link.IlvLinkLayout;
import ilog.views.interactor.IlvExpandCollapseInteractor;
import ilog.views.interactor.IlvZoomViewInteractor;
import ilog.views.swing.IlvJManagerViewControlBar;
import ilog.views.swing.IlvJScrollManagerView;
import ilog.views.util.IlvImageUtil;
import ilog.views.util.IlvLocaleUtil;
import ilog.views.util.IlvProductUtil;
import ilog.views.util.IlvResourceUtil;
import ilog.views.util.swing.IlvSwingUtil;
/**
* This is a very simple application that shows various policies when
* expanding and collapsing graphs. It shows how to use the expand utilities in
* applications that are not based on CSS styling.
*/
public class ExpandCollapseApp extends JRootPane {
static {
// Test code whether the demo works in RTL locales
// Locale newLocale = new Locale("he");
// IlvSwingUtil.setDefaultLocale(newLocale);
}
{
// This sample uses JViews Diagrammer features. When deploying an
// application that includes this code, you need to be in possession
// of a JViews Diagrammer Deployment license.
IlvProductUtil.DeploymentLicenseRequired(IlvProductUtil.JViews_Diagrammer_Deployment);
}
/** The grapher */
IlvGrapher grapher = new IlvGrapher();
/** The view of the grapher */
IlvManagerView mgrview = new IlvManagerView(grapher);
/** An instance of the Hierarchical Layout algorithm */
IlvHierarchicalLayout hierarchicalLayout = new IlvHierarchicalLayout();
/** An instance of the Link Layout algorithm */
IlvLinkLayout linkLayout = new IlvLinkLayout();
/** A node side filter for the Link Layout algorithm */
IlvNodeSideFilter nodeSideFilter = new IlvNodeSideFilter() {
Override
public boolean accept(IlvGraphModel graphModel, Object link, boolean origin, Object node,
int side) {
if (origin)
return side == IlvDirection.Right;
else
return side == IlvDirection.Left;
}
};
/** A text field to display messages */
JTextField msgLine = new JTextField();
/** The combo box for the link layout */
JComboBox<String> linkLayoutSelector = new JComboBox<String>();
/** The adjustment mode */
String actModeString = "";
int mode;
/** Whether incremental layout is required */
boolean incrementalLayout = false;
/** Whether we allow link layout */
boolean allowLinkLayout = true;
/** Whether a separate link layout is required */
String linkLayoutSelectionString = getString("linkLayoutSelector.NoneMode");
/** A custom adjustment policy */
PolicyWithLinkLayout customPolicy = new PolicyWithLinkLayout();
/**
* Initializes the application.
*/
public void init() {
showMessage(getString("InitMessage"));
// attach the grapher to the layout instances
IlvGrapherAdapter adapter = new IlvGrapherAdapter(grapher);
hierarchicalLayout.attach(adapter);
linkLayout.attach(adapter);
// change the default option for the links style
hierarchicalLayout.setGlobalLinkStyle(IlvHierarchicalLayout.ORTHOGONAL_STYLE);
// change the default flow direction
hierarchicalLayout.setFlowDirection(IlvDirection.Right);
// create the scroll manager view
IlvJScrollManagerView scrollManView = new IlvJScrollManagerView(mgrview);
// Some settings on the manager view and on the scroll manager view
mgrview.setAntialiasing(true);
mgrview.setKeepingAspectRatio(true);
mgrview.setBackground(Color.white);
mgrview.setForeground(SystemColor.windowText);
Color xc = SystemColor.windowText;
xc = new Color(255 - xc.getRed(), 255 - xc.getGreen(), 255 - xc.getBlue());
mgrview.setDefaultXORColor(xc);
mgrview.setDefaultGhostColor(SystemColor.windowText);
mgrview.setZoomFactorRange(0.02, 10.0);
mgrview.setWheelZoomingEnabled(true);
scrollManView.setWheelScrollingEnabled(true);
// create the standard control bar
IlvJManagerViewControlBar controlBar = new IlvJManagerViewControlBar();
controlBar.setView(mgrview);
IlvExpandCollapseInteractor inter = new IlvExpandCollapseInteractor() {
Override
protected void expandOrCollapse(IlvGraphic obj) {
if (obj instanceof IlvManager) {
expandOrCollapseImpl((IlvManager) obj);
} else {
super.expandOrCollapse(obj);
}
}
};
controlBar.setSelectInteractor(inter);
Image selectIconImage = getImage("gif/Expand.gif");
controlBar.setSelectIcon(new ImageIcon(selectIconImage));
controlBar.setSelectToolTipText(getString("expandButton.Tooltip"));
// modify the interactors such that the demo looks better
((IlvZoomViewInteractor) controlBar.getZoomViewInteractor()).setPermanent(true);
// set the initial interactor
mgrview.setInteractor(controlBar.getSelectInteractor());
// create the bottom panel with the layout buttons and the message line
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout());
bottomPanel.add(createParameterPanel(), BorderLayout.CENTER);
bottomPanel.add(msgLine, BorderLayout.SOUTH);
msgLine.setEditable(false);
// put manager view, top panel and bottom panel together
getContentPane().setLayout(new BorderLayout(0, 0));
getContentPane().add(scrollManView, BorderLayout.CENTER);
getContentPane().add(controlBar, BorderLayout.NORTH);
getContentPane().add(bottomPanel, BorderLayout.SOUTH);
// set the component orientation according to the locale
Locale loc = IlvSwingUtil.getDefaultLocale();
ComponentOrientation co = ComponentOrientation.getOrientation(loc);
getContentPane().applyComponentOrientation(co);
// show all
mgrview.fitTransformerToContent(true);
}
/**
* Creates the parameter panel.
*/
private JPanel createParameterPanel() {
JPanel panel = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.LINE_END;
panel.setLayout(gridbag);
// expansion adjustment mode parameter
c.gridx = 0;
c.gridy = 0;
panel.add(new JLabel(getString("expandModeSelector.Label")), c);
c.gridx = 1;
panel.add(new JLabel(" "), c);
c.gridx = 2;
JComboBox<String> adjustmentModeSelector = new JComboBox<String>();
panel.add(adjustmentModeSelector, c);
adjustmentModeSelector.addItem(getString("expandModeSelector.NoneMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.OrthogonalWithLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.OrthogonalWithoutLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.OrthogonalRecWithLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.OrthogonalRecWithoutLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.OrthogonalStableWithLinksMode"));
adjustmentModeSelector
.addItem(getString("expandModeSelector.OrthogonalStableWithoutLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.RadialWithLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.RadialWithoutLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.RadialRecWithLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.RadialRecWithoutLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.RadialStableWithLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.RadialStableWithoutLinksMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.IncrLayoutMode"));
adjustmentModeSelector.addItem(getString("expandModeSelector.CustomMode"));
adjustmentModeSelector.setSelectedIndex(5);
setAdjustmentMode((String) adjustmentModeSelector.getSelectedItem());
adjustmentModeSelector.setToolTipText(getString("expandModeSelector.Tooltip"));
adjustmentModeSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent event) {
SuppressWarnings("unchecked")
JComboBox<String> comboBox = (JComboBox<String>) event.getSource();
String modeString = (String) comboBox.getSelectedItem();
setAdjustmentMode(modeString);
}
});
// link layout mode parameter
c.gridx = 0;
c.gridy = 1;
panel.add(new JLabel(getString("linkLayoutSelector.Label")), c);
c.gridx = 1;
panel.add(new JLabel(" "), c);
c.gridx = 2;
panel.add(linkLayoutSelector, c);
linkLayoutSelector.addItem(getString("linkLayoutSelector.NoneMode"));
linkLayoutSelector.addItem(getString("linkLayoutSelector.HierMode"));
linkLayoutSelector.addItem(getString("linkLayoutSelector.GenericMode"));
linkLayoutSelector.setSelectedIndex(0);
linkLayoutSelector.setToolTipText(getString("linkLayoutSelector.Tooltip"));
linkLayoutSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent event) {
SuppressWarnings("unchecked")
JComboBox<String> comboBox = (JComboBox<String>) event.getSource();
String modeString = (String) comboBox.getSelectedItem();
setLinkLayoutMode(modeString);
}
});
return panel;
}
/**
* Sets the adjustment mode.
*/
private void setAdjustmentMode(String modeString) {
if (actModeString.equals(modeString))
return;
actModeString = modeString;
// to test a mode, it is better to start with a clean situation,
// hence load the graph new.
incrementalLayout = false;
if (modeString.equals(getString("expandModeSelector.NoneMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.NONE;
allowLinkLayout = true;
} else if (modeString.equals(getString("expandModeSelector.OrthogonalWithLinksMode"))) {
// load flatter variant
loadGrapher("graph2");
mode = IlvExpandCollapseUtil.ORTHOGONAL_WITH_LINKS;
allowLinkLayout = false;
} else if (modeString.equals(getString("expandModeSelector.OrthogonalWithoutLinksMode"))) {
// load flatter variant
loadGrapher("graph2");
mode = IlvExpandCollapseUtil.ORTHOGONAL_WITHOUT_LINKS;
allowLinkLayout = true;
} else if (modeString.equals(getString("expandModeSelector.OrthogonalRecWithLinksMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.ORTHOGONAL_RECURSIVE_WITH_LINKS;
allowLinkLayout = false;
} else if (modeString.equals(getString("expandModeSelector.OrthogonalRecWithoutLinksMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.ORTHOGONAL_RECURSIVE_WITHOUT_LINKS;
allowLinkLayout = true;
} else if (modeString.equals(getString("expandModeSelector.OrthogonalStableWithLinksMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.ORTHOGONAL_STABLE_WITH_LINKS;
allowLinkLayout = false;
} else if (modeString
.equals(getString("expandModeSelector.OrthogonalStableWithoutLinksMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.ORTHOGONAL_STABLE_WITHOUT_LINKS;
allowLinkLayout = true;
} else if (modeString.equals(getString("expandModeSelector.RadialWithLinksMode"))) {
// load flatter variant
loadGrapher("graph2");
mode = IlvExpandCollapseUtil.RADIAL_WITH_LINKS;
allowLinkLayout = false;
} else if (modeString.equals(getString("expandModeSelector.RadialWithoutLinksMode"))) {
// load flatter variant
loadGrapher("graph2");
mode = IlvExpandCollapseUtil.RADIAL_WITHOUT_LINKS;
allowLinkLayout = true;
} else if (modeString.equals(getString("expandModeSelector.RadialRecWithLinksMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.RADIAL_RECURSIVE_WITH_LINKS;
allowLinkLayout = false;
} else if (modeString.equals(getString("expandModeSelector.RadialRecWithoutLinksMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.RADIAL_RECURSIVE_WITHOUT_LINKS;
allowLinkLayout = true;
} else if (modeString.equals(getString("expandModeSelector.RadialStableWithLinksMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.RADIAL_STABLE_WITH_LINKS;
allowLinkLayout = false;
} else if (modeString.equals(getString("expandModeSelector.RadialStableWithoutLinksMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.RADIAL_STABLE_WITHOUT_LINKS;
allowLinkLayout = true;
} else if (modeString.equals(getString("expandModeSelector.IncrLayoutMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.NONE;
incrementalLayout = true;
allowLinkLayout = false;
} else if (modeString.equals(getString("expandModeSelector.CustomMode"))) {
// load deeply nested variant
loadGrapher("graph1");
mode = IlvExpandCollapseUtil.STABLE;
incrementalLayout = false;
allowLinkLayout = false;
}
linkLayoutSelector.setEnabled(allowLinkLayout);
showMessage(getString("ExpandModeStatusMessage"), modeString);
}
/**
* Sets the link layout mode.
*/
private void setLinkLayoutMode(String modeString) {
linkLayoutSelectionString = modeString;
showMessage(getString("LinkLayoutStatusMessage"), modeString);
}
/**
* Expand or collapse a manager.
*/
private void expandOrCollapseImpl(IlvManager manager) {
if (manager.getParent() == null)
return;
boolean collapse = !manager.isCollapsed();
// when expanding and using incremental layout, the node bounds get bigger.
// The incremental layout works better if it knows about the smaller node
// bounds before expanding.
if (incrementalLayout && !collapse) {
IlvManager node = manager;
IlvManager parent = manager.getParent();
while (parent != null) {
IlvHierarchicalLayout layoutOfNode =
(IlvHierarchicalLayout) hierarchicalLayout.getRecursiveLayout().getLayout(parent);
IlvRect bbox = layoutOfNode.getGraphModel().boundingBox(node);
layoutOfNode.setIncrementalNodeBoxForExpand(node, bbox);
node = parent;
parent = node.getParent();
}
}
if (allowLinkLayout
&& !linkLayoutSelectionString.equals(getString("linkLayoutSelector.NoneMode"))) {
// the expand/collapse behaves more stable if all links are straightened
// before expand/collapse. Since there is a link layout afterwards anyway,
// the links get orthogonal anyway.
straightenAllLinks();
}
// now expand or collapse
IlvTransformer t = manager.getParent().getDrawingTransformer(mgrview);
if (mode == IlvExpandCollapseUtil.STABLE) {
// custom adjustment strategy
IlvExpandCollapseUtil.expandOrCollapse(manager, customPolicy, mode, collapse, t, true);
} else {
// default adjustment strategy
IlvExpandCollapseUtil.expandOrCollapse(manager, mode, collapse, t, true);
}
// if the mode says we want an incremental hierarchical layout, do this now
if (incrementalLayout) {
hierarchicalLayout.setIncrementalMode(true);
hierarchicalLayout.setIncrementalAbsoluteLevelPositioning(false);
hierarchicalLayout.setGlobalIncrementalNodeMovementMode(IlvHierarchicalLayout.FREE_MODE);
try {
hierarchicalLayout.performLayout(true, true, true);
} catch (IlvGraphLayoutException ex) {
ex.printStackTrace();
}
}
// if an additional link layout is enabled, do this now.
if (allowLinkLayout) {
// only if we do no incremental hierarchical layout, we might need
// a link layout
if (linkLayoutSelectionString.equals(getString("linkLayoutSelector.HierMode"))) {
hierarchicalLayout.setIncrementalMode(true);
hierarchicalLayout.setIncrementalAbsoluteLevelPositioning(true);
hierarchicalLayout.setGlobalIncrementalNodeMovementMode(IlvHierarchicalLayout.FIXED_MODE);
try {
hierarchicalLayout.performLayout(true, true, true);
} catch (IlvGraphLayoutException ex) {
ex.printStackTrace();
}
} else if (linkLayoutSelectionString.equals(getString("linkLayoutSelector.GenericMode"))) {
linkLayout.setIncrementalMode(true);
linkLayout.setNodeSideFilter(nodeSideFilter);
try {
linkLayout.performLayout(true, true, true);
} catch (IlvGraphLayoutException ex) {
ex.printStackTrace();
}
}
}
}
/**
* Load a sample IVL file.
*
* @param fileNameBase
* The base of the filename, excluding the path prefix and the
* extension suffix.
*/
private void loadGrapher(String fileNameBase) {
try {
showMessage(getString("FileReadingStartMessage"), fileNameBase);
grapher.deleteAll(false);
try {
grapher.read(IlvSwingUtil.getRelativeURL(this, "data/" + fileNameBase + ".ivl"));
} catch (Exception ex1) {
// This case occurs only when we pack the entire application into
// one jar including the data files, and start as application
grapher.read(getClass().getResource("data/" + fileNameBase + ".ivl"));
}
// the transformer may have been modified, so
// we set the identity transformer
mgrview.fitTransformerToContent();
mgrview.repaint();
showMessage(getString("FileReadingDoneMessage"), fileNameBase);
} catch (Exception e) {
// e.printStackTrace();
showMessage(e.getMessage());
}
}
/**
* Displays a message.
*/
void showMessage(String message) {
// the message is displayed in the message line
msgLine.setText(message);
msgLine.paintImmediately(0, 0, msgLine.getWidth(), msgLine.getHeight());
}
void showMessage(String msgformat, Object val) {
Object[] args = {val};
showMessage(MessageFormat.format(msgformat, args));
}
void showMessage(String msgformat, Object val1, Object val2) {
Object[] args = {val1, val2};
showMessage(MessageFormat.format(msgformat, args));
}
/**
* Returns a string.
*/
static String getString(String key) {
return IlvResourceUtil.getString(key, ExpandCollapseApp.class,
IlvLocaleUtil.getCurrentLocale());
}
/**
* Reads an image. It first reads from the jar itself, and then tries to read
* fromfile.
*/
public Image getImage(String fileName) {
Image image = null;
// try to get it from jar
try {
image = IlvImageUtil.getImageFromFile(getClass(), fileName);
} catch (IOException e) {
// System.err.println("Image not found: " + fileName + " exception: " +
// e.getMessage());
showMessage(getString("ImageNotFoundErrorMessage") + "<br>", fileName, e.getMessage());
}
// if couldn't get it from the jar...
if (image == null)
image = getToolkit().getImage(fileName);
// if still null...
if (image == null) {
// System.err.println("Could not get image " + fileName + "!");
showMessage(getString("MissingImageErrorMessage") + "<br>", fileName);
}
return image;
}
/**
* Straighten all links in the grapher.
*/
private void straightenAllLinks() {
IlvGraphicEnumeration e = grapher.getObjects(true);
grapher.applyToObjects(e, new IlvApplyObject() {
Override
public void apply(IlvGraphic g, Object arg) {
if (g instanceof IlvLinkImage) {
IlvLinkImage link = (IlvLinkImage) g;
link.setIntermediateLinkPoints(null, 0, 0);
}
}
}, null, true);
}
/**
* Allows you to run the demo as a standalone application.
*/
public static void main(String[] arg) {
// Sun recommends that to put the entire GUI initialization into the
// AWT thread
SwingUtilities.invokeLater(new Runnable() {
Override
public void run() {
ExpandCollapseApp app = new ExpandCollapseApp();
app.init();
JFrame frame = new JFrame(getString("Frame.Label"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.getContentPane().add(app);
frame.setVisible(true);
}
});
}
// -------------------------------------------------------------------------------
/**
* A custom adjustment policy that runs a hierarchical link layout inside the
* adjustment (instead of running it after the expand/collapse). If a link
* layout is needed, this is in general the best approach that gives the best
* results, but it is also the slowest approach in stable mode.
*/
class PolicyWithLinkLayout implements IlvExpandCollapseUtil.CustomAdjustmentPolicy {
Override
public void apply(IlvManager parent, IlvManager child, IlvRect oldBounds, IlvRect newBounds,
IlvTransformer t, boolean redraw) {
// do an orthogonal expansion (very similar to orthWithoutLinksPolicy)
// first move the child to the center of the old bounds. This is
// already done by setCollapsed, most of the time, except that it is
// done with respect to null transformer and we really need it with
// respect to transformer t. Hence do it again.
double deltaX = 0.5d * (oldBounds.width - newBounds.width);
double deltaY = 0.5d * (oldBounds.height - newBounds.height);
IlvPoint p = new IlvPoint(oldBounds.x + deltaX, oldBounds.y + deltaY);
if (t != null)
t.inverse(p);
parent.moveObject(child, p.x, p.y, redraw);
// shift all nodes in x or y direction
double minX = oldBounds.x;
double maxX = oldBounds.x + oldBounds.width;
double centerX = oldBounds.x + 0.5 * oldBounds.width;
double minY = oldBounds.y;
double maxY = oldBounds.y + oldBounds.height;
double centerY = oldBounds.y + 0.5 * oldBounds.height;
IlvGraphicEnumeration e = parent.getObjects();
while (e.hasMoreElements()) {
IlvGraphic g = e.nextElement();
if (g == child)
continue;
if (g instanceof IlvLinkImage)
continue;
IlvRect bbox = g.boundingBox(t);
p.setLocation(bbox.x, bbox.y);
double cx = bbox.x + 0.5 * bbox.width;
double cy = bbox.y + 0.5 * bbox.height;
if (cx > maxX)
p.x -= deltaX;
else if (cx < minX)
p.x += deltaX;
else
p.x -= (deltaX * 2 * (cx - centerX) / oldBounds.width);
if (cy > maxY)
p.y -= deltaY;
else if (cy < minY)
p.y += deltaY;
else
p.y -= (deltaY * 2 * (cy - centerY) / oldBounds.height);
if (t != null)
t.inverse(p);
parent.moveObject(g, p.x, p.y, redraw);
}
// do a link layout (using the hierarchical layout) on the parent
IlvHierarchicalLayout layout = new IlvHierarchicalLayout();
layout.attach((IlvGrapher) parent);
layout.setGlobalLinkStyle(IlvHierarchicalLayout.ORTHOGONAL_STYLE);
layout.setFlowDirection(IlvDirection.Right);
layout.setIncrementalMode(true);
layout.setIncrementalAbsoluteLevelPositioning(true);
layout.setGlobalIncrementalNodeMovementMode(IlvHierarchicalLayout.FIXED_MODE);
try {
// perform layout only on parent, not recursively on children
layout.performLayout(true, true);
} catch (IlvGraphLayoutException ex) {
ex.printStackTrace();
}
layout.detach();
}
}
}