/*
* 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.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
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 java.awt.event.KeyEvent;
import java.util.Comparator;
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.SwingUtilities;
import javax.swing.border.TitledBorder;
import ilog.views.IlvAccelerator;
import ilog.views.IlvDefaultManagerFrame;
import ilog.views.IlvGrapher;
import ilog.views.IlvGraphic;
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.accelerator.IlvCycleSelectAccelerator;
import ilog.views.graphic.IlvZoomableLabel;
import ilog.views.interactor.IlvSelectInteractor;
import ilog.views.swing.IlvJScrollManagerView;
import ilog.views.util.swing.IlvJComboBox;
/**
* This is a very simple application that shows how to implement
* a selection mechanism that uses the keyboard.
*/
SuppressWarnings("serial")
public class KeyboardSelApp extends JRootPane {
{
// This sample uses JViews Diagrammer features. When deploying an
// application that includes this code, you need
// a Rogue Wave JViews Diagrammer Deployment license.
// IlvProductUtil.DeploymentLicenseRequired(
// IlvProductUtil.JViews_Diagrammer_Deployment);
}
// --------------------------------------------------------------------
IlvGrapher grapher;
IlvManagerView mgrview;
IlvZoomableLabel node;
boolean animate = true;
IlvCycleSelectAccelerator[] accelerators;
// comparator for the traversal order: x has higher priority
Comparator<IlvGraphic> xThenY = new Comparator<IlvGraphic>() {
Override
public int compare(IlvGraphic a, IlvGraphic b) {
IlvManager ma = (IlvManager) a.getGraphicBag();
IlvManager mb = (IlvManager) b.getGraphicBag();
IlvTransformer ta = ma.getTopLevelTransformer();
IlvTransformer tb = mb.getTopLevelTransformer();
IlvRect ra = a.boundingBox(ta);
IlvRect rb = b.boundingBox(tb);
if (ra.x < rb.x)
return -1;
if (ra.x > rb.x)
return 1;
if (ra.width < rb.width)
return -1;
if (ra.width > rb.width)
return 1;
if (ra.y < rb.y)
return -1;
if (ra.y > rb.y)
return 1;
if (ra.height < rb.height)
return -1;
if (ra.height > rb.height)
return 1;
return 0;
}
};
// comparator for the traversal order: y has higher priority
Comparator<IlvGraphic> yThenX = new Comparator<IlvGraphic>() {
Override
public int compare(IlvGraphic a, IlvGraphic b) {
IlvManager ma = (IlvManager) a.getGraphicBag();
IlvManager mb = (IlvManager) b.getGraphicBag();
IlvTransformer ta = ma.getTopLevelTransformer();
IlvTransformer tb = mb.getTopLevelTransformer();
IlvRect ra = a.boundingBox(ta);
IlvRect rb = b.boundingBox(tb);
if (ra.y < rb.y)
return -1;
if (ra.y > rb.y)
return 1;
if (ra.height < rb.height)
return -1;
if (ra.height > rb.height)
return 1;
if (ra.x < rb.x)
return -1;
if (ra.x > rb.x)
return 1;
if (ra.width < rb.width)
return -1;
if (ra.width > rb.width)
return 1;
return 0;
}
};
// comparator for the traversal order: nesting has highest priority, then x
Comparator<IlvGraphic> nestedThenXThenY = new Comparator<IlvGraphic>() {
Override
public int compare(IlvGraphic a, IlvGraphic b) {
IlvGrapher commonBag = IlvGrapher.getLowestCommonGrapher(a, b);
if (commonBag != null) {
while (a.getGraphicBag() != commonBag)
a = (IlvGraphic) a.getGraphicBag();
while (b.getGraphicBag() != commonBag)
b = (IlvGraphic) b.getGraphicBag();
}
IlvRect ra = a.boundingBox();
IlvRect rb = b.boundingBox();
if (ra.x < rb.x)
return -1;
if (ra.x > rb.x)
return 1;
if (ra.width > rb.width)
return -1;
if (ra.width < rb.width)
return 1;
if (ra.y < rb.y)
return -1;
if (ra.y > rb.y)
return 1;
if (ra.height > rb.height)
return -1;
if (ra.height < rb.height)
return 1;
return 0;
}
};
// comparator for the traversal order: nesting has highest priority, then y
Comparator<IlvGraphic> nestedThenYThenX = new Comparator<IlvGraphic>() {
Override
public int compare(IlvGraphic a, IlvGraphic b) {
IlvGrapher commonBag = IlvGrapher.getLowestCommonGrapher(a, b);
if (commonBag != null) {
while (a.getGraphicBag() != commonBag)
a = (IlvGraphic) a.getGraphicBag();
while (b.getGraphicBag() != commonBag)
b = (IlvGraphic) b.getGraphicBag();
}
IlvRect ra = a.boundingBox();
IlvRect rb = b.boundingBox();
if (ra.y < rb.y)
return -1;
if (ra.y > rb.y)
return 1;
if (ra.height > rb.height)
return -1;
if (ra.height < rb.height)
return 1;
if (ra.x < rb.x)
return -1;
if (ra.x > rb.x)
return 1;
if (ra.width > rb.width)
return -1;
if (ra.width < rb.width)
return 1;
return 0;
}
};
/**
* 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.blue;
IlvHandlesSelection.defaultHandleBackgroundColor = Color.blue;
IlvHandlesSelection.defaultHandleShape = IlvHandlesSelection.SQUARE_SHAPE;
// Install the select interactor
mgrview.setInteractor(new IlvSelectInteractor());
// ensure that the manager view receives the TAB key events
mgrview.setFocusable(true);
mgrview.setFocusCycleRoot(true);
mgrview.setFocusTraversalKeysEnabled(false);
// add the accelerators
accelerators = new IlvCycleSelectAccelerator[4];
IlvCycleSelectAccelerator acc;
acc = new IlvCycleSelectAccelerator(KeyEvent.KEY_PRESSED, KeyEvent.VK_TAB, 0) {
Override
protected boolean endOfSequence(IlvGraphic g) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().upFocusCycle();
return true;
}
};
acc.setForward(true);
accelerators[0] = acc;
acc = new IlvCycleSelectAccelerator(KeyEvent.KEY_PRESSED, 'F', 0);
acc.setForward(true);
accelerators[1] = acc;
acc =
new IlvCycleSelectAccelerator(KeyEvent.KEY_PRESSED, KeyEvent.VK_TAB, KeyEvent.SHIFT_MASK) {
Override
protected boolean endOfSequence(IlvGraphic g) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().upFocusCycle();
KeyboardFocusManager.getCurrentKeyboardFocusManager().focusPreviousComponent();
return true;
}
};
acc.setForward(false);
accelerators[2] = acc;
acc = new IlvCycleSelectAccelerator(KeyEvent.KEY_PRESSED, 'B', 0);
acc.setForward(false);
accelerators[3] = acc;
for (int i = 0; i < accelerators.length; i++)
grapher.addAccelerator(accelerators[i]);
IlvAccelerator acc2 =
new IlvAccelerator(KeyEvent.KEY_PRESSED, KeyEvent.VK_TAB, KeyEvent.CTRL_MASK) {
Override
protected boolean handleEvent(IlvManagerView view) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().upFocusCycle();
return true;
}
};
grapher.addAccelerator(acc2);
// Now, fill the grapher
createGraph();
// create a check box that allows the selection of expanded subgraphs
JCheckBox expandedSubgraphsCheckBox = new JCheckBox("Subgraphs", true);
expandedSubgraphsCheckBox.setToolTipText("Allow the selection of expanded subgraphs");
expandedSubgraphsCheckBox.addItemListener(new ItemListener() {
Override
public void itemStateChanged(ItemEvent e) {
for (int i = 0; i < accelerators.length; i++)
accelerators[i]
.setSelectExpandedSubgraphsAllowed(e.getStateChange() == ItemEvent.SELECTED);
}
});
// create a check box that allows the selection of nodes
JCheckBox nodesCheckBox = new JCheckBox("Nodes", true);
nodesCheckBox.setToolTipText("Allow the selection of nodes");
nodesCheckBox.addItemListener(new ItemListener() {
Override
public void itemStateChanged(ItemEvent e) {
for (int i = 0; i < accelerators.length; i++)
accelerators[i].setSelectNodesAllowed(e.getStateChange() == ItemEvent.SELECTED);
}
});
// create a check box that allows the selection of links
JCheckBox linksCheckBox = new JCheckBox("Links", false);
linksCheckBox.setToolTipText("Allow the selection of links");
linksCheckBox.addItemListener(new ItemListener() {
Override
public void itemStateChanged(ItemEvent e) {
for (int i = 0; i < accelerators.length; i++)
accelerators[i].setSelectLinksAllowed(e.getStateChange() == ItemEvent.SELECTED);
}
});
// create a check box that allows you to descend into subgraphs
JCheckBox descendCheckBox = new JCheckBox("Descend into subgraphs", true);
descendCheckBox.setToolTipText("Allow the selection cycle to descend into subgraphs");
descendCheckBox.addItemListener(new ItemListener() {
Override
public void itemStateChanged(ItemEvent e) {
for (int i = 0; i < accelerators.length; i++)
accelerators[i]
.setDescendIntoExpandedSubgraphsAllowed(e.getStateChange() == ItemEvent.SELECTED);
}
});
// create a combination box for the order mode
SuppressWarnings("unchecked")
JComboBox<String> orderingBox = new IlvJComboBox();
orderingBox.addItem("unordered");
orderingBox.addItem("x then y");
orderingBox.addItem("y then x");
orderingBox.addItem("nested then x");
orderingBox.addItem("nested then y");
orderingBox.setToolTipText("Select the selection traversal order");
orderingBox.addActionListener(new ActionListener() {
Override
public void actionPerformed(ActionEvent event) {
SuppressWarnings("unchecked")
JComboBox<String> comboBox = (JComboBox<String>) event.getSource();
String mode = (String) comboBox.getSelectedItem();
Comparator<IlvGraphic> c = null;
if ("unordered".equals(mode)) {
c = null;
} else if ("x then y".equals(mode)) {
c = xThenY;
} else if ("y then x".equals(mode)) {
c = yThenX;
} else if ("nested then x".equals(mode)) {
c = nestedThenXThenY;
} else if ("nested then y".equals(mode)) {
c = nestedThenYThenX;
}
for (int i = 0; i < accelerators.length; i++)
accelerators[i].setComparator(c);
}
});
JPanel aux = new JPanel();
aux.setLayout(new FlowLayout(FlowLayout.LEADING));
aux.add(new JLabel("Ordering: "));
aux.add(orderingBox);
// create the top panel with the toolbar and the pop-up checkbox
JPanel topPanel = new JPanel();
topPanel.setLayout(new FlowLayout(FlowLayout.LEADING));
final Dimension d1 = (new JLabel("Allow Selection of")).getPreferredSize();
JPanel leadingPanel = new JPanel() {
Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
Override
public Dimension getPreferredSize() {
Dimension d0 = super.getPreferredSize();
Dimension dd = new Dimension(d1);
dd.width += 40;
if (d0.width > dd.width)
dd.width = d0.width;
if (d0.height > dd.height)
dd.height = d0.height;
return dd;
}
};
final Dimension d2 = (new JLabel("Further Options")).getPreferredSize();
JPanel trailingPanel = new JPanel() {
Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
Override
public Dimension getPreferredSize() {
Dimension d0 = super.getPreferredSize();
Dimension dd = new Dimension(d2);
dd.width += 40;
if (d0.width > dd.width)
dd.width = d0.width;
if (d0.height > dd.height)
dd.height = d0.height;
return dd;
}
};
leadingPanel.setBorder(new TitledBorder("Allow Selection of"));
leadingPanel.setLayout(new GridLayout(3, 1));
leadingPanel.add(expandedSubgraphsCheckBox);
leadingPanel.add(nodesCheckBox);
leadingPanel.add(linksCheckBox);
trailingPanel.setBorder(new TitledBorder("Further Options"));
trailingPanel.setLayout(new GridLayout(2, 1));
trailingPanel.add(descendCheckBox);
trailingPanel.add(aux);
topPanel.add(leadingPanel);
topPanel.add(trailingPanel);
// 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, 0, 0, 1, 0, 0));
}
/**
* Creates a sample graph.
*/
private void createGraph() {
IlvGraphic[] inner1 = createSubGraph(grapher);
IlvGraphic sg1 = (IlvGraphic) inner1[0].getGraphicBag();
IlvGraphic[] inner2 = createSubGraph(grapher);
IlvGraphic sg2 = (IlvGraphic) inner2[0].getGraphicBag();
grapher.moveObject(sg1, 220, 20, true);
grapher.moveObject(sg2, 221, 140, true);
IlvGraphic[] nodes = new IlvGraphic[7];
IlvPoint[] positions =
{new IlvPoint(20, 0), new IlvPoint(90, 0), new IlvPoint(90, 60), new IlvPoint(160, 0),
new IlvPoint(160, 60), new IlvPoint(160, 120), new IlvPoint(160, 180)};
for (int i = 0; i < nodes.length; i++) {
nodes[i] = new IlvZoomableLabel(positions[i], "N", false);
setNodeAttributes(nodes[i]);
grapher.addNode(nodes[i], 0, true);
}
alignVertical(nodes[3], inner1[0]);
alignVertical(nodes[4], inner1[2]);
alignVertical(nodes[5], inner2[0]);
alignVertical(nodes[6], inner2[2]);
centerVertical(nodes[1], nodes[3], nodes[4]);
centerVertical(nodes[2], nodes[5], nodes[6]);
centerVertical(nodes[0], nodes[1], nodes[2]);
int[] linksFrom = {0, 0, 1, 1, 2, 2, 3, 4, 5, 6};
int[] linksTo = {1, 2, 3, 4, 5, 6, 7, 9, 11, 13};
for (int i = 0; i < linksFrom.length; i++) {
int fi = linksFrom[i];
IlvGraphic from = nodes[fi];
int ti = linksTo[i];
IlvGraphic to;
if (ti < nodes.length)
to = nodes[ti];
else if (ti < nodes.length + inner1.length)
to = inner1[ti - nodes.length];
else
to = inner2[ti - nodes.length - inner1.length];
IlvLinkImage link = new IlvLinkImage(from, to, true);
grapher.addLink(link, 1, true);
}
}
/**
* Centers a node between two nodes in y direction.
*/
private void centerVertical(IlvGraphic node, IlvGraphic a, IlvGraphic b) {
IlvRect bbox = a.boundingBox();
double min = bbox.y;
bbox = b.boundingBox();
double max = bbox.y + bbox.height;
bbox = node.boundingBox();
grapher.moveObject(node, bbox.x, (max + min - bbox.height) / 2, true);
}
/**
* Aligns two nodes in y direction.
*/
private void alignVertical(IlvGraphic node, IlvGraphic ref) {
IlvManager m = (IlvManager) ref.getGraphicBag();
IlvTransformer t = m.getTopLevelTransformer();
IlvRect bbox = ref.boundingBox(t);
double y = bbox.y;
bbox = node.boundingBox();
grapher.moveObject(node, bbox.x, y, true);
}
/**
* Creates a double nested subgraph.
*/
private IlvGraphic[] createSubGraph(IlvGrapher parent) {
IlvGrapher grapher = new IlvGrapher();
grapher.setSelectionInvariantSubManagerBounds(true);
IlvGraphic[] nodes = new IlvGraphic[4];
IlvPoint[] positions =
{new IlvPoint(20, 0), new IlvPoint(230, 60), new IlvPoint(20, 60), new IlvPoint(230, 0)};
int[] linksFrom = {0, 2, 5, 7, 0, 3};
int[] linksTo = {4, 6, 1, 3, 2, 1};
IlvGraphic[] inner = createSimpleSubGraph(grapher);
for (int i = 0; i < nodes.length; i++) {
nodes[i] = new IlvZoomableLabel(positions[i], "N", false);
setNodeAttributes(nodes[i]);
grapher.addNode(nodes[i], 0, true);
}
for (int i = 0; i < linksFrom.length; i++) {
int fi = linksFrom[i];
IlvGraphic from = (fi < nodes.length ? nodes[fi] : inner[fi - nodes.length]);
int ti = linksTo[i];
IlvGraphic to = (ti < nodes.length ? nodes[ti] : inner[ti - nodes.length]);
IlvLinkImage link = new IlvLinkImage(from, to, true);
grapher.addLink(link, 1, true);
}
IlvDefaultManagerFrame frame = (IlvDefaultManagerFrame) grapher.getFrame();
frame.setOpaque(true);
frame.setBackground(new Color(100, 255, 100));
parent.addNode(grapher, 0, true);
return nodes;
}
/**
* Creates a subgraph.
*/
private IlvGraphic[] createSimpleSubGraph(IlvGrapher parent) {
IlvGrapher grapher = new IlvGrapher();
grapher.setSelectionInvariantSubManagerBounds(true);
IlvGraphic[] nodes = new IlvGraphic[4];
IlvPoint[] positions =
{new IlvPoint(90, 0), new IlvPoint(160, 60), new IlvPoint(90, 60), new IlvPoint(160, 0)};
int[] linksFrom = {0, 2, 0, 3};
int[] linksTo = {3, 1, 2, 1};
for (int i = 0; i < nodes.length; i++) {
nodes[i] = new IlvZoomableLabel(positions[i], "N", false);
setNodeAttributes(nodes[i]);
grapher.addNode(nodes[i], 0, true);
}
for (int i = 0; i < linksFrom.length; i++) {
IlvGraphic from = nodes[linksFrom[i]];
IlvGraphic to = nodes[linksTo[i]];
IlvLinkImage link = new IlvLinkImage(from, to, true);
grapher.addLink(link, 1, true);
}
IlvDefaultManagerFrame frame = (IlvDefaultManagerFrame) grapher.getFrame();
frame.setOpaque(true);
frame.setBackground(new Color(255, 200, 200));
parent.addNode(grapher, 0, true);
return nodes;
}
/**
* Sets the attributes of a node.
*/
private void setNodeAttributes(IlvGraphic node) {
IlvZoomableLabel zl = (IlvZoomableLabel) node;
zl.setAntialiasing(true);
zl.setLeftMargin(6);
zl.setRightMargin(6);
zl.setTopMargin(4);
zl.setBottomMargin(4);
zl.setBorderOn(true);
zl.setBackgroundOn(true);
zl.setBackgroundPaint(Color.yellow);
}
/**
* Allows you to run the demo as a standalone application.
*/
public static void main(String[] arg) {
// Sun recommends putting the entire GUI initialization into the
// AWT thread
SwingUtilities.invokeLater(new Runnable() {
Override
public void run() {
KeyboardSelApp app = new KeyboardSelApp();
app.init();
JFrame frame = new JFrame("Keyboard Selection Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.getContentPane().add(app);
frame.setVisible(true);
}
});
}
}