/* * 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.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImageOp; import java.awt.image.ConvolveOp; import java.awt.image.Kernel; import java.awt.image.LookupOp; import java.awt.image.RescaleOp; import java.awt.image.ShortLookupTable; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import ilog.views.IlvDefaultManagerFrame; import ilog.views.IlvGrapher; import ilog.views.IlvGraphic; import ilog.views.IlvGraphicEnumeration; import ilog.views.IlvHandlesSelection; import ilog.views.IlvHoverHighlightingImageOperation; import ilog.views.IlvManager; import ilog.views.IlvManagerView; import ilog.views.IlvPoint; import ilog.views.IlvRect; import ilog.views.graphic.IlvIcon; import ilog.views.graphic.IlvPolylineLinkImage; import ilog.views.graphic.IlvRectangle; import ilog.views.graphic.IlvShadowRectangle; import ilog.views.graphic.IlvText; import ilog.views.interactor.IlvSelectInteractor; import ilog.views.swing.IlvJComponentGraphic; import ilog.views.swing.IlvJManagerViewControlBar; import ilog.views.swing.IlvJScrollManagerView; /* * bench result: Cost for Predefined: None=100 % Cost for Predefined: Brighten=251 % Cost for * Predefined: Sharpen=418 % Cost for Predefined: Blur=396 % Cost for Predefined: Grayscale=214 % * Cost for Predefined: Invert Colors=144 % Cost for User Defined: Blur2=766 % Cost for User * Defined: Emboss=1207 % Cost for User Defined: Dilation=2158 % Cost for User Defined: Erosion=2121 * % Cost for User Defined: Red invert=988 % Cost for User Defined: Green invert=984 % Cost for User * Defined: Blue invert=981 % Cost for User Defined: Negative=988 % Cost for User Defined: Negative * 2=1706 % Cost for User Defined: Brighten 2=1677 % */ /** * A sample for the hover highlighting feature. */ SuppressWarnings("serial") public class HoverHighlight extends JRootPane { { // 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); } /** * Class that defines what we know about a specific hover operation. * The operation combo box contains instances of this. */ static public class HoverOperation {// elements in the combo box final private String name;// name final private int mode; // a predefined mode final private IlvHoverHighlightingImageOperation operation;// an user defined operation /** * Creates a new <code>HoverOperation</code>. * Applying this will set a predefined mode. * @param name display name of the effect * @param mode predefined mode */ public HoverOperation(String name, int mode) { this.name = name; this.mode = mode; this.operation = null; } /** * Creates a new <code>HoverOperation</code>. * Applying this will use an user defined operation. * @param name display name of the effect * @param operation image operation */ public HoverOperation(String name, IlvHoverHighlightingImageOperation operation) { this.name = name; this.mode = IlvManager.HH_NONE; this.operation = operation; } /** * Sets the hovering effect on the graph. * @param graph graph to apply the effects to. * This uses the new API defined in JViews 8.1 */ public void apply(IlvManager graph) { if (operation == null) graph.setHoverHighlightingMode(mode); else graph.setHoverHighlightingImageOperation(operation); } /** * What we display in the combo box. */ Override public String toString() { if (operation == null) return "Predefined: " + name; return "User Defined: " + name; } } // demo instance fields. private IlvGrapher graph; private IlvManagerView mngView; private IlvJScrollManagerView scroller; private JSlider hoverAlpha; private JComboBox<HoverOperation> hoverOp; private JComboBox<IlvHoverHighlightingImageOperation.Filter> hoverFilter; // color of the subgraphs private Color frameColor = Color.pink; // various definitions for the image operations static float[] blur5Kernel = new float[5 * 5]; static { for (int i = 0; i < blur5Kernel.length; i++) { blur5Kernel[i] = 1f / blur5Kernel.length; } } static short[] invert = new short[256]; static short[] straight = new short[256]; static { for (int i = 0; i < 256; i++) { invert[i] = (short) (255 - i); straight[i] = (short) i; } } static short[][] blueInvert = new short[][] {straight, straight, invert, straight}; static BufferedImageOp blueInvertOp = new LookupOp(new ShortLookupTable(0, blueInvert), null); static short[][] redInvert = new short[][] {invert, straight, straight, straight}; static BufferedImageOp redInvertOp = new LookupOp(new ShortLookupTable(0, redInvert), null); static short[][] greenInvert = new short[][] {straight, invert, straight, straight}; static BufferedImageOp greenInvertOp = new LookupOp(new ShortLookupTable(0, greenInvert), null); static short[][] allInvert = new short[][] {invert, invert, invert, straight}; static BufferedImageOp allInvertOp = new LookupOp(new ShortLookupTable(0, greenInvert), null); static BufferedImageOp negativeOp = new RescaleOp(new float[] {-1.0f, -1.0f, -1.0f, 1}, new float[] {255f, 255f, 255f, 0}, null); static BufferedImageOp brighten2Op = new RescaleOp(new float[] {1.5f, 1.5f, 1.5f, 1}, new float[] {0, 0, 0, 0}, null); // list of hover operations. static HoverOperation operations[] = {new HoverOperation("None", IlvManager.HH_NONE), new HoverOperation("Brighten", IlvManager.HH_BRIGHTEN), new HoverOperation("Sharpen", IlvManager.HH_SHARPEN), new HoverOperation("Blur", IlvManager.HH_BLUR), new HoverOperation("Grayscale", IlvManager.HH_GRAYSCALE), new HoverOperation("Invert Colors", IlvManager.HH_INVERT_COLORS), new HoverOperation("Blur2", new IlvHoverHighlightingImageOperation(new ConvolveOp(new Kernel(5, 5, blur5Kernel)), 1)), new HoverOperation("Emboss", new IlvHoverHighlightingImageOperation(new HoverEmbossOp(null, 2), 1)), new HoverOperation("Dilation", new IlvHoverHighlightingImageOperation(new MorphologyOp(2, 2, true), 1)), new HoverOperation("Erosion", new IlvHoverHighlightingImageOperation(new MorphologyOp(2, 2, false), 1)), new HoverOperation("Red invert", new IlvHoverHighlightingImageOperation(redInvertOp, 1)), new HoverOperation("Green invert", new IlvHoverHighlightingImageOperation(greenInvertOp, 1)), new HoverOperation("Blue invert", new IlvHoverHighlightingImageOperation(blueInvertOp, 1)), new HoverOperation("Negative", new IlvHoverHighlightingImageOperation(allInvertOp, 1)), new HoverOperation("Negative 2", new IlvHoverHighlightingImageOperation(negativeOp, 1)), new HoverOperation("Brighten 2", new IlvHoverHighlightingImageOperation(brighten2Op, 1))}; /** * Creates a new <code>Test</code>. */ public HoverHighlight() { // create a sample graph content. graph = new IlvGrapher(); graph.setVisible(true); createGraph(); // create and setup the GUI // main view and scroll mngView = new IlvManagerView(graph); mngView.setAntialiasing(true); mngView.setKeepingAspectRatio(true); mngView.setWheelZoomingEnabled(true); mngView.setName("graphView"); // parameters for selection handles IlvHandlesSelection.defaultHandleColor = Color.black; IlvHandlesSelection.defaultHandleBackgroundColor = Color.white; IlvHandlesSelection.defaultHandleShape = IlvHandlesSelection.SQUARE_SHAPE; scroller = new IlvJScrollManagerView(mngView); scroller.setBackground(Color.white); scroller.setWheelScrollingEnabled(true); // control toolbar and bench button IlvJManagerViewControlBar controlBar = new IlvJManagerViewControlBar(); controlBar.setView(mngView); controlBar.setFloatable(false); IlvSelectInteractor selInter = (IlvSelectInteractor) controlBar.getSelectInteractor(); selInter.setOpaqueDragSelection(true); selInter.setOpaqueMove(true); selInter.setOpaqueResize(true); selInter.setOpaquePolyPointsEdition(true); JButton bbench = new JButton("Bench"); bbench.setToolTipText("Start a bench to compare the various operation costs"); bbench.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { bench(1);// increase this number to have more meaningful comparison } }); controlBar.add(bbench); // Hover effect settings panel hoverAlpha = new JSlider(0, 100, 100); hoverAlpha.setMajorTickSpacing(25); hoverAlpha.setPaintLabels(true); hoverAlpha.setToolTipText("Select hover alpha"); hoverAlpha.addChangeListener(new ChangeListener() { Override public void stateChanged(ChangeEvent event) { updateOperation(); } }); hoverFilter = new JComboBox<IlvHoverHighlightingImageOperation.Filter>(); hoverFilter.addItem(new IlvHoverHighlightingImageOperation.Filter() { Override public String toString() { return "Every Object"; } Override public boolean highlightObject(IlvGraphic graphic) { return true; } }); hoverFilter.addItem(new IlvHoverHighlightingImageOperation.GraphicBagFilter() { Override public String toString() { return "Containers only"; } }); hoverFilter.addItem(new IlvHoverHighlightingImageOperation.NonGraphicBagFilter() { Override public String toString() { return "Simple Graphics only"; } }); hoverFilter.setSelectedIndex(0);// set an initial operation hoverFilter.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent event) { updateOperation(); } }); hoverOp = new JComboBox<HoverHighlight.HoverOperation>(operations); hoverOp.setToolTipText("Select hover operation"); hoverOp.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent event) { SuppressWarnings("unchecked") JComboBox<HoverHighlight.HoverOperation> comboBox = (JComboBox<HoverHighlight.HoverOperation>) event.getSource(); HoverOperation op = (HoverOperation) comboBox.getSelectedItem(); // apply the operation op.apply(graph); // then set the alpha to be consistent updateOperation(); } }); hoverOp.setSelectedIndex(1);// set an initial operation JPanel settings = new JPanel(new GridLayout(3, 0)); settings.add(new JLabel("Hover Operation")); settings.add(hoverOp); settings.add(new JLabel("Operation Opacity")); settings.add(hoverAlpha); settings.add(new JLabel("Operation Filter")); settings.add(hoverFilter); settings.setBorder(BorderFactory.createTitledBorder("Hover effect settings")); // setup the main frame getContentPane().add(controlBar, BorderLayout.NORTH); getContentPane().add(scroller, BorderLayout.CENTER); getContentPane().add(settings, BorderLayout.SOUTH); } /** * Sets the current opacity and filter for the selected hover operation. */ void updateOperation() { float alpha = hoverAlpha.getValue() / 100f; IlvHoverHighlightingImageOperation op = graph.getHoverHighlightingImageOperation(); if (op != null) { op.setAlpha(alpha); op.setHighlightFilter( (IlvHoverHighlightingImageOperation.Filter) hoverFilter.getSelectedItem()); } } /** * Bench to display the cost of the image operations relatively to a "noop" operation. * @param num number of times to repeat the graph enumeration. */ public void bench(int num) { double base = -1;// base time for operations // test all operations for (int o = 0; o < operations.length; o++) { long to0 = System.currentTimeMillis(); operations[o].apply(graph);// apply the operation updateOperation();// apply the alpha&filter // get the BufferedImageOp and the alpha IlvHoverHighlightingImageOperation op = graph.getHoverHighlightingImageOperation(); for (int i = 0; i < num; i++) { // go through all graph objects. for (IlvGraphicEnumeration en = graph.getObjects(); en.hasMoreElements();) { if (op != null) { // call the method that displays the highlighted area op.showHighlight(en.nextElement(), mngView); } else { // draw the object en.nextElement().draw(mngView.getGraphics(), mngView.getTransformer()); } } } long to1 = System.currentTimeMillis(); if (op == null) {// noop (is the first one) base = (to1 - to0); } double cost = (to1 - to0) / base; System.out.println("Cost for " + operations[o] + "=" + ((int) (cost * 100)) + " %"); } hoverOp.setSelectedIndex(operations.length - 1); mngView.repaint(); } /** * Create a sample graph that contains varied objects. */ public void createGraph() { IlvGraphic node1; node1 = new IlvRectangle(new IlvRect(10, 10, 20, 20)); node1.setFillOn(true); node1.setBackground(Color.green); graph.addNode(node1, true); IlvGraphic node2; node2 = new IlvRectangle(new IlvRect(10, 60, 20, 20)); node2.setFillOn(true); node2.setBackground(Color.green); graph.addNode(node2, true); IlvGraphic node3; node3 = addSubgraph(graph, 60, 0, 5); IlvPolylineLinkImage link1 = new IlvPolylineLinkImage(node1, node2, true, null); link1.setLineWidth(3.0); graph.addLink(link1, true); IlvPoint[] points = {new IlvPoint(40, 20), new IlvPoint(40, 40), new IlvPoint(50, 40), new IlvPoint(50, 20)}; IlvPolylineLinkImage link2 = new IlvPolylineLinkImage(node1, node3, true, points); link2.setLineWidth(3.0); link2.setForeground(Color.red); graph.addLink(link2, true); node1 = new IlvRectangle(new IlvRect(10, 120, 30, 30)); node1.setFillOn(true); node1.setBackground(Color.green); graph.addNode(node1, true); node1 = new IlvRectangle(new IlvRect(20, 125, 30, 30)); node1.setFillOn(true); node1.setBackground(Color.pink); graph.addNode(node1, true); node1 = new IlvRectangle(new IlvRect(15, 135, 30, 30)); node1.setFillOn(true); node1.setBackground(Color.cyan); graph.addNode(node1, true); IlvText text = new IlvText(new IlvPoint(120, 180), "This is a text"); text.setAntialiasing(true); text.setForeground(Color.blue); graph.addNode(text, true); IlvIcon icon = new IlvIcon(getClass().getResource("data/bookmark_48.gif"), new IlvRect(40, 170, 48, 48)); graph.addObject(icon, true); JButton b = new JButton("Swing Button"); IlvJComponentGraphic cg = new IlvJComponentGraphic( new IlvRect(120, 210, b.getPreferredSize().getWidth(), b.getPreferredSize().getHeight()), b); graph.addObject(cg, true); } /** * Add a sub graph. * @param parent * @param x * @param y * @param nesting * @return the subgraph */ public IlvGraphic addSubgraph(IlvGrapher parent, float x, float y, int nesting) { IlvGrapher sub = new IlvGrapher(); IlvGraphic node1; node1 = new IlvRectangle(new IlvRect(x + 10, y + 10, 20, 20)); node1.setFillOn(true); node1.setBackground(Color.green); sub.addNode(node1, true); IlvGraphic node2; node2 = new IlvShadowRectangle(new IlvRect(x + 10, y + 60, 20, 20)); // node2.setFillOn(true); node2.setBackground(Color.green); sub.addNode(node2, true); IlvGraphic node3; if (nesting == 0) { node3 = new IlvShadowRectangle(new IlvRect(x + 60, y + 10, 20, 20)); // node3.setFillOn(true); node3.setBackground(Color.green); sub.addNode(node3, true); } else { node3 = addSubgraph(sub, x + 60, y + 10, nesting - 1); } IlvPolylineLinkImage link1 = new IlvPolylineLinkImage(node1, node2, true, null); link1.setLineWidth(3.0); sub.addLink(link1, true); IlvPolylineLinkImage link2 = new IlvPolylineLinkImage(node1, node3, true, null); link2.setLineWidth(3.0); link2.setForeground(Color.red); sub.addLink(link2, true); IlvDefaultManagerFrame frame = (IlvDefaultManagerFrame) sub.getFrame(); if (nesting % 2 == 0) { frame.setOpaque(true); frame.setBackground(frameColor); frame.setForeground(Color.red); frameColor = new Color((frameColor.getRed() * 211 + 17) % 255, (frameColor.getGreen() * 211 + 113) % 255, (frameColor.getBlue() * 211 + 37) % 255); } else { frame.setOpaque(false); } parent.addNode(sub, true); return node1; } /** * Starts the hover highlighting sample * @param args (ignored) */ public static void main(String args[]) { JFrame f = new JFrame(); f.getContentPane().add(new HoverHighlight()); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setTitle("Hover Highlighting Sample"); f.setSize(500, 500); f.setVisible(true); } }