/* * Licensed Materials - Property of Rogue Wave Software, Inc. * © Copyright Rogue Wave Software, Inc. 2014, 2015 * © 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 ilog.views.diagrammer.IlvDiagrammer; import ilog.views.diagrammer.application.IlvDiagrammerViewBar; import ilog.views.diagrammer.application.IlvDiagrammerAction; import ilog.views.sdm.IlvSDMEngine; import ilog.views.sdm.renderer.graphlayout.IlvGraphLayoutRenderer; import ilog.views.sdm.util.IlvSDMMutableStyleSheet; import ilog.views.graphlayout.IlvGraphLayout; import ilog.views.graphlayout.IlvGraphLayoutReport; import ilog.views.graphlayout.GraphLayoutEvent; import ilog.views.graphlayout.GraphLayoutEventListener; import ilog.views.graphlayout.random.IlvRandomLayout; import ilog.views.util.IlvProductUtil; import ilog.views.util.swing.IlvSwingUtil; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.URL; /** * This is a very simple applet/application that uses the * <code>IlvDiagrammer</code> to perform a bus layout. * It loads a style sheet containing the bus layout specification. * It allows to set various bus layout parameters by using the * <code>IlvSDMMutableStyleSheet</code>. */ public class BusLayoutApplet extends JApplet { { // 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); /** * Initializes the applet/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.02f); diagrammer.setMaximumZoom(10f); diagrammer.getView().setBackground(Color.white); diagrammer.getView().setForeground(SystemColor.windowText); // create the file selector JComboBox fileSelector = new JComboBox(); fileSelector.addItem("small"); fileSelector.addItem("medium"); fileSelector.addItem("large"); fileSelector.setToolTipText("Select a sample graph"); fileSelector.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { JComboBox comboBox = (JComboBox)event.getSource(); String fileName = (String)comboBox.getSelectedItem(); loadDataFile(fileName); } }); // create the layout button JButton layoutButton = new JButton("Layout"); layoutButton.setToolTipText("Perform a bus layout"); layoutButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { performLayout(); }}); // create the panel for the layout buttons JPanel layoutButtonPanel = new JPanel(); layoutButtonPanel.setLayout(new FlowLayout()); layoutButtonPanel.add(layoutButton); addFurtherCheckboxes(layoutButtonPanel); // create the top panel with the toolbar and the file selector JPanel topPanel = new JPanel(); topPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); topPanel.add(toolbar); topPanel.add(new JLabel("Select graph:")); topPanel.add(fileSelector); // 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(createParameterPanel(), 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); try { // load the main style file diagrammer.setStyleSheet( IlvSwingUtil.getRelativeURL(this, "data/bus.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); } /** * Called when this applet is being reclaimed in order to destroy * any resources that it has allocated. */ public void destroy() { super.destroy(); // This method is intended to workaround memory management issues // in the Sun JRE. Please refer to the method documentation for more // details and a description of the known issues. IlvSwingUtil.cleanupApplet(); } /** * Adds further checkboxes near the layout button. */ private void addFurtherCheckboxes(JPanel panel) { // some space panel.add(new JLabel(" ")); JCheckBox incrementalOption = new JCheckBox("Incremental", false); panel.add(incrementalOption); incrementalOption.setToolTipText("Enable or disable the incremental mode"); incrementalOption.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { setIncrementalMode(e.getStateChange() == ItemEvent.SELECTED); } }); JCheckBox preserveFixedNodesOption = new JCheckBox("Fix Selected", false); panel.add(preserveFixedNodesOption); preserveFixedNodesOption.setToolTipText( "Enable or disable that selected nodes don't move"); preserveFixedNodesOption.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { setSelectedAreFixed(e.getStateChange() == ItemEvent.SELECTED); } }); } /** * Creates the layout parameter panel. */ private JPanel createParameterPanel() { JPanel panel = new JPanel(); panel.setLayout(new GridLayout(3, 2)); // alignment paranter JComboBox vAlignmentSelector = new JComboBox(); panel.add(new JLabel("Vertical Alignment:")); panel.add(vAlignmentSelector); vAlignmentSelector.setToolTipText("Select the vertical alignment"); vAlignmentSelector.addItem("Center"); vAlignmentSelector.addItem("Top"); vAlignmentSelector.addItem("Bottom"); vAlignmentSelector.setSelectedIndex(0); vAlignmentSelector.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { JComboBox comboBox = (JComboBox)event.getSource(); String alignment = (String)comboBox.getSelectedItem(); setVerticalAlignment(alignment); } }); // ordering of the nodes JComboBox orderSelector = new JComboBox(); panel.add(new JLabel("Node Order:")); panel.add(orderSelector); orderSelector.setToolTipText("Select the node ordering"); orderSelector.addItem("Arbitrary"); orderSelector.addItem("By label"); orderSelector.addItem("By height"); orderSelector.setSelectedIndex(2); orderSelector.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { JComboBox comboBox = (JComboBox)event.getSource(); String ordering = (String)comboBox.getSelectedItem(); setOrdering(ordering); } }); // flow direction parameter JComboBox flowDirectionSelector = new JComboBox(); panel.add(new JLabel("Node Flow Direction:")); panel.add(flowDirectionSelector); flowDirectionSelector.addItem("Left to right"); flowDirectionSelector.addItem("Alternate"); flowDirectionSelector.setSelectedIndex(0); flowDirectionSelector.setToolTipText("Select the node flow direction"); flowDirectionSelector.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { JComboBox comboBox = (JComboBox)event.getSource(); String flow = (String)comboBox.getSelectedItem(); setFlowDirection(flow); } }); return panel; } /** * 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("Reading " + fileNameBase + ".xml ..."); diagrammer.setDataFile( IlvSwingUtil.getRelativeURL(this, "data/" + fileNameBase + ".xml")); showMessage("Reading " + fileNameBase + ".xml done."); } catch (Exception e) { showMessage(e.getMessage()); } } /** * Sets the incremental mode. */ private void setIncrementalMode(boolean flag) { styleSheet.setDeclaration("GraphLayout", "incrementalMode", (flag ? "true" : "false")); } /** * Sets whether nodes specified as fixes (that is, nodes that are selected) * are really fixed. */ private void setSelectedAreFixed(boolean flag) { // don't set preserveFixedNodes because it is automatically set by // the graph layout renderer depending on the existence of the Fixed // property on a node. styleSheet.setDeclaration("node:selected", "Fixed", (flag ? "true" : "false")); } /** * Sets the vertical node alignment. */ private void setVerticalAlignment(String alignment) { if (alignment.equals("Center")) styleSheet.setDeclaration("GraphLayout", "globalVerticalAlignment", "CENTER"); else if (alignment.equals("Top")) styleSheet.setDeclaration("GraphLayout", "globalVerticalAlignment", "TOP"); else if (alignment.equals("Bottom")) styleSheet.setDeclaration("GraphLayout", "globalVerticalAlignment", "BOTTOM"); } /** * Sets the node ordering mode. */ private void setOrdering(String ordering) { if (ordering.equals("Arbitrary")) styleSheet.setDeclaration("GraphLayout", "ordering", "NO_ORDERING"); else if (ordering.equals("By label")) styleSheet.setDeclaration("GraphLayout", "ordering", "ORDER_BY_INDEX"); else if (ordering.equals("By height")) styleSheet.setDeclaration("GraphLayout", "ordering", "ORDER_BY_HEIGHT"); } /** * Sets the flow direction of nodes. */ private void setFlowDirection(String flow) { if (flow.equals("Left to right")) styleSheet.setDeclaration("GraphLayout", "flowDirection", "LEFT_TO_RIGHT"); else if (flow.equals("Alternate")) styleSheet.setDeclaration("GraphLayout", "flowDirection", "ALTERNATE"); } /** * Performs the bus layout. * The layout type is stored in the CSS file, therefore we don't need to * set the bus layout explicitely. After loading the graph and the CSS * style sheet, the bus layout is already instantiated. */ private void performLayout() { showMessage("Layout started..."); // initialize the iteration listener layoutListener.initialize(getGraphLayout()); // Perform Bus Layout as node layout. Bus 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(report.codeToString(report.getCode()) + "."); } } } /** * Returns the graph layout currently used by the diagrammer. */ private IlvGraphLayout getGraphLayout() { IlvGraphLayoutRenderer renderer = (IlvGraphLayoutRenderer)diagrammer.getEngine().getNodeLayoutRenderer(); return renderer == null ? null : renderer.getGraphLayout(); } /** * 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()); } /** * Allows you to run the demo as a standalone application. */ public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { BusLayoutApplet applet = new BusLayoutApplet(); applet.init(); JFrame frame = new JFrame("Bus Layout Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(400, 500); frame.getContentPane().add(applet); 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 a dot each time the method * layoutStepPerformed is called, that is after each iteration of * the Bus Layout algorithm. */ class LayoutIterationListener implements GraphLayoutEventListener { private IlvGraphLayout layout; private String toShow = ""; private static final int MAX_LENGTH = 50; /** * This method is automatically called by the layout algorithm. */ public void layoutStepPerformed(GraphLayoutEvent event) { // the status area has a limited width, so we are forced to // reinitialize the message string if (toShow.length() > MAX_LENGTH) toShow = ""; toShow += "."; showMessage(toShow); } /** * 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); } toShow = ""; } } }