/* * Licensed Materials - Property of Perforce Software, Inc. * © Copyright Perforce Software, Inc. 2014, 2021 * © 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 javax.swing.SwingUtilities; import ilog.views.IlvDirection; import ilog.views.IlvGrapher; import ilog.views.IlvGraphic; import ilog.views.IlvGraphicEnumeration; import ilog.views.IlvHandlesSelection; import ilog.views.IlvLinkImage; import ilog.views.IlvManagerView; import ilog.views.IlvTransformer; import ilog.views.graphlayout.GraphLayoutEvent; import ilog.views.graphlayout.GraphLayoutEventListener; import ilog.views.graphlayout.IlvGraphLayout; import ilog.views.graphlayout.IlvGraphLayoutException; import ilog.views.graphlayout.IlvGraphLayoutReport; import ilog.views.graphlayout.IlvGrapherAdapter; import ilog.views.graphlayout.random.IlvRandomLayout; import ilog.views.graphlayout.tree.IlvTreeLayout; import ilog.views.interactor.IlvSelectInteractor; import ilog.views.interactor.IlvZoomViewInteractor; import ilog.views.swing.IlvJManagerViewControlBar; import ilog.views.swing.IlvJScrollManagerView; import ilog.views.util.IlvLocaleUtil; import ilog.views.util.IlvProductUtil; import ilog.views.util.IlvResourceUtil; import ilog.views.util.swing.IlvJComboBox; import ilog.views.util.swing.IlvJSpinnerDecimalNumberField; import ilog.views.util.swing.IlvSwingUtil; /** * This is a very simple application that uses the * <code>IlvGrapher</code> to perform a tree layout. It shows how to use tree * layout in applications that are not based on CSS styling. */ public class TreeLayoutApp 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 Tree Layout algorithm */ IlvTreeLayout layout = new IlvTreeLayout(); /** An instance of the Random Layout algorithm */ IlvRandomLayout randomLayout = new IlvRandomLayout(); /** A graph layout event listener */ LayoutIterationListener layoutListener = new LayoutIterationListener(); /** A text field to display messages */ JTextField msgLine = new JTextField(); /** The flow direction selector */ SuppressWarnings("unchecked") JComboBox<String> flowDirectionSelector = new IlvJComboBox(); /** The link style selector */ SuppressWarnings("unchecked") JComboBox<String> linkStyleSelector = new IlvJComboBox(); /** The layout mode selector */ SuppressWarnings("unchecked") JComboBox<String> layoutModeSelector = new IlvJComboBox(); /** The default offset */ static final double DEFAULT_OFFSET = 20.; /** Fields for the offset parameters */ IlvJSpinnerDecimalNumberField branchOffsetSelector = new IlvJSpinnerDecimalNumberField(0, 200, DEFAULT_OFFSET, true, 6, 5); IlvJSpinnerDecimalNumberField siblingOffsetSelector = new IlvJSpinnerDecimalNumberField(0, 200, DEFAULT_OFFSET, true, 6, 5); IlvJSpinnerDecimalNumberField parentOffsetSelector = new IlvJSpinnerDecimalNumberField(0, 200, DEFAULT_OFFSET, true, 6, 5); IlvJSpinnerDecimalNumberField startAngleSelector = new IlvJSpinnerDecimalNumberField(0, 360, 0, false, 3, 2); IlvJSpinnerDecimalNumberField rootAngleRangeSelector = new IlvJSpinnerDecimalNumberField(1, 360, 360, false, 3, 10); IlvJSpinnerDecimalNumberField innerAngleRangeSelector = new IlvJSpinnerDecimalNumberField(1, 360, 360, false, 3, 10); IlvJSpinnerDecimalNumberField leafAngleRangeSelector = new IlvJSpinnerDecimalNumberField(1, 360, 360, false, 3, 10); /** whether we show east-west neighboring */ boolean useNeighboring = true; boolean lastUseNeighboring = false; /** the last specified root node */ IlvGraphic oldRootNode = null; /** 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() { showMessage(getString("InitMessage")); // attach the grapher to the layout instances IlvGrapherAdapter adapter = new IlvGrapherAdapter(grapher); layout.attach(adapter); randomLayout.attach(adapter); // install the layout iteration listener on the layout instance layout.addGraphLayoutEventListener(layoutListener); // change the default option for the links style layout.setGlobalLinkStyle(IlvTreeLayout.ORTHOGONAL_STYLE); // change the default flow direction layout.setFlowDirection(IlvDirection.Bottom); // set the aspect ratio to the approximate size of the window layout.setAspectRatio(1.5); // use manager coordinates layout.setCoordinatesMode(IlvGraphLayout.MANAGER_COORDINATES); randomLayout.setCoordinatesMode(IlvGraphLayout.MANAGER_COORDINATES); // 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.002, 10.0); mgrview.setWheelZoomingEnabled(true); scrollManView.setWheelScrollingEnabled(true); // Settings parameters for selection handles IlvHandlesSelection.defaultHandleColor = Color.black; IlvHandlesSelection.defaultHandleBackgroundColor = Color.white; IlvHandlesSelection.defaultHandleShape = IlvHandlesSelection.SQUARE_SHAPE; // create the standard control bar IlvJManagerViewControlBar controlBar = new IlvJManagerViewControlBar(); controlBar.setView(mgrview); // modify the interactors such that the demo looks better ((IlvSelectInteractor) controlBar.getSelectInteractor()).setOpaqueMove(true); ((IlvZoomViewInteractor) controlBar.getZoomViewInteractor()).setPermanent(true); // set the initial interactor mgrview.setInteractor(controlBar.getSelectInteractor()); // create the graph selector SuppressWarnings("unchecked") JComboBox<String> fileSelector = new IlvJComboBox(); 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(); loadGrapher(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) { layout(randomLayout, grapher); } }); // 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 setOffsetOrAngle("branchOffset", branchOffsetSelector); setOffsetOrAngle("siblingOffset", siblingOffsetSelector); setOffsetOrAngle("parentChildOffset", parentOffsetSelector); setOffsetOrAngle("startAngle", startAngleSelector); setOffsetOrAngle("rootAngle", rootAngleRangeSelector); setOffsetOrAngle("innerAngle", innerAngleRangeSelector); setOffsetOrAngle("leafAngle", leafAngleRangeSelector); // now the layout preprocess(); layout(layout, grapher); } }); 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(controlBar); 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 manager view, top panel and bottom panel together getContentPane().setLayout(new BorderLayout(0, 0)); getContentPane().add(scrollManView, 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); // load a sample grapher loadGrapher("small"); } /** * 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.LINE_END; 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; SuppressWarnings("unchecked") JComboBox<String> balloonAngleSpacingSelector = new IlvJComboBox(); 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; SuppressWarnings("unchecked") JComboBox<String> balloonRadiusModeSelector = new IlvJComboBox(); 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("BranchOffset.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("startAngle", (IlvJSpinnerDecimalNumberField) e.getSource()); } }); rootAngleRangeSelector.setToolTipText(getString("RootAngleRange.Tooltip")); rootAngleRangeSelector.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { setOffsetOrAngle("rootAngle", (IlvJSpinnerDecimalNumberField) e.getSource()); } }); innerAngleRangeSelector.setToolTipText(getString("InnerAngleRange.Tooltip")); innerAngleRangeSelector.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { setOffsetOrAngle("innerAngle", (IlvJSpinnerDecimalNumberField) e.getSource()); } }); leafAngleRangeSelector.setToolTipText(getString("LeafAngleRange.Tooltip")); leafAngleRangeSelector.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { setOffsetOrAngle("leafAngle", (IlvJSpinnerDecimalNumberField) 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. */ SuppressWarnings("unchecked") private JPanel createNormalParameterPanel() { JPanel panel = new JPanel(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.LINE_END; 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 IlvJComboBox(); panel.add(layoutModeSelector, c); layoutModeSelector.addItem(getString("LayoutMode.FreeMode")); layoutModeSelector.addItem(getString("LayoutMode.FreeNeiMode")); layoutModeSelector.addItem(getString("LayoutMode.LevelMode")); layoutModeSelector.addItem(getString("LayoutMode.TipOverMode")); layoutModeSelector.addItem(getString("LayoutMode.BalloonMode")); layoutModeSelector.addItem(getString("LayoutMode.RadialMode")); layoutModeSelector.addItem(getString("LayoutMode.RadialNeiMode")); layoutModeSelector.addItem(getString("LayoutMode.AltRadialMode")); layoutModeSelector.setSelectedIndex(1); layoutModeSelector.setToolTipText(getString("LayoutMode.Tooltip")); layoutModeSelector.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent event) { 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) { 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) { 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 IlvJComboBox(); 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) { 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("SiblingOffset.Tooltip")); panel.add(label, c); c.gridy = 2; label = new JLabel(getString("BranchOffset.Label")); label.setToolTipText(getString("BranchOffset.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("BranchOffset.Tooltip")); branchOffsetSelector.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { setOffsetOrAngle("branchOffset", (IlvJSpinnerDecimalNumberField) e.getSource()); } }); siblingOffsetSelector.setToolTipText(getString("SiblingOffset.Tooltip")); siblingOffsetSelector.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { setOffsetOrAngle("siblingOffset", (IlvJSpinnerDecimalNumberField) e.getSource()); } }); parentOffsetSelector.setToolTipText(getString("ParentChildOffset.Tooltip")); parentOffsetSelector.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { setOffsetOrAngle("parentChildOffset", (IlvJSpinnerDecimalNumberField) 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.LINE_END; 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(); } } /** * Sets the layout mode. */ private void setLayoutMode(String mode) { layout.setAspectRatio(1.5); if (mode.equals(getString("LayoutMode.FreeMode"))) { layout.setLayoutMode(IlvTreeLayout.FREE); useNeighboring = false; flowDirectionSelector.setEnabled(true); linkStyleSelector.setEnabled(true); installParameterPanel(normalPanel); } else if (mode.equals(getString("LayoutMode.FreeNeiMode"))) { layout.setLayoutMode(IlvTreeLayout.FREE); useNeighboring = true; flowDirectionSelector.setEnabled(true); linkStyleSelector.setEnabled(true); installParameterPanel(normalPanel); } else if (mode.equals(getString("LayoutMode.LevelMode"))) { layout.setLayoutMode(IlvTreeLayout.LEVEL); useNeighboring = false; flowDirectionSelector.setEnabled(true); linkStyleSelector.setEnabled(true); installParameterPanel(normalPanel); } else if (mode.equals(getString("LayoutMode.TipOverMode"))) { layout.setLayoutMode(IlvTreeLayout.TIP_LEAVES_OVER); useNeighboring = false; flowDirectionSelector.setEnabled(true); linkStyleSelector.setEnabled(true); installParameterPanel(normalPanel); } else if (mode.equals(getString("LayoutMode.BalloonMode"))) { layout.setLayoutMode(IlvTreeLayout.BALLOON); useNeighboring = false; flowDirectionSelector.setEnabled(false); linkStyleSelector.setEnabled(false); installParameterPanel(balloonPanel); layout.setAspectRatio(1.0); } else if (mode.equals(getString("LayoutMode.RadialMode"))) { layout.setLayoutMode(IlvTreeLayout.RADIAL); useNeighboring = false; flowDirectionSelector.setEnabled(false); linkStyleSelector.setEnabled(false); installParameterPanel(normalPanel); } else if (mode.equals(getString("LayoutMode.RadialNeiMode"))) { layout.setLayoutMode(IlvTreeLayout.RADIAL); useNeighboring = true; flowDirectionSelector.setEnabled(false); linkStyleSelector.setEnabled(false); installParameterPanel(normalPanel); } else if (mode.equals(getString("LayoutMode.AltRadialMode"))) { layout.setLayoutMode(IlvTreeLayout.ALTERNATING_RADIAL); useNeighboring = false; flowDirectionSelector.setEnabled(false); linkStyleSelector.setEnabled(false); installParameterPanel(normalPanel); } if (autoLayout) layout(layout, grapher); } /** * Sets the flow direction. */ private void setFlowDirection(String flow) { if (flow.equals(getString("FlowDirection.Top"))) layout.setFlowDirection(IlvDirection.Top); else if (flow.equals(getString("FlowDirection.Bottom"))) layout.setFlowDirection(IlvDirection.Bottom); else if (flow.equals(getString("FlowDirection.Left"))) layout.setFlowDirection(IlvDirection.Left); else if (flow.equals(getString("FlowDirection.Right"))) layout.setFlowDirection(IlvDirection.Right); if (autoLayout) layout(layout, grapher); } /** * Sets the global link style. */ private void setGlobalLinkStyle(String style) { if (style.equals(getString("LinkStyle.Orthogonal"))) layout.setGlobalLinkStyle(IlvTreeLayout.ORTHOGONAL_STYLE); else if (style.equals(getString("LinkStyle.Straight"))) layout.setGlobalLinkStyle(IlvTreeLayout.STRAIGHT_LINE_STYLE); else if (style.equals(getString("LinkStyle.Mixed"))) layout.setGlobalLinkStyle(IlvTreeLayout.MIXED_STYLE); if (autoLayout) layout(layout, grapher); } /** * Sets the global alignment. */ private void setGlobalAlignment(String alignment) { if (alignment.equals(getString("Alignment.Center"))) layout.setGlobalAlignment(IlvTreeLayout.CENTER); else if (alignment.equals(getString("Alignment.East"))) layout.setGlobalAlignment(IlvTreeLayout.EAST); else if (alignment.equals(getString("Alignment.West"))) layout.setGlobalAlignment(IlvTreeLayout.WEST); else if (alignment.equals(getString("Alignment.TipOver"))) layout.setGlobalAlignment(IlvTreeLayout.TIP_OVER); if (autoLayout) layout(layout, grapher); } /** * Sets the angle spacing mode in balloon mode. */ private void setBalloonAngleSpacing(String mode) { if (mode.equals(getString("AngleSpacing.RegularMode"))) layout.setBalloonAngleSpacing(IlvTreeLayout.REGULAR); else if (mode.equals(getString("AngleSpacing.FastPropMode"))) layout.setBalloonAngleSpacing(IlvTreeLayout.FAST_PROPORTIONAL); else if (mode.equals(getString("AngleSpacing.SlowPropMode"))) layout.setBalloonAngleSpacing(IlvTreeLayout.PROPORTIONAL); if (autoLayout) layout(layout, grapher); } /** * Sets the radius mode in balloon mode. */ private void setBalloonRadiusMode(String mode) { if (mode.equals(getString("RadiusMode.VarMode"))) layout.setBalloonRadiusMode(IlvTreeLayout.VARIABLE_RADIUS); else if (mode.equals(getString("RadiusMode.OptVarMode"))) layout.setBalloonRadiusMode(IlvTreeLayout.OPTIMIZED_VARIABLE_RADIUS); else if (mode.equals(getString("RadiusMode.UniLfMode"))) layout.setBalloonRadiusMode(IlvTreeLayout.UNIFORM_LEAVES_RADIUS); else if (mode.equals(getString("RadiusMode.OptUniLfMode"))) layout.setBalloonRadiusMode(IlvTreeLayout.OPTIMIZED_UNIFORM_LEAVES_RADIUS); else if (mode.equals(getString("RadiusMode.UniMode"))) layout.setBalloonRadiusMode(IlvTreeLayout.UNIFORM_RADIUS); if (autoLayout) layout(layout, grapher); } /** * Sets the sibling, branch or parent/child offset from a textfield. */ private void setOffsetOrAngle(String property, IlvJSpinnerDecimalNumberField valueSelector) { double value = valueSelector.getDoubleValue(); // set the new value of the layout property if (property.equals("branchOffset")) layout.setBranchOffset(value); else if (property.equals("siblingOffset")) layout.setSiblingOffset( value); else if (property.equals("parentChildOffset")) layout.setParentChildOffset( value); else if (property.equals("startAngle")) layout.setBalloonStartAngle((int) value); else if (property.equals("rootAngle")) layout.setBalloonRootChildrenAngle((int) value); else if (property.equals("innerAngle")) layout.setBalloonInnerChildrenAngle((int) value); else if (property.equals("leafAngle")) layout.setBalloonLeafChildrenAngle((int) value); if (autoLayout) layout(layout, grapher); } /** * Performs the layout of the graph. */ private void layout(IlvGraphLayout layout, IlvGrapher grapher) { // the layout report instance; this is an object in which // the layout algorithm stores information about its behavior IlvGraphLayoutReport layoutReport = null; showMessage(getString("LayoutStartMessage")); // initialize the iteration listener layoutListener.initialize(); try { // perform the layout and get the layout report layoutReport = layout.performLayout(false, false); // print the code from the layout report showMessage(getString("LayoutDoneMessage"), layoutReport.codeToString(layoutReport.getCode(), IlvLocaleUtil.getCurrentULocale())); } catch (IlvGraphLayoutException e) { // e.printStackTrace(); showMessage(e.getMessage()); } finally { if (layoutReport != null && layoutReport.getCode() != IlvGraphLayoutReport.NOT_NEEDED) { // show all if (autoFit) mgrview.fitTransformerToContent(); mgrview.repaint(); } } } /** * 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.setTransformer(new IlvTransformer()); grapher.reDraw(); // just to be sure layout info is cleaned before the next layout lastUseNeighboring = !useNeighboring; oldRootNode = null; showMessage(getString("FileReadingDoneMessage"), fileNameBase); } catch (Exception e) { // e.printStackTrace(); showMessage(e.getMessage()); } } /** * Preprocess graph: Add some local parameters for demonstration purpose. */ void preprocess() { IlvGraphicEnumeration objects; IlvGraphic obj; IlvGraphic rootNode = null; // get the root node: if a node is selected, this is our root IlvGraphicEnumeration selectedObjects = grapher.getSelectedObjects(); while (selectedObjects.hasMoreElements()) { obj = selectedObjects.nextElement(); if (grapher.isNode(obj)) { rootNode = obj; break; } } // clean all information at nodes if (oldRootNode != rootNode || useNeighboring != lastUseNeighboring) { objects = grapher.getObjects(); while (objects.hasMoreElements()) { obj = objects.nextElement(); if (grapher.isNode(obj)) { layout.setRootPreference(obj, -1); layout.setEastWestNeighboring(obj, null); layout.setEastWestNeighboring(null, obj); } } } // set the selected root node if (rootNode != null) layout.setRoot(rootNode); // sets some local layout parameters. The color decides which parameter // is used at which node and link. objects = grapher.getObjects(); while (objects.hasMoreElements()) { obj = objects.nextElement(); if (grapher.isLink(obj)) { IlvLinkImage link = (IlvLinkImage) obj; if (link.getForeground().equals(Color.red)) { layout.setLinkStyle(obj, IlvTreeLayout.STRAIGHT_LINE_STYLE); } else if (link.getForeground().equals(Color.green)) { layout.setLinkStyle(obj, IlvTreeLayout.ORTHOGONAL_STYLE); if (useNeighboring && !lastUseNeighboring) { if (layout.getEastNeighbor(link.getFrom()) == null && layout.getWestNeighbor(link.getTo()) == null) layout.setEastWestNeighboring(link.getTo(), link.getFrom()); else layout.setEastWestNeighboring(link.getFrom(), link.getTo()); } } else { layout.setLinkStyle(obj, IlvTreeLayout.ORTHOGONAL_STYLE); } } } lastUseNeighboring = useNeighboring; oldRootNode = rootNode; } /** * 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[] arg) { // Sun recommends that to put the entire GUI initialization into the // AWT thread 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 { 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 by reseting the toShow variable. This method must * be called before the layout is started. */ void initialize() { oldPercentage = -1.0f; } } }