/* * 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.Dimension; import java.awt.FlowLayout; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Insets; import java.awt.Paint; import java.awt.SystemColor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; 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.JSplitPane; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import ilog.views.IlvDirection; import ilog.views.IlvGraphic; import ilog.views.IlvHandlesSelection; import ilog.views.IlvManager; import ilog.views.IlvManagerView; import ilog.views.IlvPoint; import ilog.views.IlvRect; import ilog.views.graphic.IlvGeneralPath; import ilog.views.graphic.IlvHalfZoomingGraphic; import ilog.views.graphic.IlvMarker; import ilog.views.graphic.IlvRectangle; import ilog.views.graphic.IlvText; import ilog.views.graphic.IlvZoomableLabel; import ilog.views.graphic.composite.IlvCompositeGraphic; import ilog.views.graphic.composite.decoration.IlvRoundRectBalloon; import ilog.views.graphic.composite.layout.IlvAttachmentConstraint; import ilog.views.graphic.composite.layout.IlvAttachmentLayout; import ilog.views.graphic.composite.layout.IlvAttachmentLocation; import ilog.views.graphic.composite.layout.IlvCenteredLayout; import ilog.views.interactor.IlvManagerMagViewInteractor; import ilog.views.interactor.IlvSelectInteractor; import ilog.views.interactor.IlvZoomViewInteractor; import ilog.views.java2d.IlvBlinkingAction; import ilog.views.java2d.IlvBlinkingMultiAction; import ilog.views.swing.IlvJManagerViewControlBar; import ilog.views.swing.IlvJScrollManagerView; import ilog.views.util.java2d.IlvBlinkingColor; import ilog.views.util.java2d.IlvBlinkingMultiColor; import ilog.views.util.java2d.IlvBlinkingMultiPaint; import ilog.views.util.java2d.IlvBlinkingPaint; /** * This is a very simple application that shows how to implement * blinking effects in a manager. */ SuppressWarnings("serial") public class BlinkingApp extends JRootPane { // for the performance measurement: the time in milliseconds we spend // for redraw long sumRedrawTime; { // 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 manager final IlvManager manager = new IlvManager(); // create the manager views: a main view and an overview final IlvManagerView mgrview1 = new ManagerView(manager); final IlvManagerView mgrview2 = new ManagerView(manager); // create the scroll manager view for the main view IlvJScrollManagerView scrollManView = new IlvJScrollManagerView(mgrview1); // Adjust the overview IlvManagerMagViewInteractor overviewInteractor = new IlvManagerMagViewInteractor(mgrview1, true); overviewInteractor.setDrawingStyle(IlvManagerMagViewInteractor.Wire); mgrview2.setInteractor(overviewInteractor); mgrview2.setAutoFitToContents(true); mgrview2.setBlinkingMode(IlvManagerView.BLINKING_DISABLED); // Create a panel with the overview JPanel overviewPanel = new JPanel(new BorderLayout(0, 0)); overviewPanel.add(new JLabel("Overview"), BorderLayout.NORTH); overviewPanel.add(mgrview2, BorderLayout.CENTER); // Create a panel with the performance history indicator JPanel historyPanel = new JPanel(new BorderLayout(0, 0)); JLabel historyLabel = new JLabel("Redraw Time: 0.0 %"); historyPanel.add(historyLabel, BorderLayout.NORTH); historyPanel.add(new PerformanceHistory(historyLabel), BorderLayout.CENTER); // Settings parameters for selection handles IlvHandlesSelection.defaultHandleColor = Color.red; IlvHandlesSelection.defaultHandleBackgroundColor = Color.black; IlvHandlesSelection.defaultHandleShape = IlvHandlesSelection.SQUARE_SHAPE; // create the standard control bar IlvJManagerViewControlBar controlBar = new IlvJManagerViewControlBar(); controlBar.setView(mgrview1); // modify the interactors such that the demo looks better ((IlvSelectInteractor)controlBar.getSelectInteractor()).setOpaqueMove(true); ((IlvZoomViewInteractor)controlBar.getZoomViewInteractor()).setPermanent(true); mgrview1.setInteractor(controlBar.getSelectInteractor()); // Now, fill the manager fillManager(manager, 1); // create the top panel with the toolbar and the checkboxes JPanel topPanel = new JPanel(); topPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); topPanel.add(controlBar); // add the choice to set the blinking speed final JComboBox<String> speedChoice = new JComboBox<String>(); speedChoice.addItem("1x"); speedChoice.addItem("2x"); speedChoice.addItem("3x"); speedChoice.setSelectedIndex(0); topPanel.add(new JLabel(" Blinking Speed: ")); topPanel.add(speedChoice); speedChoice.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { switch (speedChoice.getSelectedIndex()) { case 0: fillManager(manager, 1); break; case 1: fillManager(manager, 0.5f); break; case 2: fillManager(manager, 0.33f); break; } } }); // add the choice to disable blinking per view JCheckBox blinkingOnView1 = new JCheckBox("Main View", true); JCheckBox blinkingOnView2 = new JCheckBox("Overview", false); topPanel.add(new JLabel(" Blinking on: ")); topPanel.add(blinkingOnView1); topPanel.add(new JLabel(" ")); topPanel.add(blinkingOnView2); blinkingOnView1.addItemListener(new ItemListener() { Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) mgrview1.setBlinkingMode(IlvManagerView.BLINKING_AUTOMATIC); else if (e.getStateChange() == ItemEvent.DESELECTED) mgrview1.setBlinkingMode(IlvManagerView.BLINKING_DISABLED); mgrview1.repaint(); } }); blinkingOnView2.addItemListener(new ItemListener() { Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) mgrview2.setBlinkingMode(IlvManagerView.BLINKING_AUTOMATIC); else if (e.getStateChange() == ItemEvent.DESELECTED) mgrview2.setBlinkingMode(IlvManagerView.BLINKING_DISABLED); mgrview2.repaint(); } }); // put all panels together final JSplitPane splitPane1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, overviewPanel, historyPanel); splitPane1.addHierarchyListener(new HierarchyListener(){ Override public void hierarchyChanged(HierarchyEvent e) { if (splitPane1.isShowing()){ splitPane1.setDividerLocation(0.5); splitPane1.removeHierarchyListener(this); } } }); final JSplitPane splitPane2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, scrollManView, splitPane1); splitPane2.addHierarchyListener(new HierarchyListener(){ Override public void hierarchyChanged(HierarchyEvent e) { if (splitPane2.isShowing()){ splitPane2.setDividerLocation(0.7); splitPane2.removeHierarchyListener(this); } } }); getContentPane().setLayout(new BorderLayout(0, 0)); getContentPane().add(splitPane2, BorderLayout.CENTER); getContentPane().add(topPanel, BorderLayout.NORTH); } /** * Fills the manager with objects that have various blinking actions, * blinking colors or blinking periods set. * @param manager The manager to be filled * @param blinkingSpeed The base speed of all blinking timings */ private void fillManager(IlvManager manager, float blinkingSpeed) { if (blinkingSpeed <= 0) blinkingSpeed = 1; // calculate the timings long base300 = (long)(blinkingSpeed * 300); long base500 = (long)(blinkingSpeed * 500); long base1000 = (long)(blinkingSpeed * 1000); // clear the manager manager.deleteAll(true); // this is a nonpersistent blinking action. It cannot be stored in // an IVL file. IlvBlinkingAction action1 = new IlvBlinkingMultiAction(3, base1000) { Override protected void changeState(IlvGraphic obj, int step) { // assume the associated object is always an IlvMarker IlvMarker marker = (IlvMarker)obj; // no applyToObject necessary because the caller does it already switch (step) { case 0: marker.setType(IlvMarker.IlvMarkerCircle); break; case 1: marker.setType(IlvMarker.IlvMarkerPlus); break; case 2: marker.setType(IlvMarker.IlvMarkerCross); break; } } }; // this is a blinking color that shows red, blue and green Color color = new IlvBlinkingMultiColor(base300, Color.red, Color.blue, Color.green); IlvMarker marker1 = new IlvMarker(new IlvPoint(10,10), IlvMarker.IlvMarkerCircle); IlvMarker marker2 = new IlvMarker(new IlvPoint(10,30), IlvMarker.IlvMarkerCircle); // blinking actions can be shared among multiple objects marker1.setBlinkingAction(action1); marker2.setBlinkingAction(action1); marker1.setForeground(color); marker2.setForeground(color); manager.addObject(marker1, true); manager.addObject(marker2, true); // some labels for the marked IlvText text1 = new IlvText(new IlvPoint(20, 15), "Blinking Marker"); IlvText text2 = new IlvText(new IlvPoint(20, 35), "Blinking Marker"); manager.addObject(text1, true); manager.addObject(text2, true); text2.setBlinkingOnPeriod(base500); text2.setBlinkingOffPeriod(base500); // for this text, use a persistent blinking action IlvText text3 = new IlvText(new IlvPoint(10,55), ""); text3.setBlinkingAction(new LabelBlinkingAction(base1000, base1000, "Text with blinking action", "Blinking action on text")); text3.setEditable(false); manager.addObject(text3, true); Color color1 = new IlvBlinkingColor(Color.red, Color.yellow, base300, base1000); Color color2 = new IlvBlinkingMultiColor(base300, Color.blue, Color.green, Color.cyan, Color.yellow); Color color3 = Color.cyan; for (int i = 0; i < 15; i++) { IlvRectangle rect = new IlvRectangle(new IlvRect(340, 10 + i * 40, 50, 23)); rect.setFillOn(true); switch (i % 3) { case 0: rect.setBackground(color1); rect.setForeground(color2); break; case 1: rect.setBackground(color2); rect.setForeground(color1); break; case 2: rect.setBackground(color3); rect.setBlinkingOffPeriod(base300); rect.setBlinkingOnPeriod(base300); break; } manager.addObject(rect, true); } Paint paint1 = new GradientPaint(0,0,Color.red,0,100,Color.blue); Paint paint2 = new GradientPaint(0,0,Color.blue,0,100,Color.green); Paint paint3 = new GradientPaint(0,0,Color.green,0,100,Color.red); Paint bpaint1 = new IlvBlinkingMultiPaint(base300, paint1, paint2, paint3); Paint bpaint2 = new IlvBlinkingMultiPaint(base300, paint2, paint3, paint1); Paint bpaint3 = new IlvBlinkingMultiPaint(base300, paint3, paint1, paint2); for (int i = 0; i < 15; i++) { IlvGeneralPath gp = new IlvGeneralPath(new Rectangle2D.Double(270, 10 + i * 40, 50, 20)); gp.setFillOn(true); gp.setStrokeOn(true); switch (i % 3) { case 0: gp.setFillPaint(bpaint1); gp.setStrokePaint(bpaint2); break; case 1: gp.setFillPaint(bpaint2); gp.setStrokePaint(bpaint3); break; case 2: gp.setFillPaint(bpaint3); gp.setStrokePaint(bpaint1); break; } manager.addObject(gp, true); } // a blinking action for IlvGeneralPath IlvBlinkingAction action2 = new IlvBlinkingMultiAction(3, base1000) { Override protected void changeState(IlvGraphic obj, int step) { // assume the associated object is always an IlvGeneralPath IlvGeneralPath gp = (IlvGeneralPath)obj; IlvRect r = gp.boundingBox(); float x = 0; float y = 0; float w = 50; float h = 20; // no applyToObject necessary because the caller does it already for us switch (step) { case 0: gp.setShape(new Rectangle2D.Double(x,y,w,h)); break; case 1: gp.setShape(new Ellipse2D.Double(x,y,w,h)); break; case 2: GeneralPath p = new GeneralPath(); p.moveTo(x+0.5*w, y); p.lineTo(x+w, y+0.5*h); p.lineTo(x+0.5*w, y+h); p.lineTo(x, y+0.5*h); p.closePath(); gp.setShape(p); break; } gp.move(r.x, r.y); } }; // objects encapsulated in IlvHalfZoomingGraphic Paint bpaint4 = new IlvBlinkingPaint(paint1, paint2, base500, base500); Paint bpaint5 = new IlvBlinkingPaint(paint2, paint3, base500, base500); Paint bpaint6 = new IlvBlinkingPaint(paint3, paint1, base500, base500); for (int i = 0; i < 15; i++) { IlvGeneralPath gp = new IlvGeneralPath(new Rectangle2D.Double(200, 10 + i * 40, 50, 20)); gp.setFillOn(true); gp.setStrokeOn(true); gp.setBlinkingAction(action2); switch (i % 3) { case 0: gp.setFillPaint(bpaint4); gp.setStrokePaint(bpaint5); break; case 1: gp.setFillPaint(bpaint5); gp.setStrokePaint(bpaint6); break; case 2: gp.setFillPaint(bpaint6); gp.setStrokePaint(bpaint4); break; } IlvHalfZoomingGraphic hzg = new IlvHalfZoomingGraphic(gp, IlvDirection.Center, null, 0.1, 1.5, 1.0); manager.addObject(hzg, true); } // finally a blinking composite graphic IlvCompositeGraphic cg = new IlvCompositeGraphic(); cg.setLayout(new IlvAttachmentLayout()); IlvRectangle rectangle = new IlvRectangle(new IlvRect(50, 200, 40, 40), true, true); rectangle.setBackground(color1); cg.setChildren(0, rectangle); IlvText text = new IlvText(); text.setLabel("Composite"); text.setBlinkingAction(new LabelBlinkingAction(base300,base300, "Composite", " Graphic")); cg.setChildren(1, text); cg.setConstraints(1, new IlvAttachmentConstraint( IlvAttachmentLocation.TopCenter, IlvAttachmentLocation.BottomCenter)); // Creates a balloon, made of two graphics with a centered layout IlvCompositeGraphic balloonGraphic = new IlvCompositeGraphic(); balloonGraphic.setLayout(new IlvCenteredLayout(new Insets(4,10,4,10))); IlvRoundRectBalloon balloon = new IlvRoundRectBalloon(); balloon.setOrientation(SwingConstants.NORTH_EAST); balloon.setPointerDepth(10); balloon.setShadowThickness(2); balloon.setRadius(15); balloon.setShadowColor(Color.black); balloon.setBorderColor(Color.black); balloon.setBalloonColor(new IlvBlinkingColor(Color.green, Color.yellow, base300, base1000)); IlvZoomableLabel label = new IlvZoomableLabel(new IlvPoint(0,0), "This is a composite graphic"); label.setBlinkingOnPeriod(base500); label.setBlinkingOffPeriod(base300); balloonGraphic.setChildren(0,balloon); balloonGraphic.setChildren(1,label); cg.setChildren(2, balloonGraphic); cg.setConstraints(2, new IlvAttachmentConstraint( IlvAttachmentLocation.BottomCenter, IlvAttachmentLocation.TopRight)); manager.addObject(cg, true); } /** * 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() { BlinkingApp app = new BlinkingApp(); app.init(); JFrame frame = new JFrame("Blinking Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(700, 500); frame.getContentPane().add(app); frame.setVisible(true); } }); } /** * A manager view that registers its own redraw time. * This allows the performance history to show the percentage of the * redraw time compared to the overall time. */ class ManagerView extends IlvManagerView { /** * Constructs a new manager view. */ ManagerView(IlvManager m) { super(m); // some useful default settings of the manager view setDoubleBuffering(true); setAntialiasing(true); setKeepingAspectRatio(true); setBackground(Color.white); setForeground(SystemColor.windowText); Color xc = SystemColor.windowText; xc = new Color(255-xc.getRed(), 255-xc.getGreen(), 255-xc.getBlue()); setDefaultXORColor(xc); setDefaultGhostColor(SystemColor.windowText); setZoomFactorRange(0.002, 15.0); } /** * Paints the view. * This is overridden to measure the time we need for painting. */ Override public void paint(Graphics g) { long startTime = System.currentTimeMillis(); super.paint(g); long stopTime = System.currentTimeMillis(); sumRedrawTime += (stopTime - startTime); } } /** * The performance history panel. * This displays the percentage of the redraw time of the views compared * to the overall time. */ class PerformanceHistory extends JPanel implements ActionListener { long maxPermille = 1000; long[] permilles = null; long lastTimeStamp = 0; JLabel label; /** * Constructor. */ PerformanceHistory(JLabel label) { this.label = label; this.lastTimeStamp = System.currentTimeMillis(); new javax.swing.Timer(2000, this).start(); } /** * Called by the timer every second. Updates the percentage of the redraw * time. */ Override public void actionPerformed(ActionEvent evt) { long timeDiff = System.currentTimeMillis() - lastTimeStamp; int permille = (int)(1000.0 * sumRedrawTime / timeDiff); addEntry(permille); int permilleint = permille / 10; int permillefrac = permille % 10; if (label != null) { label.setText("Redraw Time: " + permilleint + "." + permillefrac + " %"); } repaint(); sumRedrawTime = 0; lastTimeStamp = System.currentTimeMillis(); } /** * Paints this performance history panel. */ Override public void paint(Graphics g) { super.paint(g); int w = getWidth(); int h = getHeight(); g.setColor(Color.black); g.fillRect(0, 0, w, h); g.setColor(Color.green); for (int i = 0; i < w; i += 15) g.drawLine(i, 0, i, h); for (int i = 0; i < h; i += 15) g.drawLine(0, i, w, i); g.setColor(Color.yellow); float f = (float)h / (float)maxPermille; for (int i = 1; i < permilles.length; i++) { g.drawLine(w-1-i, h - (int)(permilles[i-1] * f), w-2-i, h - (int)(permilles[i] * f)); } g.setColor(Color.lightGray); g.drawRect(0,0,w,h); g.drawRect(1,1,w-2,h-2); g.drawRect(0,0,w-2,h-2); } /** * Add an entry to the performance history. */ private void addEntry(long val) { if (permilles == null || permilles.length == 0) return; int n = permilles.length; if (n > 1) System.arraycopy(permilles, 0, permilles, 1, n-1); permilles[0] = val; if (val > maxPermille) maxPermille = 3 * val / 2; } /** * Changes the bounds of this panel. */ Override public void setBounds(int x, int y, int w, int h) { long[] old = permilles; permilles = new long[w]; if (old != null) { int n = Math.min(old.length, permilles.length); System.arraycopy(old, 0, permilles, 0, n); } super.setBounds(x, y, w, h); } /** * Returns the preferred size. */ Override public Dimension getPreferredSize() { return new Dimension(60,60); } /** * Returns the minimum size. */ Override public Dimension getMinimumSize() { return new Dimension(60,60); } } }