/* * 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.Container; import java.awt.event.ActionEvent; import java.util.Enumeration; import java.util.Iterator; import java.util.ResourceBundle; import ilog.views.IlvRect; import ilog.views.diagrammer.IlvDiagrammer; import ilog.views.diagrammer.application.IlvDiagrammerAction; import ilog.views.diagrammer.application.IlvDiagrammerFrame; import ilog.views.diagrammer.application.IlvDiagrammerToolBar; import ilog.views.sdm.IlvSDMModel; import ilog.views.sdm.modeltools.IlvContentController; import ilog.views.sdm.modeltools.IlvContentHandler; import ilog.views.sdm.modeltools.IlvVisibleAreaListener; import ilog.views.util.IlvProductUtil; /** * This example shows how to use content on demand tool. * * @since JViews 8.0 * @proofread */ public class ContentDemo extends IlvDiagrammerFrame { //////////////////////////////////////////////////// // The following fields are interesting to modify, /** Number of nodes */ public int _nodeNumber = 100; // best between 100 and 10 000 /** Offset between nodes, in the grid */ public long _delta = 40; /** Size of the cache */ public int _cacheSize = _nodeNumber / 2; // 0 is also an interesting value /** * Show nodes in cache. This is less realistic, slower, but it shows how the * cache is working. */ public boolean _showCachedNodes = true; //////////////////////////////////////////////////// private static final String CODstatus = "detailsOnDemand"; private static final String LOCKED = new String("locked"); private static final String LOADED = new String("loaded"); private static final String UNLOADED = new String("unloaded"); private static final String CONTENT = "content"; private IlvContentController _controller; // entry point public static void main(final String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { Override public void run() { new ContentDemo().init(args); } }); } // constructor public ContentDemo() { super(new String[] { "-data", "data/grid.idpr", "-simple" }); // 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); } // init GUI Override public void init(Container contentPane) { super.init(contentPane); ResourceBundle rb; rb = ResourceBundle.getBundle("main"); // add actions IlvDiagrammerToolBar tb = getViewToolBar(); tb.addAction(new MoveAreaAction(rb)); IlvDiagrammerToolBar toolbar = new IlvDiagrammerToolBar(); toolbar.addAction(new Lock(rb)); toolbar.addAction(new Load(rb)); toolbar.addAction(new Unload(rb)); contentPane.add(toolbar, BorderLayout.NORTH); } // GUI is ready, init application Override public void ready() { super.ready(); // redo the diagram populateDiagram(_nodeNumber); final IlvDiagrammer diagrammer = getDiagrammers()[0]; // initialize the content controler _controller = new IlvContentController(); _controller.setCacheSize(_cacheSize); _controller.setSDMEngine(diagrammer.getEngine()); _controller.setContentHandler(new IlvContentHandler() { // callback for loading content. Could be done in a separate thread, too. Override public void loadContent(IlvContentController source, Object[] objects) { // prevent too much notifications diagrammer.setAdjusting(true); // loop over objects to load for (int i = 0; i < objects.length; i++) { loadObject(objects[i], true); } diagrammer.setAdjusting(false); } // callback for unloading content Override public void unloadContent(IlvContentController source, Object[] objects) { diagrammer.setAdjusting(true); for (int i = 0; i < objects.length; i++) { loadObject(objects[i], false); } diagrammer.setAdjusting(false); } }); // install view listener to lock objects in visible area. diagrammer.getView().fitTransformerToContent(); IlvVisibleAreaListener val = new IlvVisibleAreaListener(_controller) { // here we subclass only to check nodes in cache Override public int requestAreaToLock(IlvRect area) { int result = super.requestAreaToLock(area); // check whether some nodes goes to cache if (_showCachedNodes) { updateStates(); } return result; } }; val.installListener(_controller.getSDMEngine().getReferenceView()); } /////////////////////////////// // make "pop" different nodes, in a grid private void populateDiagram(int pop) { IlvDiagrammer d = getDiagrammers()[0]; d.setAdjusting(true); IlvSDMModel model = d.getEngine().getModel(); model.clear(); long width = (long) Math.sqrt(pop) * _delta; long x = 0; long y = 0; for (int i = 0; i < pop; i++) { Object node = model.createNode("form"); model.setObjectProperty(node, "name", Integer.valueOf(i)); model.setObjectProperty(node, "x", Long.valueOf(x)); model.setObjectProperty(node, "y", Long.valueOf(y)); x += _delta; if (x >= width) { x = 0; y += _delta; } // all nodes are unloaded model.setObjectProperty(node, CODstatus, UNLOADED); model.addObject(node, null, null); } d.setAdjusting(false); } // callback from lock/load/unload actions private void workOnSelection(int action) { IlvDiagrammer d = getDiagrammers()[0]; // loop on selected objects Iterator<?> selected = d.getSelectedObjects(); _controller.processObjects(selected, action); // check whether some nodes goes to cache if (_showCachedNodes) { updateStates(); } } /** * Callback from RectangleInteractor * * @param area * the area to lock */ void lockArea(IlvRect area) { _controller.lockArea(area, IlvContentController.OVERRIDE); // check whether some nodes goes to cache if (_showCachedNodes) { updateStates(); } } // the exact status of objects, including in cache. This is slow, because // we need to check state of all objects. private void updateStates() { getDiagrammers()[0].setAdjusting(true); IlvSDMModel model = getDiagrammers()[0].getEngine().getModel(); // loop over all objects Enumeration<?> e = getDiagrammers()[0].getEngine().getAllObjects(); while (e.hasMoreElements()) { Object node = e.nextElement(); String expected = statToString(_controller.getObjectStatus(node)); if (model.getObjectProperty(node, CODstatus) != expected) { // == is ok, // here model.setObjectProperty(node, CODstatus, expected); } } getDiagrammers()[0].setAdjusting(false); } /** * Loads or unloads an object * * @param node * the object * @param load * the action */ private void loadObject(Object node, boolean load) { IlvSDMModel model = getDiagrammers()[0].getEngine().getModel(); if (load) { // here we simulate the loading of node contents // it can be also interesting to put a sleep() command here, or loading a // huge value. model.setObjectProperty(node, CONTENT, "content should be more complex than this string"); } else { // unload values model.setObjectProperty(node, CONTENT, null); } // adjust state. It's use only to have an accurate visual feedback in the // CSS model.setObjectProperty(node, CODstatus, statToString(_controller.getObjectStatus(node))); } /** * Converts content status to a string that is simpler to match in the CSS. * * @param objectStatus * the loaded state * @return a string */ private String statToString(int objectStatus) { switch (objectStatus) { case IlvContentController.LOCK: return LOCKED; case IlvContentController.LOAD: return LOADED; case IlvContentController.UNLOAD: return UNLOADED; } return null; } ///////////////////////////////// // inner classes /** * The action that locks selected objects. */ private class Lock extends IlvDiagrammerAction { public Lock(ResourceBundle rb) { super("Lock", rb); } Override public void perform(ActionEvent e, IlvDiagrammer source) { workOnSelection(IlvContentController.LOCK); } Override protected boolean isEnabled(IlvDiagrammer diagrammer) throws Exception { return true; } } /** * The action that load in cache selected objects. */ private class Load extends IlvDiagrammerAction { public Load(ResourceBundle rb) { super("Load", rb); } Override public void perform(ActionEvent e, IlvDiagrammer source) { workOnSelection(IlvContentController.LOAD); } Override protected boolean isEnabled(IlvDiagrammer diagrammer) throws Exception { return true; } } /** * The action that unloads selected objects. */ private class Unload extends IlvDiagrammerAction { public Unload(ResourceBundle rb) { super("Unload", rb); } Override protected boolean isEnabled(IlvDiagrammer diagrammer) throws Exception { return true; } Override public void perform(ActionEvent e, IlvDiagrammer source) { workOnSelection(IlvContentController.UNLOAD); } } /** * An action that controls the content on demand through a visible area. */ private class MoveAreaAction extends IlvDiagrammerAction.ToggleAction { /** * @param bundle */ protected MoveAreaAction(ResourceBundle bundle) { super("MoveArea", bundle); } /* * (non-Javadoc) * * @see ilog.views.diagrammer.application.IlvDiagrammerAction.ToggleAction# * isSelected(ilog.views.diagrammer.IlvDiagrammer) */ Override protected boolean isSelected(IlvDiagrammer diagrammer) throws Exception { return diagrammer != null && diagrammer.getView().getInteractor() instanceof RectangleInteractor; } /* * (non-Javadoc) * * @see ilog.views.diagrammer.application.IlvDiagrammerAction.ToggleAction# * setSelected(ilog.views.diagrammer.IlvDiagrammer, boolean) */ Override protected void setSelected(IlvDiagrammer diagrammer, boolean selected) throws Exception { if (selected) { diagrammer.getView().pushInteractor(new RectangleInteractor(ContentDemo.this)); } else { diagrammer.getView().popInteractor(); } } /* * (non-Javadoc) * * @see * ilog.views.diagrammer.application.IlvDiagrammerAction#isEnabled(ilog. * views.diagrammer.IlvDiagrammer) */ Override protected boolean isEnabled(IlvDiagrammer diagrammer) throws Exception { return diagrammer != null; } } }