/*
* 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.
*/
/**
* This examples shows illustrates how to use various
* accessibility features inside a Rogue Wave JViews Diagrammer.
*/
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Font;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.net.URL;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import javax.swing.Box;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JToolBar;
import ilog.views.IlvAccelerator;
import ilog.views.IlvGrapher;
import ilog.views.IlvGraphic;
import ilog.views.IlvManager;
import ilog.views.IlvManagerView;
import ilog.views.IlvRect;
import ilog.views.accelerator.IlvCycleSelectAccelerator;
import ilog.views.accelerator.IlvDeleteSelectionAccelerator;
import ilog.views.accelerator.IlvExpandSelectionAccelerator;
import ilog.views.accelerator.IlvFitToSizeAccelerator;
import ilog.views.accelerator.IlvIdentityAccelerator;
import ilog.views.accelerator.IlvMoveSelectionAccelerator;
import ilog.views.accelerator.IlvPopupMenuAccelerator;
import ilog.views.accelerator.IlvRotateAccelerator;
import ilog.views.accelerator.IlvScrollDownAccelerator;
import ilog.views.accelerator.IlvScrollLeftAccelerator;
import ilog.views.accelerator.IlvScrollRightAccelerator;
import ilog.views.accelerator.IlvScrollUpAccelerator;
import ilog.views.accelerator.IlvSelectAllAccelerator;
import ilog.views.accelerator.IlvZoomInAccelerator;
import ilog.views.accelerator.IlvZoomOutAccelerator;
import ilog.views.diagrammer.IlvDiagrammer;
import ilog.views.diagrammer.IlvDiagrammerProduct;
import ilog.views.diagrammer.application.IlvDiagrammerAction;
import ilog.views.diagrammer.application.IlvDiagrammerFrame;
import ilog.views.diagrammer.application.IlvDiagrammerMenu;
import ilog.views.diagrammer.application.IlvDiagrammerMenuBar;
import ilog.views.diagrammer.project.IlvDiagrammerProject;
import ilog.views.sdm.IlvSDMEngine;
import ilog.views.sdm.IlvSDMView;
import ilog.views.sdm.renderer.IlvRendererUtil;
import ilog.views.swing.IlvPopupMenuContext;
import ilog.views.swing.IlvPopupMenuManager;
import ilog.views.swing.IlvSimplePopupMenu;
import ilog.views.util.IlvProductUtil;
import ilog.views.util.IlvResourceUtil;
import ilog.views.util.internal.IlvSplash;
import ilog.views.util.swing.IlvSwingUtil;
/**
* This is a very simple application that shows how to use various
* accessibility features inside an IlvDiagrammer.
*/
public class AccessibleDiagram extends IlvDiagrammerFrame {
private ResourceBundle bundle;
private URL backgroundStyleSheet;
private URL normalBackgroundStyleSheet;
private URL highContrastBackgroundStyleSheet;
private URL varyShapesStyleSheet;
private URL varyShapesOnStyleSheet;
private URL varyShapesOffStyleSheet;
/**
* The color modes.
*/
private static int NORMAL = 0;
private static int GRAYSCALE = 1;
private static int DEUTAN = 2;
private int colorMode = NORMAL;
private boolean blockColorModeChange = false;
private JMenu colorModeMenu;
/**
* Varying shapes modes.
*/
private boolean varyingShapes = false;
/**
* High contrast mode.
*/
private boolean highContrastMode = false;
/**
* High contrast colors, for the GUI only.
*/
private Color lightColor = new Color(238, 238, 238);
private Color darkColor = new Color(51, 51, 51);
/**
* Fonts for normal contrast.
*/
private Map<Object, Font> normalContrastFonts = new HashMap<Object, Font>();
/**
* Fonts for high contrast.
*/
private Map<Object, Font> highContrastFonts = new HashMap<Object, Font>();
/**
* The popup menu.
*/
private JPopupMenu popupMenu = null;
/**
* The about dialog.
*/
private JDialog aboutDialog = null;
/**
* The label showing the keypress.
*/
private JLabel statusLabel = new JLabel("No focus on view");
/**
* Comparator for the traversal order: nesting has highest, then x has
* priority
*/
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();
}
// use model coordinates, not graphic coordinates to have a
// predictive behavior
IlvSDMEngine engine = IlvSDMEngine.getSDMEngine(a);
if (IlvSDMEngine.getSDMEngine(b) != engine)
return 0;
Object ma = engine.getObject(a);
Object mb = engine.getObject(b);
if (ma == mb)
return 0;
if (ma == null)
return -1;
if (mb == null)
return 1;
// does not work when coordinates are not stored in the model
// or when coordinates are stored as latitude/logitude
float ax = IlvRendererUtil.getGraphicPropertyAsFloat(engine, ma, "x", null, -1);
float bx = IlvRendererUtil.getGraphicPropertyAsFloat(engine, mb, "x", null, -1);
if (ax < bx)
return -1;
if (ax > bx)
return 1;
float ay = IlvRendererUtil.getGraphicPropertyAsFloat(engine, ma, "y", null, -1);
float by = IlvRendererUtil.getGraphicPropertyAsFloat(engine, mb, "y", null, -1);
if (ay < by)
return -1;
if (ay > by)
return 1;
return 0;
}
};
public static void main(final String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
Override
public void run() {
AccessibleDiagram app = new AccessibleDiagram();
app.init(args);
}
});
}
public AccessibleDiagram() {
super(new String[] { "-simple" });
}
/**
* This method is overridden to change the size of the frame.
*/
Override
public void initFrame() {
super.initFrame();
setSize(800, 400);
}
/**
* Initializes the GUI.
*
* @param contentPane
* The container of the application.
*/
Override
public void init(Container contentPane) {
// 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);
bundle = ResourceBundle.getBundle("accessibledemo");
try {
URL documentBase = new URL("file:./");
normalBackgroundStyleSheet = new URL(documentBase, "data/background.css");
highContrastBackgroundStyleSheet = new URL(documentBase, "data/backgroundHC.css");
varyShapesOnStyleSheet = new URL(documentBase, "data/varyshapeon.css");
varyShapesOffStyleSheet = new URL(documentBase, "data/varyshapeoff.css");
} catch (Exception ex) {
ex.printStackTrace();
}
super.init(contentPane);
// remove the items that we don't need
IlvDiagrammerMenuBar menuBar = (IlvDiagrammerMenuBar) getJMenuBar();
int idx = menuBar.getFileMenu().indexOf(IlvDiagrammerAction.printWithDialog);
if (idx > 0) {
try {
idx--;
// separator
menuBar.getFileMenu().remove(idx);
// the printWithDiaglog
menuBar.getFileMenu().remove(idx);
} catch (Exception ex) {
}
}
// change the about dialog
IlvDiagrammerMenu helpMenu = menuBar.getDiagrammerHelpMenu();
final IlvDiagrammerAction aboutAction = new IlvDiagrammerAction("Diagrammer.Action.About") {
Override
protected boolean isEnabled(IlvDiagrammer diagrammer) throws Exception {
return true;
}
Override
public void perform(ActionEvent e, IlvDiagrammer diagrammer) throws Exception {
if (aboutDialog == null)
return;
aboutDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
aboutDialog.setVisible(true);
}
};
helpMenu.insertAction(aboutAction, 0);
try {
helpMenu.remove(1);
} catch (Exception ex) {
}
// remove the properties and tree view
JToolBar viewToolBar = getViewToolBar();
try {
viewToolBar.remove(8);
viewToolBar.remove(7);
} catch (Exception ex) {
}
// remove the properties and tree view
IlvDiagrammerMenu viewMenu = menuBar.getViewMenu();
try {
viewMenu.remove(6);
viewMenu.remove(5);
} catch (Exception ex) {
}
// enhance the view menu with the high contrast mode
highContrastMode = IlvSwingUtil.isHighContrastMode();
final IlvDiagrammerAction.ToggleAction hcAction = new IlvDiagrammerAction.ToggleAction(
"AccessibleDiagram.HighContrast", bundle) {
Override
protected boolean isEnabled(IlvDiagrammer diagrammer) throws Exception {
return true;
}
Override
protected boolean isSelected(IlvDiagrammer diagrammer) throws Exception {
return highContrastMode;
}
Override
protected void setSelected(IlvDiagrammer diagrammer, boolean selected) throws Exception {
if (selected) {
setHighContrast(true);
} else {
setHighContrast(false);
}
}
};
viewMenu.insertAction(hcAction, 0);
viewMenu.insertSeparator(1);
final IlvDiagrammerAction.ToggleAction vsAction = new IlvDiagrammerAction.ToggleAction(
"AccessibleDiagram.VaryShapes", bundle) {
Override
protected boolean isEnabled(IlvDiagrammer diagrammer) throws Exception {
return true;
}
Override
protected boolean isSelected(IlvDiagrammer diagrammer) throws Exception {
return varyingShapes;
}
Override
protected void setSelected(IlvDiagrammer diagrammer, boolean selected) throws Exception {
setVaryShapesCSS(selected);
varyingShapes = selected;
}
};
viewMenu.insertAction(vsAction, 2);
// submenu for the drawing mode
colorModeMenu = new JMenu(getString("AccessibleDiagram.ColorMode.Name"));
colorModeMenu.setOpaque(true);
final JCheckBoxMenuItem[] colorModeChoices = new JCheckBoxMenuItem[3];
colorModeChoices[0] = new JCheckBoxMenuItem(getString("AccessibleDiagram.ColorMode.Normal"));
colorModeChoices[1] = new JCheckBoxMenuItem(getString("AccessibleDiagram.ColorMode.Grayscale"));
colorModeChoices[2] = new JCheckBoxMenuItem(getString("AccessibleDiagram.ColorMode.Deutan"));
ActionListener action = new ActionListener() {
Override
public void actionPerformed(ActionEvent evt) {
if (blockColorModeChange)
return;
blockColorModeChange = true;
try {
Object src = evt.getSource();
for (int i = 0; i < colorModeChoices.length; i++) {
if (src == colorModeChoices[i])
colorMode = i;
colorModeChoices[i].setSelected(false);
}
colorModeChoices[colorMode].setSelected(true);
} finally {
blockColorModeChange = false;
}
getCurrentDiagrammer().getView().repaint();
}
};
colorModeChoices[0].setSelected(true);
for (int i = 0; i < colorModeChoices.length; i++) {
colorModeChoices[i].addActionListener(action);
colorModeMenu.add(colorModeChoices[i]);
}
viewMenu.add(colorModeMenu, 3);
viewMenu.insertSeparator(4);
// add the status label at the right side of the menu bar
menuBar.add(Box.createHorizontalGlue());
menuBar.add(statusLabel);
// exchange the grapher with one that notifies the status label
IlvDiagrammer diagrammer = getCurrentDiagrammer();
diagrammer.getEngine().setGrapher(new IlvGrapher() {
Override
protected boolean handleAccelerators(AWTEvent evt, IlvManagerView view) {
if (evt instanceof KeyEvent) {
KeyEvent kev = (KeyEvent) evt;
if (kev.getID() == KeyEvent.KEY_PRESSED) {
statusLabel.setText(getKeyEventLabel(kev));
}
}
return super.handleAccelerators(evt, view);
}
});
diagrammer.getView().setManager(diagrammer.getEngine().getGrapher());
// set the manager view to revieve TAB events
IlvManagerView mgrview = diagrammer.getView();
mgrview.setFocusable(true);
mgrview.setFocusCycleRoot(true);
mgrview.setFocusTraversalKeysEnabled(false);
mgrview.addFocusListener(new FocusListener() {
Override
public void focusGained(FocusEvent e) {
statusLabel.setText("Key:0x----(-)---------");
}
Override
public void focusLost(FocusEvent e) {
statusLabel.setText("No focus on view");
}
});
// install the accelerators
installAccelerators(diagrammer.getEngine().getGrapher());
// install the popup menu
// register view view to the popup manager
IlvPopupMenuManager.registerView(diagrammer.getView());
// register the menu
IlvPopupMenuManager.registerMenu("MENU", popupMenu = createPopupMenu());
// allocate the about dialog
aboutDialog = IlvSplash.createSplashDialog(diagrammer, null, null, null, "Rogue Wave JViews Diagrammer Demo", "",
IlvDiagrammerProduct.getVersion(), IlvDiagrammerProduct.getMinorVersion(),
IlvDiagrammerProduct.getSubMinorVersion(), IlvDiagrammerProduct.getPatchLevel(),
IlvDiagrammerProduct.getBuildNumber(), IlvDiagrammerProduct.getReleaseDate());
// check whether we started with high contrast node
Toolkit toolkit = Toolkit.getDefaultToolkit();
Boolean highContrast = (Boolean) toolkit.getDesktopProperty("win.highContrast.on");
if (highContrast != null && highContrast.booleanValue()) {
setHighContrast(true);
}
}
/**
* Loads the first diagram.
*/
Override
protected void ready() {
super.ready();
loadDiagram();
// fit to the initial part
IlvSDMView view = getCurrentDiagrammer().getView();
view.fitTransformerToArea(null, new IlvManagerView.FitAreaCalculator() {
Override
public IlvRect getAreaToFit(IlvManagerView view) {
return new IlvRect(-420, 100, 200, 200);
}
}, 1, true);
}
/**
* Loads a diagram.
*
* @param project
* The diagram project to load.
*/
private void loadDiagram() {
try {
URL documentBase = new URL("file:./");
URL url = new URL(documentBase, "data/accsample.idpr");
IlvDiagrammerProject project = new IlvDiagrammerProject(url);
getCurrentDiagrammer().setProject(project);
// add the style sheet for baclground
backgroundStyleSheet = normalBackgroundStyleSheet;
varyShapesStyleSheet = varyShapesOffStyleSheet;
getCurrentDiagrammer().addStyleSheet(backgroundStyleSheet);
getCurrentDiagrammer().addStyleSheet(varyShapesStyleSheet);
} catch (Exception e1) {
e1.printStackTrace();
}
setHighContrastCSS(getCurrentDiagrammer(), highContrastMode);
setVaryShapesCSS(varyingShapes);
}
/**
* Sets the high contrast code.
*/
private void setHighContrast(boolean on) {
if (on == highContrastMode)
return;
highContrastMode = on;
setHighContrastCSS(getCurrentDiagrammer(), on);
Container c = getCurrentDiagrammer();
while (c.getParent() != null)
c = c.getParent();
setHighContrast(c, on);
if (popupMenu != null) {
setHighContrast(popupMenu, on);
}
if (aboutDialog != null) {
setHighContrast(aboutDialog, on);
}
setHighContrast(getOverview(), on);
}
/**
* Sets high contrast on a hierarchy of Swing components. This is usually not
* needed, if the high contrast mode was set at the operating level already
* when starting this demo. We do this code in this demo only to illustrate
* and to be able to switch the high contrast mode dynamically on the fly.
*/
void setHighContrast(Container c, boolean on) {
c.setForeground(on ? lightColor : darkColor);
c.setBackground(on ? darkColor : lightColor);
adaptFont(c, on);
if (c instanceof JMenu) {
Component[] cs = ((JMenu) c).getMenuComponents();
if (cs == null)
return;
for (int i = 0; i < cs.length; i++) {
if (cs[i] instanceof Container)
setHighContrast((Container) cs[i], on);
}
} else {
Component[] cs = c.getComponents();
if (cs == null)
return;
for (int i = 0; i < cs.length; i++) {
if (cs[i] instanceof Container)
setHighContrast((Container) cs[i], on);
}
}
}
/**
* Adapt the font to high contrast on a component.
*/
void adaptFont(Component c, boolean highContrast) {
if (c.isFontSet()) {
Font oldFont = c.getFont();
Font newFont = getAdapted(oldFont, c, highContrast);
c.setFont(newFont);
}
}
/**
* Returns the high or low contrast font.
*/
Font getAdapted(Font oldFont, Object key, boolean highContrast) {
Font newFont = null;
if (highContrast) {
if (normalContrastFonts.get(key) == null)
normalContrastFonts.put(key, oldFont);
newFont = (Font) highContrastFonts.get(key);
if (newFont == null) {
newFont = new Font(oldFont.getName(), oldFont.getStyle(), (int) (oldFont.getSize() * 1.2));
highContrastFonts.put(key, newFont);
}
} else {
if (highContrastFonts.get(key) == null)
highContrastFonts.put(key, oldFont);
newFont = (Font) normalContrastFonts.get(key);
if (newFont == null) {
newFont = new Font(oldFont.getName(), oldFont.getStyle(), (int) (oldFont.getSize() / 1.2));
normalContrastFonts.put(key, newFont);
}
}
return newFont;
}
/**
* Sets the CSS for high contrast.
*/
private void setHighContrastCSS(IlvDiagrammer diagrammer, boolean on) {
String theme = on ? IlvSDMEngine.HIGH_CONTRAST : IlvSDMEngine.NORMAL_CONTRAST;
diagrammer.getEngine().setContrastAccessibilityTheme(theme);
try {
diagrammer.removeStyleSheet(backgroundStyleSheet);
backgroundStyleSheet = on ? highContrastBackgroundStyleSheet : normalBackgroundStyleSheet;
diagrammer.addStyleSheet(backgroundStyleSheet);
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Sets the CSS for varying shapes.
*/
private void setVaryShapesCSS(boolean on) {
IlvDiagrammer diagrammer = getCurrentDiagrammer();
try {
diagrammer.removeStyleSheet(varyShapesStyleSheet);
varyShapesStyleSheet = on ? varyShapesOnStyleSheet : varyShapesOffStyleSheet;
diagrammer.addStyleSheet(varyShapesStyleSheet);
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Install all accelerators.
*/
private void installAccelerators(IlvGrapher grapher) {
// F1 -> popup menu
// P -> popup menu
// TAB -> select forward
// Shift TAB -> select backward
// F -> select forward
// B -> select backward
// A -> select all
// Ctrl A -> deselect all
// Ctrl 0 -> Identity zoom
// Ctrl F -> Fit zoom
// Ctrl - -> Zoom out
// Ctrl + -> Zoom in
// Ctrl R -> Rotate view
// Arrow up -> Scroll up
// Arrow down -> Scroll down
// Arrow left -> Scroll left
// Arrow right -> Scroll right
// Shift Arrow up -> Move selection up
// Shift Arrow down -> Move selection down
// Shift Arrow left -> Move selection left
// Shift Arrow right -> Move selection right
// Delete key -> Delete selection
// E -> Expand selection
IlvPopupMenuAccelerator popupAcc;
IlvCycleSelectAccelerator selAcc;
IlvMoveSelectionAccelerator movAcc;
IlvSelectAllAccelerator selAllAcc;
IlvAccelerator acc;
// just for shorter writing
int keypress = KeyEvent.KEY_PRESSED;
// int keyrelease = KeyEvent.KEY_RELEASED;
int shift = KeyEvent.SHIFT_MASK;
int ctrl = KeyEvent.CTRL_MASK;
// int ctsht = KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK;
char unspecCode = KeyEvent.VK_UNDEFINED;
// popup menu
popupAcc = new IlvPopupMenuAccelerator(keypress, KeyEvent.VK_F1, 0, true);
grapher.addAccelerator(popupAcc);
popupAcc = new IlvPopupMenuAccelerator(keypress, unspecCode, 'p', 0, true);
grapher.addAccelerator(popupAcc);
popupAcc = new IlvPopupMenuAccelerator(keypress, unspecCode, 'P', shift, true);
grapher.addAccelerator(popupAcc);
// select all
selAllAcc = new IlvSelectAllAccelerator(keypress, unspecCode, 'a', 0, true);
selAllAcc.setTraverse(true);
grapher.addAccelerator(selAllAcc);
selAllAcc = new IlvSelectAllAccelerator(keypress, unspecCode, 'A', shift, true);
selAllAcc.setTraverse(true);
grapher.addAccelerator(selAllAcc);
selAllAcc = new IlvSelectAllAccelerator(keypress, KeyEvent.VK_A, ctrl, true);
selAllAcc.setTraverse(true);
selAllAcc.setSelectAll(false);
grapher.addAccelerator(selAllAcc);
// select
selAcc = new IlvCycleSelectAccelerator(keypress, KeyEvent.VK_TAB, 0, true);
selAcc.setForward(true);
selAcc.setComparator(nestedThenXThenY);
grapher.addAccelerator(selAcc);
selAcc = new IlvCycleSelectAccelerator(keypress, unspecCode, 'f', 0, true);
selAcc.setForward(true);
selAcc.setComparator(nestedThenXThenY);
grapher.addAccelerator(selAcc);
selAcc = new IlvCycleSelectAccelerator(keypress, unspecCode, 'F', shift, true);
selAcc.setForward(true);
selAcc.setComparator(nestedThenXThenY);
grapher.addAccelerator(selAcc);
selAcc = new IlvCycleSelectAccelerator(keypress, KeyEvent.VK_TAB, shift, true);
selAcc.setForward(false);
selAcc.setComparator(nestedThenXThenY);
grapher.addAccelerator(selAcc);
selAcc = new IlvCycleSelectAccelerator(keypress, unspecCode, 'b', 0, true);
selAcc.setForward(false);
selAcc.setComparator(nestedThenXThenY);
grapher.addAccelerator(selAcc);
selAcc = new IlvCycleSelectAccelerator(keypress, unspecCode, 'B', shift, true);
selAcc.setForward(false);
selAcc.setComparator(nestedThenXThenY);
grapher.addAccelerator(selAcc);
acc = new IlvDeleteSelectionAccelerator(keypress, KeyEvent.VK_DELETE, 0, true) {
Override
protected boolean handleEvent(IlvManagerView v) {
// super.handleEvents deals only with the graphic objects, but
// we also need to delete the model objects
if (v instanceof IlvSDMView) {
IlvSDMEngine engine = ((IlvSDMView) v).getSDMEngine();
// delete the selected objects
engine.delete();
}
// in case there are graphics that don't correspond to model objects
return super.handleEvent(v);
}
};
grapher.addAccelerator(acc);
acc = new IlvIdentityAccelerator(keypress, KeyEvent.VK_HOME, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvIdentityAccelerator(keypress, '0', ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvIdentityAccelerator(keypress, KeyEvent.VK_NUMPAD0, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvIdentityAccelerator(keypress, KeyEvent.VK_INSERT, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvZoomOutAccelerator(keypress, KeyEvent.VK_SUBTRACT, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvZoomOutAccelerator(keypress, unspecCode, '-', ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvZoomInAccelerator(keypress, KeyEvent.VK_ADD, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvZoomInAccelerator(keypress, unspecCode, '+', ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvFitToSizeAccelerator(keypress, KeyEvent.VK_NUMPAD5, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvFitToSizeAccelerator(keypress, KeyEvent.VK_BEGIN, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvFitToSizeAccelerator(keypress, KeyEvent.VK_F, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvRotateAccelerator(keypress, KeyEvent.VK_R, ctrl, true);
grapher.addAccelerator(acc);
// scroll with normal arrows
acc = new IlvScrollUpAccelerator(keypress, KeyEvent.VK_UP, 0, true);
grapher.addAccelerator(acc);
acc = new IlvScrollDownAccelerator(keypress, KeyEvent.VK_DOWN, 0, true);
grapher.addAccelerator(acc);
acc = new IlvScrollRightAccelerator(keypress, KeyEvent.VK_RIGHT, 0, true);
grapher.addAccelerator(acc);
acc = new IlvScrollLeftAccelerator(keypress, KeyEvent.VK_LEFT, 0, true);
grapher.addAccelerator(acc);
// scroll with numpad
acc = new IlvScrollUpAccelerator(keypress, KeyEvent.VK_NUMPAD8, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvScrollDownAccelerator(keypress, KeyEvent.VK_NUMPAD2, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvScrollLeftAccelerator(keypress, KeyEvent.VK_NUMPAD4, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvScrollRightAccelerator(keypress, KeyEvent.VK_NUMPAD6, ctrl, true);
grapher.addAccelerator(acc);
// scroll with arrows on numpad
acc = new IlvScrollUpAccelerator(keypress, KeyEvent.VK_KP_UP, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvScrollDownAccelerator(keypress, KeyEvent.VK_KP_DOWN, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvScrollLeftAccelerator(keypress, KeyEvent.VK_KP_LEFT, ctrl, true);
grapher.addAccelerator(acc);
acc = new IlvScrollRightAccelerator(keypress, KeyEvent.VK_KP_RIGHT, ctrl, true);
grapher.addAccelerator(acc);
// move with normal arrows
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_UP, shift, true);
movAcc.setMoveVector(0, -10);
grapher.addAccelerator(movAcc);
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_DOWN, shift, true);
movAcc.setMoveVector(0, 10);
grapher.addAccelerator(movAcc);
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_LEFT, shift, true);
movAcc.setMoveVector(-10, 0);
grapher.addAccelerator(movAcc);
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_RIGHT, shift, true);
movAcc.setMoveVector(10, 0);
grapher.addAccelerator(movAcc);
// move with numpad
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_NUMPAD8, shift, true);
movAcc.setMoveVector(0, -5);
grapher.addAccelerator(movAcc);
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_NUMPAD2, shift, true);
movAcc.setMoveVector(0, 5);
grapher.addAccelerator(movAcc);
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_NUMPAD4, shift, true);
movAcc.setMoveVector(-5, 0);
grapher.addAccelerator(movAcc);
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_NUMPAD6, shift, true);
movAcc.setMoveVector(5, 0);
grapher.addAccelerator(movAcc);
// move with arrows on numpad
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_KP_UP, shift, true);
movAcc.setMoveVector(0, -3);
grapher.addAccelerator(movAcc);
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_KP_DOWN, shift, true);
movAcc.setMoveVector(0, 3);
grapher.addAccelerator(movAcc);
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_KP_LEFT, shift, true);
movAcc.setMoveVector(-3, 0);
grapher.addAccelerator(movAcc);
movAcc = new IlvMoveSelectionAccelerator(keypress, KeyEvent.VK_KP_RIGHT, shift, true);
movAcc.setMoveVector(3, 0);
grapher.addAccelerator(movAcc);
// expand selection
acc = new IlvExpandSelectionAccelerator(keypress, KeyEvent.VK_E, 0, true);
grapher.addAccelerator(acc);
acc = new IlvExpandSelectionAccelerator(keypress, KeyEvent.VK_E, shift, true);
grapher.addAccelerator(acc);
}
/**
* Returns the indicator of a key event.
*/
private String getKeyEventLabel(KeyEvent ev) {
String digits = "0123456789ABCDEF";
StringBuffer buf = new StringBuffer("Key:0x");
int code = ev.getKeyCode();
code = code & 0xffff;
int d = code / 4096;
buf.append(digits.charAt(d));
code -= d * 4096;
d = code / 256;
buf.append(digits.charAt(d));
code -= d * 256;
d = code / 16;
buf.append(digits.charAt(d));
code -= d * 16;
buf.append(digits.charAt(code));
buf.append('(');
if (ev.getKeyChar() == KeyEvent.CHAR_UNDEFINED) {
// nothing
} else if (Character.isISOControl(ev.getKeyChar())) {
code = (int) ev.getKeyChar();
code = code & 0xff;
d = code / 16;
buf.append(digits.charAt(d));
code -= d * 16;
buf.append(digits.charAt(code));
} else {
buf.append(ev.getKeyChar());
}
buf.append(')');
int mod = ev.getModifiers();
boolean shift = ((mod & InputEvent.SHIFT_MASK) != 0);
boolean ctrl = ((mod & InputEvent.CTRL_MASK) != 0);
boolean alt = ((mod & InputEvent.ALT_MASK) != 0);
boolean meta = ((mod & InputEvent.META_MASK) != 0);
boolean altgr = ((mod & InputEvent.ALT_GRAPH_MASK) != 0);
int count = 0;
if (shift)
count++;
if (ctrl)
count++;
if (alt)
count++;
if (meta)
count++;
if (altgr)
count++;
if (shift) {
if (count > 4)
buf.append("S");
else if (count >= 3)
buf.append("Sh");
else if (count == 2)
buf.append("Shft");
else
buf.append("Shift");
}
if (ctrl) {
if (count > 4)
buf.append("C");
else if (count >= 3)
buf.append("Ct");
else if (count == 2)
buf.append("Ctrl");
else
buf.append("Control");
}
if (alt) {
if (count > 4)
buf.append("A");
else if (count >= 3)
buf.append("Al");
else
buf.append("Alt");
}
if (meta) {
if (count > 4)
buf.append("M");
else if (count >= 3)
buf.append("Me");
else
buf.append("Meta");
}
if (altgr) {
if (count > 4)
buf.append("a");
else if (count >= 3)
buf.append("Ag");
else if (count == 2)
buf.append("Algr");
else
buf.append("Altgraph");
}
if (ev.isConsumed())
buf.append("*");
else
buf.append(" ");
return buf.toString();
}
/**
* Creates the popup menu.
*/
private JPopupMenu createPopupMenu() {
// create the action listener for the popup menu
ActionListener actionListener = new ActionListener() {
Override
public void actionPerformed(ActionEvent e) {
// retrieve the selected menu item
JMenuItem m = (JMenuItem) e.getSource();
// retrieve the graphic that has this popup menu
IlvPopupMenuContext context = IlvPopupMenuManager.getPopupMenuContext(m);
IlvGraphic graphic = context.getGraphic();
// do the action
if (m.getText().equals("Shift left")) {
IlvRect bbox = graphic.boundingBox();
bbox.x -= 20;
IlvManager manager = (IlvManager) graphic.getGraphicBag();
// this will also notify the model
manager.moveObject(graphic, bbox.x, bbox.y, true);
} else if (m.getText().equals("Shift right")) {
IlvRect bbox = graphic.boundingBox();
bbox.x += 20;
IlvManager manager = (IlvManager) graphic.getGraphicBag();
// this will also notify the model
manager.moveObject(graphic, bbox.x, bbox.y, true);
}
}
};
// create a simple popup menu with the following items
// - Make larger: makes the graphic larger
// - Make smaller: makes the graphic smaller
IlvSimplePopupMenu menu = new IlvSimplePopupMenu("Menu1", "Shift left | Shift right", null, actionListener);
return menu;
}
/**
* Creates a new diagrammer.
*/
Override
protected IlvDiagrammer createDiagrammer() {
IlvSDMView view = new IlvSDMView() {
Override
protected Image createDoubleBufferImage(int width, int height) {
return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
Override
protected void doubleBufferedImageUpToDate(Image doubleBufferImage) {
super.doubleBufferedImageUpToDate(doubleBufferImage);
adaptBuffer(doubleBufferImage);
}
};
// enable double buffering to allow the colorMode GRAYSCALE...
view.setDoubleBuffering(true);
// keep aspect ratio
view.setKeepingAspectRatio(true);
return new IlvDiagrammer(view);
}
/**
* Adapts the double buffer to the color mode.
*/
private void adaptBuffer(Image image) {
if (colorMode == GRAYSCALE) {
BufferedImage buffer = (BufferedImage) image;
WritableRaster raster = buffer.copyData(null);
int mx = raster.getMinX();
int my = raster.getMinY();
int w = raster.getWidth();
int h = raster.getHeight();
int[] data = null;
for (int x = mx; x < mx + w; x++) {
for (int y = my; y < my + h; y++) {
data = raster.getPixel(x, y, data);
if (data[0] == data[1] && data[1] == data[2])
continue;
int g = (int) (0.299 * data[0] + 0.587 * data[1] + 0.114 * data[2]);
if (g < 0)
g = 0;
if (g > 255)
g = 255;
data[0] = data[1] = data[2] = g;
raster.setPixel(x, y, data);
}
}
buffer.setData(raster);
} else if (colorMode == DEUTAN) {
// There are many variants of red green blind. This is just one of them.
BufferedImage buffer = (BufferedImage) image;
WritableRaster raster = buffer.copyData(null);
int mx = raster.getMinX();
int my = raster.getMinY();
int w = raster.getWidth();
int h = raster.getHeight();
int[] data = null;
for (int x = mx; x < mx + w; x++) {
for (int y = my; y < my + h; y++) {
data = raster.getPixel(x, y, data);
if (data[0] == data[1])
continue;
int g = (int) (0.337 * data[0] + 0.663 * data[1]);
if (g < 0)
g = 0;
if (g > 255)
g = 255;
data[0] = data[1] = g;
raster.setPixel(x, y, data);
}
}
buffer.setData(raster);
}
}
/**
* Returns a string from the resource bundle.
*/
private String getString(String key) {
try {
return bundle.getString(key);
} catch (Exception ex) {
return key;
}
}
}