/* * 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.FlowLayout; import java.awt.SystemColor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; import ilog.views.IlvGrapher; import ilog.views.IlvGraphic; import ilog.views.IlvGraphicEnumeration; import ilog.views.IlvHandlesSelection; 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.graphic.IlvZoomableLabel; import ilog.views.linkconnector.IlvClippingLinkConnector; import ilog.views.swing.IlvJScrollManagerView; //import ilog.views.util.IlvProductUtil; import ilog.views.util.IlvResourceUtil; /** * This is a very simple application that shows how to implement * facilities to find nodes and to center them in the view. */ SuppressWarnings("serial") public class FindInViewApp extends JRootPane { IlvGrapher grapher; IlvManagerView mgrview; IlvZoomableLabel node; boolean animate = true; { // This sample uses JViews Diagrammer features. When deploying an // application that includes this code, you need to be in possession // of a Perforce JViews Diagrammer Deployment license. // IlvProductUtil.DeploymentLicenseRequired( // IlvProductUtil.JViews_Diagrammer_Deployment); } /** * Initializes the application. */ public void init() { // create a grapher grapher = new IlvGrapher(); // create a manager view mgrview = new IlvManagerView(grapher); // 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); // Settings parameters for selection handles IlvHandlesSelection.defaultHandleColor = Color.red; IlvHandlesSelection.defaultHandleBackgroundColor = Color.green; IlvHandlesSelection.defaultHandleShape = IlvHandlesSelection.SQUARE_SHAPE; // Now, fill the grapher generateBinTree(10, 11, 1); // create a textfield that allows to search for nodes JTextField searchField = new JTextField("", 8); searchField.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { JTextField source = (JTextField)e.getSource(); try { int num = Integer.valueOf(source.getText().trim()).intValue(); if (!find(num)) JOptionPane.showMessageDialog(FindInViewApp.this, "Node " + num + " not found!"); } catch (Exception ex) { source.setText(""); } } }); // create a checkbox that allows to disable the animation JCheckBox useAnimation = new JCheckBox("Animation", true); useAnimation.setToolTipText( "Enable or disable the animation during search"); useAnimation.addItemListener(new ItemListener() { Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) animate = true; else if (e.getStateChange() == ItemEvent.DESELECTED) animate = false; } }); // create the top panel with the toolbar and the pop-up checkbox JPanel topPanel = new JPanel(); topPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); topPanel.add(new JLabel("Search for: ")); topPanel.add(searchField); topPanel.add(new JLabel(" ")); topPanel.add(useAnimation); // 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); mgrview.setDoubleBuffering(true); mgrview.setTransformer(new IlvTransformer(1.5, 0, 0, 1.2, 0, 0)); } /** * Creates a balanced binary tree. * @param leftPos The leftmost position allowed for the tree. * @param depth The depth of the tree. * @param i The number of the root of the tree. * @return The rightmost position of the tree. */ private double generateBinTree(double leftPos, int depth, int i) { if (depth == 0) { double x = leftPos; double y = 300-depth * 80; node = new IlvZoomableLabel(new IlvPoint(x,y), "" + i, false); setNodeAttributes(node); grapher.addNode(node, true); IlvRect bbox = node.boundingBox(); return bbox.x + bbox.width; } else { int r = 1; for (int k = 0; k < depth; k++) r = 2 * r; double maxLeft = generateBinTree(leftPos, depth-1, i + 1); IlvGraphic leftRoot = node; double maxRight = generateBinTree(maxLeft + 25, depth-1, i + r); IlvGraphic rightRoot = node; double x = (leftPos + maxRight) / 2; double y = 300-depth * 80; node = new IlvZoomableLabel(new IlvPoint(x,y), "" + i, false); IlvRect bbox = node.boundingBox(); node.translate(-bbox.width/2, 0); setNodeAttributes(node); grapher.addNode(node, true); IlvLinkImage link1 = new IlvLinkImage(node, leftRoot, true); IlvLinkImage link2 = new IlvLinkImage(node, rightRoot, true); grapher.addLink(link1, true); grapher.addLink(link2, true); return maxRight; } } /** * Sets the attributes of a node. */ private void setNodeAttributes(IlvZoomableLabel node) { node.setAntialiasing(true); node.setLeftMargin(6); node.setRightMargin(6); node.setTopMargin(4); node.setBottomMargin(4); node.setBorderOn(true); node.setBackgroundOn(true); node.setBackgroundPaint(Color.yellow); new IlvClippingLinkConnector(node); } /** * Find an object and center it in the view. * We search for the number. */ private boolean find(int number) { String name = "" + number; IlvGraphicEnumeration e = grapher.getObjects(true); while (e.hasMoreElements()) { IlvGraphic g = e.nextElement(); // we only search of IlvZoomableLabel if (g instanceof IlvZoomableLabel) { IlvZoomableLabel label = (IlvZoomableLabel)g; if (name.equals(label.getLabel())) { // found. Center it in the view. IlvManager manager = (IlvManager)label.getGraphicBag(); IlvTransformer t = manager.getDrawingTransformer(mgrview); IlvRect bbox = label.boundingBox(t); int w = mgrview.getWidth(); int h = mgrview.getHeight(); grapher.setSelected(label, true, true); translateView((w - bbox.width)/2 - bbox.x, (h - bbox.height)/2 - bbox.y, animate); grapher.deSelectAll(true, true); grapher.setSelected(label, true, true); return true; } } } return false; } /** * Translates the view by (dx, dy). * If animation is switched off, it does the translation immediately. * If animation is switched on, it shows a smooth animation from the * old position to the new position. * This should be called in the swing thread. * @param dx The x shift value. * @param dy The y shift value. * @param animate Whether animation is enabled. */ private void translateView(double dx, double dy, boolean animate) { if (!animate) mgrview.translate(dx, dy, true); else { Repainter repainter = new Repainter(); mgrview.setDoubleBufferFrozen(true); repainter.oldT = mgrview.getTransformer(); mgrview.translate(dx, dy, false); repainter.newT = mgrview.getTransformer(); mgrview.fitTransformerToArea(null, fcalc, 10); repainter.fitT = mgrview.getTransformer(); mgrview.setTransformer(repainter.oldT); mgrview.setDoubleBufferFrozen(false); repainter.mgrview = mgrview; repainter.count = 0; repainter.maxcount = 10; repainter.timer = new javax.swing.Timer(30, repainter); repainter.timer.start(); } } /** * The fit area calculator. * It calculates the area of all selected objects. */ IlvManagerView.FitAreaCalculator fcalc = new IlvManagerView.FitAreaCalculator() { Override public IlvRect getAreaToFit(IlvManagerView view) { IlvGraphicEnumeration e = view.getManager().getSelectedObjects(true); IlvRect rect = null; while (e.hasMoreElements()) { IlvGraphic g = e.nextElement(); IlvManager m = (IlvManager)g.getGraphicBag(); IlvRect bbox = g.boundingBox(m.getDrawingTransformer(view)); if (rect == null) rect = bbox; else rect.add(bbox); } if (rect == null) // nothing selected, fallback: fit to all return view.computeBBox(); else return rect; } }; /** * The animated repainter. * This passed to a swing timer does an animation in two phases: * First is scrolls and zooms from oldT to fitT, then it scrolls and * zooms from fitT to newT. */ class Repainter implements ActionListener { IlvManagerView mgrview; IlvTransformer oldT; IlvTransformer newT; IlvTransformer fitT; int count; int maxcount; javax.swing.Timer timer; boolean phase2; Override public void actionPerformed(ActionEvent evt) { count++; if (count == maxcount) { mgrview.setTransformer(fitT); mgrview.repaint(); if (!phase2) { count = 0; phase2 = true; oldT = fitT; fitT = newT; } else { timer.stop(); } } else { IlvTransformer t = new IlvTransformer(oldT.getx11() + count * (fitT.getx11() - oldT.getx11()) / maxcount, oldT.getx12() + count * (fitT.getx12() - oldT.getx12()) / maxcount, oldT.getx21() + count * (fitT.getx21() - oldT.getx21()) / maxcount, oldT.getx22() + count * (fitT.getx22() - oldT.getx22()) / maxcount, oldT.getx0() + count * (fitT.getx0() - oldT.getx0()) / maxcount, oldT.gety0() + count * (fitT.gety0() - oldT.gety0()) / maxcount); mgrview.setTransformer(t); mgrview.repaint(); } } } /** * 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() { FindInViewApp app = new FindInViewApp(); app.init(); JFrame frame = new JFrame("Find In View Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(500, 500); frame.getContentPane().add(app); frame.setVisible(true); } }); } }