/*
* 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.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.MessageFormat;
import java.util.Locale;
import javax.swing.JButton;
import javax.swing.JCheckBox;
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 ilog.views.diagrammer.IlvDiagrammer;
import ilog.views.diagrammer.application.IlvDiagrammerViewBar;
import ilog.views.graphlayout.GraphLayoutEvent;
import ilog.views.graphlayout.GraphLayoutEventListener;
import ilog.views.graphlayout.IlvGraphLayout;
import ilog.views.graphlayout.IlvGraphLayoutReport;
import ilog.views.graphlayout.random.IlvRandomLayout;
import ilog.views.sdm.renderer.graphlayout.IlvGraphLayoutRenderer;
import ilog.views.sdm.util.IlvSDMMutableStyleSheet;
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 uses the
* <code>IlvDiagrammer</code> to perform a tree layout. It loads a style sheet
* containing the tree layout specification. It allows to set various tree
* layout parameters by using the <code>IlvSDMMutableStyleSheet</code>.
*/
public class TreeLayoutApp extends JRootPane {
{
// This sample uses JViews Diagrammer features. When deploying an
// application that includes this code, you need to be in possession
// of a Rogue Wave JViews Diagrammer Deployment license.
IlvProductUtil.DeploymentLicenseRequired(IlvProductUtil.JViews_Diagrammer_Deployment);
}
/** The diagrammer */
IlvDiagrammer diagrammer = new IlvDiagrammer();
/** A graph layout event listener */
LayoutIterationListener layoutListener = new LayoutIterationListener();
/** A text field to display messages */
JTextField msgLine = new JTextField();
/** The style sheet for temporary changes */
IlvSDMMutableStyleSheet styleSheet = new IlvSDMMutableStyleSheet(diagrammer.getEngine(), true, false);
/** The flow direction selector */
JComboBox<String> flowDirectionSelector = new JComboBox<String>();
/** The link style selector */
JComboBox<String> linkStyleSelector = new JComboBox<String>();
/** The layout mode selector */
JComboBox<String> layoutModeSelector = new JComboBox<String>();
/** The default offset */
static final double DEFAULT_OFFSET = 20.;
/** Text fields for the offset parameters */
NumberField branchOffsetSelector = new NumberField(0, 200, DEFAULT_OFFSET, true, 6, 5);
NumberField siblingOffsetSelector = new NumberField(0, 200, DEFAULT_OFFSET, true, 6, 5);
NumberField parentOffsetSelector = new NumberField(0, 200, DEFAULT_OFFSET, true, 6, 5);
NumberField startAngleSelector = new NumberField(0, 360, 0, false, 3, 2);
NumberField rootAngleRangeSelector = new NumberField(1, 360, 360, false, 3, 10);
NumberField innerAngleRangeSelector = new NumberField(1, 360, 360, false, 3, 10);
NumberField leafAngleRangeSelector = new NumberField(1, 360, 360, false, 3, 10);
/** Whether to use automatic layout */
boolean autoLayout = false;
/** Whether to do fit to view after layout */
boolean autoFit = true;
/** Layout parameter panels. */
JPanel normalPanel;
JPanel balloonPanel;
/**
* Initializes the application.
*/
public void init() {
// we use the standard diagrammer toolbar
IlvDiagrammerViewBar toolbar = new IlvDiagrammerViewBar();
// various settings of the diagrammer
diagrammer.setSelectMode(true);
diagrammer.setScrollable(true);
diagrammer.setEditingAllowed(true);
diagrammer.setMinimumZoom(0.02);
diagrammer.setMaximumZoom(10);
diagrammer.getView().setBackground(Color.white);
diagrammer.getView().setForeground(SystemColor.windowText);
// create the file selector
JComboBox<String> fileSelector = new JComboBox<String>();
fileSelector.addItem("small");
fileSelector.addItem("medium");
fileSelector.addItem("large");
fileSelector.addItem("balloonSmall");
fileSelector.addItem("balloonMedium");
fileSelector.addItem("balloonLarge");
fileSelector.setToolTipText(getString("FileSelector.Tooltip"));
fileSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent event) {
SuppressWarnings("unchecked")
JComboBox<String> comboBox = (JComboBox<String>) event.getSource();
String fileName = (String) comboBox.getSelectedItem();
loadDataFile(fileName);
}
});
// create the randomize button
JButton randomizeButton = new JButton(getString("RandomLayout.Button.Label"));
randomizeButton.setToolTipText(getString("RandomLayout.Button.Tooltip"));
randomizeButton.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent evt) {
randomize();
}
});
// create the layout button
JButton layoutButton = new JButton(getString("TreeLayout.Button.Label"));
layoutButton.setToolTipText(getString("TreeLayout.Button.Tooltip"));
layoutButton.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent evt) {
// before performing layout, make sure that the values in the text
// fields are transfered to the style sheet
styleSheet.setAdjusting(true);
try {
setOffsetOrAngle("branchOffset", branchOffsetSelector);
setOffsetOrAngle("siblingOffset", siblingOffsetSelector);
setOffsetOrAngle("parentChildOffset", parentOffsetSelector);
setOffsetOrAngle("balloonStartAngle", startAngleSelector);
setOffsetOrAngle("balloonRootChildrenAngle", rootAngleRangeSelector);
setOffsetOrAngle("balloonInnerChildrenAngle", innerAngleRangeSelector);
setOffsetOrAngle("balloonLeafChildrenAngle", leafAngleRangeSelector);
} finally {
styleSheet.setAdjusting(false);
}
performLayout();
}
});
JCheckBox fitToViewBox = new JCheckBox(getString("AutoFit.CheckBox.Label"), autoFit);
fitToViewBox.setToolTipText(getString("AutoFit.CheckBox.Tooltip"));
fitToViewBox.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent evt) {
autoFit = ((JCheckBox) evt.getSource()).isSelected();
}
});
JCheckBox autoLayoutBox = new JCheckBox(getString("AutoLayout.CheckBox.Label"), autoLayout);
autoLayoutBox.setToolTipText(getString("AutoLayout.CheckBox.Tooltip"));
autoLayoutBox.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent evt) {
autoLayout = ((JCheckBox) evt.getSource()).isSelected();
}
});
// create the panel for the layout buttons
JPanel layoutButtonPanel = new JPanel();
layoutButtonPanel.setLayout(new FlowLayout());
layoutButtonPanel.add(new JLabel(" "));
layoutButtonPanel.add(autoLayoutBox);
layoutButtonPanel.add(randomizeButton);
layoutButtonPanel.add(layoutButton);
layoutButtonPanel.add(fitToViewBox);
// create the top panel with the toolbar and the file selector
JPanel topPanel = new JPanel();
topPanel.setLayout(new FlowLayout(FlowLayout.LEADING));
topPanel.add(toolbar);
JLabel label = new JLabel(getString("FileSelector.Label"));
label.setToolTipText(getString("FileSelector.Tooltip"));
topPanel.add(label);
topPanel.add(fileSelector);
// create the layout parameter panels
normalPanel = createNormalParameterPanel();
balloonPanel = createBalloonParameterPanel();
// create the bottom panel with the layout buttons and the message line
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BorderLayout());
bottomPanel.add(layoutButtonPanel, BorderLayout.NORTH);
bottomPanel.add(normalPanel, BorderLayout.CENTER);
bottomPanel.add(msgLine, BorderLayout.SOUTH);
msgLine.setEditable(false);
// put diagrammer, top panel and bottom panel together
getContentPane().setLayout(new BorderLayout(0, 0));
getContentPane().add(diagrammer, BorderLayout.CENTER);
getContentPane().add(topPanel, 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);
try {
// load the main style file
diagrammer.setStyleSheet(IlvSwingUtil.getRelativeURL(this, "data/tree.css"));
// load a mutable style file that we use for temporary style changes
diagrammer.getEngine().setStyleSheets(1, styleSheet.toString());
} catch (Exception e) {
showMessage(e.getMessage());
}
// load the initial sample grapher
loadDataFile("small");
// add the layout listener to the current graph layout. This must be done
// here after reading the style file, because before reading the style file,
// the layout instance is not yet instantiated.
getGraphLayout().addGraphLayoutEventListener(layoutListener);
}
/**
* Creates the layout parameter panel for balloon mode.
*/
private JPanel createBalloonParameterPanel() {
JPanel panel = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.EAST;
panel.setLayout(gridbag);
// layout mode parameter
c.gridx = 0;
c.gridy = 0;
JLabel label = new JLabel(getString("LayoutMode.Label"));
label.setToolTipText(getString("LayoutMode.Tooltip"));
panel.add(label, c);
// angle spacing parameter
c.gridx = 0;
c.gridy = 1;
label = new JLabel(getString("AngleSpacing.Label"));
label.setToolTipText(getString("AngleSpacing.Tooltip"));
panel.add(label, c);
c.gridx = 1;
JComboBox<String> balloonAngleSpacingSelector = new JComboBox<String>();
panel.add(balloonAngleSpacingSelector, c);
balloonAngleSpacingSelector.addItem(getString("AngleSpacing.RegularMode"));
balloonAngleSpacingSelector.addItem(getString("AngleSpacing.FastPropMode"));
balloonAngleSpacingSelector.addItem(getString("AngleSpacing.SlowPropMode"));
balloonAngleSpacingSelector.setSelectedIndex(2);
balloonAngleSpacingSelector.setToolTipText(getString("AngleSpacing.Tooltip"));
balloonAngleSpacingSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent event) {
SuppressWarnings("unchecked")
JComboBox<String> comboBox = (JComboBox<String>) event.getSource();
String mode = (String) comboBox.getSelectedItem();
setBalloonAngleSpacing(mode);
}
});
// radius mode parameter
c.gridx = 0;
c.gridy = 2;
label = new JLabel(getString("RadiusMode.Label"));
label.setToolTipText(getString("RadiusMode.Tooltip"));
panel.add(label, c);
c.gridx = 1;
JComboBox<String> balloonRadiusModeSelector = new JComboBox<String>();
panel.add(balloonRadiusModeSelector, c);
balloonRadiusModeSelector.addItem(getString("RadiusMode.VarMode"));
balloonRadiusModeSelector.addItem(getString("RadiusMode.OptVarMode"));
balloonRadiusModeSelector.addItem(getString("RadiusMode.UniLfMode"));
balloonRadiusModeSelector.addItem(getString("RadiusMode.OptUniLfMode"));
balloonRadiusModeSelector.addItem(getString("RadiusMode.UniMode"));
balloonRadiusModeSelector.setSelectedIndex(3);
balloonRadiusModeSelector.setToolTipText(getString("RadiusMode.Tooltip"));
balloonRadiusModeSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent event) {
SuppressWarnings("unchecked")
JComboBox<String> comboBox = (JComboBox<String>) event.getSource();
String mode = (String) comboBox.getSelectedItem();
setBalloonRadiusMode(mode);
}
});
// branch offset = node offset
c.gridx = 0;
c.gridy = 3;
c.insets = new Insets(5, 0, 0, 0);
label = new JLabel(getString("NodeOffset.Label"));
label.setToolTipText(getString("SiblingOffset.Tooltip"));
panel.add(label, c);
// branch offset = node offset
c.gridx = 2;
c.gridy = 0;
c.insets = new Insets(0, 25, 0, 0);
label = new JLabel(getString("StartAngle.Label"));
label.setToolTipText(getString("StartAngle.Tooltip"));
panel.add(label, c);
c.gridy = 1;
label = new JLabel(getString("RootAngleRange.Label"));
label.setToolTipText(getString("RootAngleRange.Tooltip"));
panel.add(label, c);
c.gridy = 2;
label = new JLabel(getString("InnerAngleRange.Label"));
label.setToolTipText(getString("InnerAngleRange.Tooltip"));
panel.add(label, c);
c.gridy = 3;
label = new JLabel(getString("LeafAngleRange.Label"));
label.setToolTipText(getString("LeafAngleRange.Tooltip"));
panel.add(label, c);
c.gridx = 3;
c.gridy = 0;
panel.add(startAngleSelector, c);
c.gridy = 1;
panel.add(rootAngleRangeSelector, c);
c.gridy = 2;
panel.add(innerAngleRangeSelector, c);
c.gridy = 3;
panel.add(leafAngleRangeSelector, c);
startAngleSelector.setToolTipText(getString("StartAngle.Tooltip"));
startAngleSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent e) {
setOffsetOrAngle("balloonStartAngle", (NumberField) e.getSource());
}
});
rootAngleRangeSelector.setToolTipText(getString("RootAngleRange.Tooltip"));
rootAngleRangeSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent e) {
setOffsetOrAngle("balloonRootChildrenAngle", (NumberField) e.getSource());
}
});
innerAngleRangeSelector.setToolTipText(getString("InnerAngleRange.Tooltip"));
innerAngleRangeSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent e) {
setOffsetOrAngle("balloonInnerChildrenAngle", (NumberField) e.getSource());
}
});
leafAngleRangeSelector.setToolTipText(getString("LeafAngleRange.Tooltip"));
leafAngleRangeSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent e) {
setOffsetOrAngle("balloonLeafChildrenAngle", (NumberField) e.getSource());
}
});
// set the component orientation according to the locale
Locale loc = IlvSwingUtil.getDefaultLocale();
ComponentOrientation co = ComponentOrientation.getOrientation(loc);
panel.applyComponentOrientation(co);
return panel;
}
/**
* Creates the layout parameter panel for normal mode.
*/
private JPanel createNormalParameterPanel() {
JPanel panel = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.EAST;
panel.setLayout(gridbag);
// layout mode parameter
c.gridx = 0;
c.gridy = 0;
JLabel label = new JLabel(getString("LayoutMode.Label"));
label.setToolTipText(getString("LayoutMode.Tooltip"));
panel.add(label, c);
c.gridx = 1;
layoutModeSelector = new JComboBox<String>();
panel.add(layoutModeSelector, c);
layoutModeSelector.addItem(getString("LayoutMode.FreeMode"));
layoutModeSelector.addItem(getString("LayoutMode.LevelMode"));
layoutModeSelector.addItem(getString("LayoutMode.TipOverMode"));
layoutModeSelector.addItem(getString("LayoutMode.BalloonMode"));
layoutModeSelector.addItem(getString("LayoutMode.RadialMode"));
layoutModeSelector.addItem(getString("LayoutMode.AltRadialMode"));
layoutModeSelector.setSelectedIndex(0);
layoutModeSelector.setToolTipText(getString("LayoutMode.Tooltip"));
layoutModeSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent event) {
SuppressWarnings("unchecked")
JComboBox<String> comboBox = (JComboBox<String>) event.getSource();
String mode = (String) comboBox.getSelectedItem();
setLayoutMode(mode);
}
});
// flow direction parameter
c.gridx = 0;
c.gridy = 1;
label = new JLabel(getString("FlowDirection.Label"));
label.setToolTipText(getString("FlowDirection.Tooltip"));
panel.add(label, c);
c.gridx = 1;
panel.add(flowDirectionSelector, c);
flowDirectionSelector.addItem(getString("FlowDirection.Top"));
flowDirectionSelector.addItem(getString("FlowDirection.Bottom"));
flowDirectionSelector.addItem(getString("FlowDirection.Left"));
flowDirectionSelector.addItem(getString("FlowDirection.Right"));
flowDirectionSelector.setSelectedIndex(1);
flowDirectionSelector.setToolTipText(getString("FlowDirection.Tooltip"));
flowDirectionSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent event) {
SuppressWarnings("unchecked")
JComboBox<String> comboBox = (JComboBox<String>) event.getSource();
String flow = (String) comboBox.getSelectedItem();
setFlowDirection(flow);
}
});
// link style parameter
c.gridx = 0;
c.gridy = 2;
label = new JLabel(getString("LinkStyle.Label"));
label.setToolTipText(getString("LinkStyle.Tooltip"));
panel.add(label, c);
c.gridx = 1;
panel.add(linkStyleSelector, c);
linkStyleSelector.addItem(getString("LinkStyle.Orthogonal"));
linkStyleSelector.addItem(getString("LinkStyle.Straight"));
linkStyleSelector.addItem(getString("LinkStyle.Mixed"));
linkStyleSelector.setSelectedIndex(0);
linkStyleSelector.setToolTipText(getString("LinkStyle.Tooltip"));
linkStyleSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent event) {
SuppressWarnings("unchecked")
JComboBox<String> comboBox = (JComboBox<String>) event.getSource();
String style = (String) comboBox.getSelectedItem();
setGlobalLinkStyle(style);
}
});
// alignment parameter
c.gridx = 0;
c.gridy = 3;
label = new JLabel(getString("Alignment.Label"));
label.setToolTipText(getString("Alignment.Tooltip"));
panel.add(label, c);
c.gridx = 1;
JComboBox<String> alignmentSelector = new JComboBox<String>();
panel.add(alignmentSelector, c);
alignmentSelector.addItem(getString("Alignment.Center"));
alignmentSelector.addItem(getString("Alignment.East"));
alignmentSelector.addItem(getString("Alignment.West"));
alignmentSelector.addItem(getString("Alignment.TipOver"));
alignmentSelector.setSelectedIndex(0);
alignmentSelector.setToolTipText(getString("Alignment.Tooltip"));
alignmentSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent event) {
SuppressWarnings("unchecked")
JComboBox<String> comboBox = (JComboBox<String>) event.getSource();
String alignment = (String) comboBox.getSelectedItem();
setGlobalAlignment(alignment);
}
});
// tree layout offset parameters
c.gridx = 3;
c.gridy = 1;
panel.add(siblingOffsetSelector, c);
c.gridy = 2;
panel.add(branchOffsetSelector, c);
c.gridy = 3;
panel.add(parentOffsetSelector, c);
c.gridx = 2;
c.gridy = 0;
c.insets = new Insets(0, 25, 0, 0);
label = new JLabel(getString("OffsetIntro.Label"));
panel.add(label, c);
c.gridy = 1;
label = new JLabel(getString("SiblingOffset.Label"));
label.setToolTipText(getString("BranchOffset.Tooltip"));
panel.add(label, c);
c.gridy = 2;
label = new JLabel(getString("BranchOffset.Label"));
label.setToolTipText(getString("SiblingOffset.Tooltip"));
panel.add(label, c);
c.gridy = 3;
label = new JLabel(getString("ParentChildOffset.Label"));
label.setToolTipText(getString("ParentChildOffset.Tooltip"));
panel.add(label, c);
branchOffsetSelector.setToolTipText(getString("SiblingOffset.Tooltip"));
branchOffsetSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent e) {
setOffsetOrAngle("branchOffset", (NumberField) e.getSource());
}
});
siblingOffsetSelector.setToolTipText(getString("BranchOffset.Tooltip"));
siblingOffsetSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent e) {
setOffsetOrAngle("siblingOffset", (NumberField) e.getSource());
}
});
parentOffsetSelector.setToolTipText(getString("ParentChildOffset.Tooltip"));
parentOffsetSelector.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent e) {
setOffsetOrAngle("parentChildOffset", (NumberField) e.getSource());
}
});
// set the component orientation according to the locale
Locale loc = IlvSwingUtil.getDefaultLocale();
ComponentOrientation co = ComponentOrientation.getOrientation(loc);
panel.applyComponentOrientation(co);
return panel;
}
/**
* Install the parameter panel.
*/
private void installParameterPanel(JPanel panel) {
if (panel.getParent() != null)
return;
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.EAST;
if (normalPanel.getParent() != null) {
JPanel parent = (JPanel) normalPanel.getParent();
parent.remove(normalPanel);
normalPanel.remove(layoutModeSelector);
c.gridy = 0;
c.gridx = 1;
panel.add(layoutModeSelector, c);
normalPanel.remove(branchOffsetSelector);
c.gridy = 3;
c.gridx = 1;
c.insets = new Insets(5, 0, 0, 0);
panel.add(branchOffsetSelector, c);
parent.add(panel, BorderLayout.CENTER);
parent.revalidate();
parent.repaint();
} else if (balloonPanel.getParent() != null) {
JPanel parent = (JPanel) balloonPanel.getParent();
parent.remove(balloonPanel);
balloonPanel.remove(layoutModeSelector);
c.gridy = 0;
c.gridx = 1;
panel.add(layoutModeSelector, c);
balloonPanel.remove(branchOffsetSelector);
c.gridy = 2;
c.gridx = 3;
panel.add(branchOffsetSelector, c);
parent.add(panel, BorderLayout.CENTER);
parent.revalidate();
parent.repaint();
}
}
/**
* Load a sample data file.
*
* @param fileNameBase
* The base of the filename, excluding the path prefix and the
* extension suffix.
*/
private void loadDataFile(String fileNameBase) {
try {
showMessage(getString("FileReadingStartMessage"), fileNameBase);
diagrammer.setDataFile(IlvSwingUtil.getRelativeURL(this, "data/" + fileNameBase + ".xml"));
showMessage(getString("FileReadingDoneMessage"), fileNameBase);
} catch (Exception e) {
showMessage(e.getMessage());
}
}
/**
* Sets the layout mode.
*/
private void setLayoutMode(String mode) {
styleSheet.setDeclaration("GraphLayout", "aspectRatio", "1.5");
if (mode.equals(getString("LayoutMode.FreeMode"))) {
flowDirectionSelector.setEnabled(true);
linkStyleSelector.setEnabled(true);
styleSheet.setDeclaration("GraphLayout", "layoutMode", "FREE");
installParameterPanel(normalPanel);
} else if (mode.equals(getString("LayoutMode.LevelMode"))) {
flowDirectionSelector.setEnabled(true);
linkStyleSelector.setEnabled(true);
styleSheet.setDeclaration("GraphLayout", "layoutMode", "LEVEL");
installParameterPanel(normalPanel);
} else if (mode.equals(getString("LayoutMode.TipOverMode"))) {
flowDirectionSelector.setEnabled(true);
linkStyleSelector.setEnabled(true);
styleSheet.setDeclaration("GraphLayout", "layoutMode", "TIP_LEAVES_OVER");
installParameterPanel(normalPanel);
} else if (mode.equals(getString("LayoutMode.BalloonMode"))) {
flowDirectionSelector.setEnabled(false);
linkStyleSelector.setEnabled(false);
styleSheet.setDeclaration("GraphLayout", "layoutMode", "BALLOON");
styleSheet.setDeclaration("GraphLayout", "aspectRatio", "1.0");
installParameterPanel(balloonPanel);
} else if (mode.equals(getString("LayoutMode.RadialMode"))) {
flowDirectionSelector.setEnabled(false);
linkStyleSelector.setEnabled(false);
styleSheet.setDeclaration("GraphLayout", "layoutMode", "RADIAL");
installParameterPanel(normalPanel);
} else if (mode.equals(getString("LayoutMode.AltRadialMode"))) {
flowDirectionSelector.setEnabled(false);
linkStyleSelector.setEnabled(false);
styleSheet.setDeclaration("GraphLayout", "layoutMode", "ALTERNATING_RADIAL");
installParameterPanel(normalPanel);
}
if (autoLayout)
performLayout();
}
/**
* Sets the flow direction.
*/
private void setFlowDirection(String flow) {
if (flow.equals(getString("FlowDirection.Top")))
styleSheet.setDeclaration("GraphLayout", "flowDirection", "Top");
else if (flow.equals(getString("FlowDirection.Bottom")))
styleSheet.setDeclaration("GraphLayout", "flowDirection", "Bottom");
else if (flow.equals(getString("FlowDirection.Left")))
styleSheet.setDeclaration("GraphLayout", "flowDirection", "Left");
else if (flow.equals(getString("FlowDirection.Right")))
styleSheet.setDeclaration("GraphLayout", "flowDirection", "Right");
if (autoLayout)
performLayout();
}
/**
* Sets the global link style.
*/
private void setGlobalLinkStyle(String style) {
if (style.equals(getString("LinkStyle.Orthogonal")))
styleSheet.setDeclaration("GraphLayout", "globalLinkStyle", "ORTHOGONAL_STYLE");
else if (style.equals(getString("LinkStyle.Straight")))
styleSheet.setDeclaration("GraphLayout", "globalLinkStyle", "STRAIGHT_LINE_STYLE");
else if (style.equals(getString("LinkStyle.Mixed")))
styleSheet.setDeclaration("GraphLayout", "globalLinkStyle", "MIXED_STYLE");
if (autoLayout)
performLayout();
}
/**
* Sets the global alignment.
*/
private void setGlobalAlignment(String alignment) {
if (alignment.equals(getString("Alignment.Center")))
styleSheet.setDeclaration("GraphLayout", "globalAlignment", "CENTER");
else if (alignment.equals(getString("Alignment.East")))
styleSheet.setDeclaration("GraphLayout", "globalAlignment", "EAST");
else if (alignment.equals(getString("Alignment.West")))
styleSheet.setDeclaration("GraphLayout", "globalAlignment", "WEST");
else if (alignment.equals(getString("Alignment.TipOver")))
styleSheet.setDeclaration("GraphLayout", "globalAlignment", "TIP_OVER");
if (autoLayout)
performLayout();
}
/**
* Sets the angle spacing mode in balloon mode.
*/
private void setBalloonAngleSpacing(String mode) {
if (mode.equals(getString("AngleSpacing.RegularMode")))
styleSheet.setDeclaration("GraphLayout", "balloonAngleSpacing", "REGULAR");
else if (mode.equals(getString("AngleSpacing.FastPropMode")))
styleSheet.setDeclaration("GraphLayout", "balloonAngleSpacing", "FAST_PROPORTIONAL");
else if (mode.equals(getString("AngleSpacing.SlowPropMode")))
styleSheet.setDeclaration("GraphLayout", "balloonAngleSpacing", "PROPORTIONAL");
if (autoLayout)
performLayout();
}
/**
* Sets the radius mode in balloon mode.
*/
private void setBalloonRadiusMode(String mode) {
if (mode.equals(getString("RadiusMode.VarMode")))
styleSheet.setDeclaration("GraphLayout", "balloonRadiusMode", "VARIABLE_RADIUS");
else if (mode.equals(getString("RadiusMode.OptVarMode")))
styleSheet.setDeclaration("GraphLayout", "balloonRadiusMode", "OPTIMIZED_VARIABLE_RADIUS");
else if (mode.equals(getString("RadiusMode.UniLfMode")))
styleSheet.setDeclaration("GraphLayout", "balloonRadiusMode", "UNIFORM_LEAVES_RADIUS");
else if (mode.equals(getString("RadiusMode.OptUniLfMode")))
styleSheet.setDeclaration("GraphLayout", "balloonRadiusMode", "OPTIMIZED_UNIFORM_LEAVES_RADIUS");
else if (mode.equals(getString("RadiusMode.UniMode")))
styleSheet.setDeclaration("GraphLayout", "balloonRadiusMode", "UNIFORM_RADIUS");
if (autoLayout)
performLayout();
}
/**
* Sets the sibling, branch or parent/child offset from a textfield.
*/
private void setOffsetOrAngle(String property, NumberField valueSelector) {
try {
// get the value of the parameter from the valueSelector
double value = valueSelector.getValue();
// set the new value of the layout property
if (property.contains("Angle"))
styleSheet.setDeclaration("GraphLayout", property, "" + (int) value);
else
styleSheet.setDeclaration("GraphLayout", property, "" + value);
} catch (Exception ex) {
showMessage(getString("IllegalPropertyMessage"), property, ex.getMessage());
}
if (autoLayout)
performLayout();
}
/**
* Performs the tree layout. The layout type is stored in the CSS file,
* therefore we don't need to set the tree layout explicitely. After loading
* the graph and the CSS style sheet, the tree layout is already instantiated.
*/
private void performLayout() {
showMessage(getString("LayoutStartMessage"));
// initialize the iteration listener
layoutListener.initialize(getGraphLayout());
// Perform Tree Layout as node layout. Tree layout always handles nodes
// and links at the same time, therefore a separate link layout is not
// necessary.
if (diagrammer.isNodeLayoutAvailable()) {
// perform the layout
diagrammer.layoutAllNodes();
// show the layout report information about the return code
IlvGraphLayoutReport report = getGraphLayout().getLayoutReport();
if (report != null) {
// showMessage(getString("LayoutDoneMessage"),
// report.codeToString(report.getCode()));
showMessage("");
// if layout was successfully done, fit in the diagrammer's view
if (report.getCode() == IlvGraphLayoutReport.LAYOUT_DONE) {
if (autoFit)
diagrammer.fitToContents();
}
}
}
}
/**
* Randomize the node positions.
*/
private void randomize() {
// clear previous message
showMessage("");
// create a new random layout
IlvRandomLayout randomLayout = new IlvRandomLayout();
// save the old layout instance
IlvGraphLayout oldLayout = getGraphLayout();
// tell the diagrammer to temporarily use the random layout, which
// disabled the tree layout.
setGraphLayout(randomLayout);
if (diagrammer.isNodeLayoutAvailable()) {
// perform the layout
diagrammer.layoutAllNodes();
}
// restore the old layout instance
setGraphLayout(oldLayout);
}
/**
* Returns the graph layout currently used by the diagrammer.
*/
private IlvGraphLayout getGraphLayout() {
IlvGraphLayoutRenderer renderer = (IlvGraphLayoutRenderer) diagrammer.getEngine().getNodeLayoutRenderer();
return renderer == null ? null : renderer.getGraphLayout();
}
/**
* Sets the graph layout currently used by the diagrammer.
*/
private void setGraphLayout(IlvGraphLayout layout) {
IlvGraphLayoutRenderer renderer = (IlvGraphLayoutRenderer) diagrammer.getEngine().getNodeLayoutRenderer();
if (renderer == null)
return;
renderer.setGraphLayout(layout);
}
/**
* 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) {
showMessage(MessageFormat.format(msgformat, val));
}
/**
* Returns a string.
*/
static String getString(String key) {
return IlvResourceUtil.getString(key, TreeLayoutApp.class, IlvLocaleUtil.getCurrentLocale());
}
/**
* Allows you to run the demo as a standalone application.
*/
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
Override
public void run() {
TreeLayoutApp app = new TreeLayoutApp();
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 graph layout iteration listener. Implementing the interface
* GraphLayoutEventListener gives you the possibility to receive during the
* layout information about the behavior of the layout algorithm. This
* information is contained in the graph layout event.
*
* In our case, we will simply print the percentage completed by the layout
* each time the method layoutStepPerformed is called, that is after each
* iteration of the Tree Layout algorithm.
*/
class LayoutIterationListener implements GraphLayoutEventListener {
IlvGraphLayout layout;
private float oldPercentage;
/**
* This method is automatically called by the layout algorithm.
*/
Override
public void layoutStepPerformed(GraphLayoutEvent event) {
float percentage = event.getLayoutReport().getPercentageComplete();
if (percentage != oldPercentage) {
showMessage(getString("PercentageCompleteMessage"), percentage);
oldPercentage = percentage;
}
}
/**
* Initialize the listener. This method must be called before the layout is
* started.
*/
void initialize(IlvGraphLayout l) {
if (layout != l) {
if (layout != null)
layout.removeGraphLayoutEventListener(this);
layout = l;
if (layout != null)
layout.addGraphLayoutEventListener(this);
}
oldPercentage = -1.0f;
}
}
}