/*
* Licensed Materials - Property of Rogue Wave Software, Inc.
* © Copyright Rogue Wave Software, Inc. 2014, 2017
* © 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 Rogue Wave 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);
}
});
}
}