/* * 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.SystemColor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.MessageFormat; import java.util.Locale; 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.IlvPoint; import ilog.views.IlvTransformer; import ilog.views.diagrammer.IlvDiagrammer; import ilog.views.diagrammer.application.IlvDiagrammerViewBar; 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.IlvJComboBox; import ilog.views.util.swing.IlvSwingUtil; /** * This is a very simple application that uses the * <code>IlvDiagrammer</code> to perform a rotated layout. It uses the rotation * angle feature of the graph layout renderer. It loads a style sheet containing * the layout specification. It allows to set various layout parameters by using * the <code>IlvSDMMutableStyleSheet</code>. */ public class RotatedLayoutApp extends JRootPane { { // This sample uses JViews Diagrammer features. When deploying an // application that includes this code, you need // a Perforce JViews Diagrammer Deployment license. IlvProductUtil.DeploymentLicenseRequired(IlvProductUtil.JViews_Diagrammer_Deployment); } /** The diagrammer */ IlvDiagrammer diagrammer = new IlvDiagrammer(); /** The style sheet for temporary changes */ IlvSDMMutableStyleSheet styleSheet = new IlvSDMMutableStyleSheet(diagrammer.getEngine(), true, false); /** The display names of the samples */ String[] sampleNames; /** The base file names of the samples (excluding the .xml or .css */ String[] fileNames; /** The shear modes: the values must be the index in the combo box. */ final static int UNSHEARED = 0; final static int SHEAR_X = 1; final static int SHEAR_Y = 2; /** Whether the rotation is a shear in X direction. */ int shearMode = UNSHEARED; /** A text field to display messages */ JTextField msgLine = new JTextField(); /** The default angle */ static final double DEFAULT_ANGLE = 30.; /** Fields for the offset parameters */ NumberField rotationAngleSelector = new NumberField(-45, 45, DEFAULT_ANGLE, false, 6, 1); /** * 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); // initialize the sample names initSampleNames(); // create the file selector SuppressWarnings("unchecked") JComboBox<String> fileSelector = new IlvJComboBox(); for (int i = 0; i < sampleNames.length; i++) fileSelector.addItem(sampleNames[i]); 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 sampleName = (String) comboBox.getSelectedItem(); for (int i = 0; i < sampleNames.length; i++) if (sampleNames[i].equals(sampleName)) loadSample(i); } }); // 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 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 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); // set the initial rotation angle styleSheet.setDeclaration("GraphLayout", "rotationAngle", "" + DEFAULT_ANGLE); // load the initial sample loadSample(0); diagrammer.getView().fitTransformerToContent(true); } /** * Initialize the information about the samples. */ private void initSampleNames() { sampleNames = new String[4]; fileNames = new String[4]; sampleNames[0] = getString("Sample.TreeLayout"); fileNames[0] = "tree"; sampleNames[1] = getString("Sample.HierarchicalLayout"); fileNames[1] = "hierarchical"; sampleNames[2] = getString("Sample.GridLayout"); fileNames[2] = "grid"; sampleNames[3] = getString("Sample.TMLLayout"); fileNames[3] = "tml"; } /** * Creates the layout parameter panel. */ private JPanel createParameterPanel() { JPanel panel = new JPanel(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.EAST; panel.setLayout(gridbag); // rotation angle parameter c.gridx = 0; c.gridy = 0; JLabel label = new JLabel(getString("RotationAngle.Label")); label.setToolTipText(getString("RotationAngle.Tooltip")); panel.add(label, c); c.gridx = 1; panel.add(rotationAngleSelector, c); rotationAngleSelector.setToolTipText(getString("RotationAngle.Tooltip")); rotationAngleSelector.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { setRotationAngle((NumberField) e.getSource()); } }); // spacer c.gridx = 2; panel.add(new JLabel(" ")); // rotation angle parameter c.gridx = 3; label = new JLabel(getString("ShearMode.Label")); label.setToolTipText(getString("ShearMode.Tooltip")); panel.add(label, c); c.gridx = 4; SuppressWarnings("unchecked") JComboBox<String> shearModeSelector = new IlvJComboBox(); shearModeSelector.addItem(getString("ShearMode.Unsheared")); shearModeSelector.addItem(getString("ShearMode.ShearX")); shearModeSelector.addItem(getString("ShearMode.ShearY")); shearModeSelector.setToolTipText(getString("ShearMode.Tooltip")); shearModeSelector.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent event) { SuppressWarnings("unchecked") JComboBox<String> comboBox = (JComboBox<String>) event.getSource(); shearMode = comboBox.getSelectedIndex(); setRotationAngle(rotationAngleSelector); } }); panel.add(shearModeSelector, c); // set the component orientation according to the locale Locale loc = IlvSwingUtil.getDefaultLocale(); ComponentOrientation co = ComponentOrientation.getOrientation(loc); panel.applyComponentOrientation(co); return panel; } /** * Load a sample file. It loads both the XML file and the style file. * * @param index * The index of the sample file. */ private void loadSample(int index) { String fileNameBase = fileNames[index]; try { showMessage(getString("FileReadingStartMessage"), fileNameBase); // load an empty file. This avoids that we get temporary styling // warnings because the data and css files don't match eachother diagrammer.setDataFile(IlvSwingUtil.getRelativeURL(this, "data/empty.xml")); // load the style file diagrammer.setStyleSheet(IlvSwingUtil.getRelativeURL(this, "data/" + fileNameBase + ".css")); // load a mutable style file that we use for temporary style changes diagrammer.getEngine().setStyleSheets(1, styleSheet.toString()); // load the data file diagrammer.setDataFile(IlvSwingUtil.getRelativeURL(this, "data/" + fileNameBase + ".xml")); // zoom to fit diagrammer.fitToContents(); showMessage(getString("FileReadingDoneMessage"), fileNameBase); } catch (Exception e) { showMessage(e.getMessage()); } } /** * Sets the rotation angle of the rotated model. */ private void setRotationAngle(NumberField valueSelector) { styleSheet.setAdjusting(true); try { IlvTransformer t; double D; double angle = valueSelector.getValue(); switch (shearMode) { case UNSHEARED: styleSheet.removeDeclaration("GraphLayout", "rotationTransformer"); styleSheet.setDeclaration("GraphLayout", "rotationAngle", "" + angle); break; case SHEAR_X: t = new IlvTransformer(new IlvPoint(), angle); t.setValues(t.getx11(), 0, t.getx21(), t.getx22(), t.getx0(), t.gety0()); D = t.getDeterminant(); t.setValues(t.getx11() / D, t.getx12() / D, t.getx21() / D, t.getx22() / D, t.getx0(), t.gety0()); styleSheet.removeDeclaration("GraphLayout", "rotationAngle"); styleSheet.setDeclaration("GraphLayout", "rotationTransformer", "" + t.getx11() + "," + t.getx12() + "," + t.getx21() + "," + t.getx11() + "," + t.getx0() + "," + t.gety0()); break; case SHEAR_Y: t = new IlvTransformer(new IlvPoint(), angle); t.setValues(t.getx11(), t.getx12(), 0, t.getx22(), t.getx0(), t.gety0()); D = t.getDeterminant(); t.setValues(t.getx11() / D, t.getx12() / D, t.getx21() / D, t.getx22() / D, t.getx0(), t.gety0()); styleSheet.removeDeclaration("GraphLayout", "rotationAngle"); styleSheet.setDeclaration("GraphLayout", "rotationTransformer", "" + t.getx11() + "," + t.getx12() + "," + t.getx21() + "," + t.getx11() + "," + t.getx0() + "," + t.gety0()); break; } } finally { styleSheet.setAdjusting(false); diagrammer.fitToContents(); } } /** * 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)); } /** * Returns a string. */ static String getString(String key) { return IlvResourceUtil.getString(key, RotatedLayoutApp.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() { RotatedLayoutApp app = new RotatedLayoutApp(); 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); } }); } }