assign keyboard shortcuts to components

This commit is contained in:
bancika
2017-04-21 17:04:11 +02:00
parent 6458dfd39b
commit 2bd78110a7
5 changed files with 169 additions and 2 deletions
Binary file not shown.
Binary file not shown.
@@ -19,15 +19,22 @@ import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.image.VolatileImage; import java.awt.image.VolatileImage;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import org.apache.log4j.Logger;
import org.diylc.appframework.miscutils.ConfigurationManager; import org.diylc.appframework.miscutils.ConfigurationManager;
import org.diylc.common.ComponentType;
import org.diylc.common.DrawOption; import org.diylc.common.DrawOption;
import org.diylc.common.IBlockProcessor.InvalidBlockException;
import org.diylc.common.IPlugInPort; import org.diylc.common.IPlugInPort;
import org.diylc.swing.plugins.tree.TreePanel;
/** /**
* GUI class used to draw onto. * GUI class used to draw onto.
@@ -38,6 +45,8 @@ public class CanvasPanel extends JComponent implements Autoscroll {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Logger LOG = Logger.getLogger(CanvasPlugin.class);
private IPlugInPort plugInPort; private IPlugInPort plugInPort;
private Image bufferImage; private Image bufferImage;
@@ -53,6 +62,8 @@ public class CanvasPanel extends JComponent implements Autoscroll {
// DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.ANTIALIASING, // DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.ANTIALIASING,
// DrawOption.CONTROL_POINTS); // DrawOption.CONTROL_POINTS);
private HashMap<String, ComponentType> componentTypeCache;
public CanvasPanel(IPlugInPort plugInPort) { public CanvasPanel(IPlugInPort plugInPort) {
super(); super();
this.plugInPort = plugInPort; this.plugInPort = plugInPort;
@@ -70,6 +81,17 @@ public class CanvasPanel extends JComponent implements Autoscroll {
bufferImage = null; bufferImage = null;
} }
public HashMap<String, ComponentType> getComponentTypeCache() {
if (componentTypeCache == null) {
componentTypeCache = new HashMap<String, ComponentType>();
for (Entry<String, List<ComponentType>> entry : this.plugInPort.getComponentTypes().entrySet()) {
for (ComponentType type : entry.getValue())
componentTypeCache.put(type.getInstanceClass().getCanonicalName(), type);
}
}
return componentTypeCache;
}
private void initializeDnD() { private void initializeDnD() {
// Initialize drag source recognizer. // Initialize drag source recognizer.
DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(this, DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(this,
@@ -80,6 +102,21 @@ public class CanvasPanel extends JComponent implements Autoscroll {
private void initializeActions() { private void initializeActions() {
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "clearSlot"); getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "clearSlot");
for (int i = 1; i <= 12; i++) {
final int x = i;
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F1 + i - 1, 0),
"functionKey" + i);
getActionMap().put("functionKey" + i, new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
functionKeyPressed(x);
}
});
}
getActionMap().put("clearSlot", new AbstractAction() { getActionMap().put("clearSlot", new AbstractAction() {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -91,6 +128,35 @@ public class CanvasPanel extends JComponent implements Autoscroll {
}); });
} }
@SuppressWarnings("unchecked")
protected void functionKeyPressed(int i) {
HashMap<String, String> shortcutMap =
(HashMap<String, String>) ConfigurationManager.getInstance().readObject(TreePanel.COMPONENT_SHORTCUT_KEY, null);
if (shortcutMap == null)
return;
String typeName = shortcutMap.get("F" + i);
if (typeName == null)
return;
if (typeName.startsWith("block:")) {
String blockName = typeName.substring(6);
try {
plugInPort.loadBlock(blockName);
} catch (InvalidBlockException e) {
LOG.error("Could not find block assigned to shortcut: " + blockName);
}
} else {
ComponentType type = getComponentTypeCache().get(typeName);
if (type == null) {
LOG.error("Could not find type: " + typeName);
return;
}
this.plugInPort.setNewComponentTypeSlot(type, null);
}
// hack: fake mouse movement to repaint
this.plugInPort.mouseMoved(getMousePosition(), false, false, false);
}
protected void createBufferImage() { protected void createBufferImage() {
if (USE_HARDWARE_ACCELLERATION) { if (USE_HARDWARE_ACCELLERATION) {
bufferImage = screenGraphicsConfiguration.createCompatibleVolatileImage(getWidth(), getHeight()); bufferImage = screenGraphicsConfiguration.createCompatibleVolatileImage(getWidth(), getHeight());
@@ -9,6 +9,7 @@ import java.awt.Graphics2D;
import java.awt.GridBagConstraints; import java.awt.GridBagConstraints;
import java.awt.GridBagLayout; import java.awt.GridBagLayout;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter; import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent; import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
@@ -17,12 +18,16 @@ import java.awt.event.MouseListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JMenu;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
@@ -60,6 +65,8 @@ public class TreePanel extends JPanel {
private static final Logger LOG = Logger.getLogger(TreePanel.class); private static final Logger LOG = Logger.getLogger(TreePanel.class);
public static final String COMPONENT_SHORTCUT_KEY = "componentShortcuts";
private DefaultTreeModel treeModel; private DefaultTreeModel treeModel;
private JTree tree; private JTree tree;
private JScrollPane treeScroll; private JScrollPane treeScroll;
@@ -312,9 +319,78 @@ public class TreePanel extends JPanel {
Payload payload = (Payload) selectedNode.getUserObject(); Payload payload = (Payload) selectedNode.getUserObject();
ComponentType componentType = payload.getComponentType(); final ComponentType componentType = payload.getComponentType();
final String identifier =
componentType == null ? "block:" + payload.toString() : componentType.getInstanceClass()
.getCanonicalName();
JMenu shortcutSubmenu = new JMenu("Assign Shortcut");
final JMenuItem noneItem = new JMenuItem("None");
noneItem.addActionListener(new ActionListener() {
@SuppressWarnings("unchecked")
@Override
public void actionPerformed(ActionEvent e) {
HashMap<String, String> map =
(HashMap<String, String>) ConfigurationManager.getInstance().readObject(COMPONENT_SHORTCUT_KEY, null);
if (map == null)
map = new HashMap<String, String>();
Iterator<Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> item = it.next();
if (item.getValue().equals(identifier))
it.remove();
}
ConfigurationManager.getInstance().writeValue(COMPONENT_SHORTCUT_KEY, map);
TreePanel.this.invalidate();
TreePanel.this.repaint();
}
});
shortcutSubmenu.add(noneItem);
for (int i = 1; i <= 12; i++) {
final JMenuItem item = new JMenuItem("F" + i);
item.addActionListener(new ActionListener() {
@SuppressWarnings("unchecked")
@Override
public void actionPerformed(ActionEvent e) {
HashMap<String, String> map =
(HashMap<String, String>) ConfigurationManager.getInstance().readObject(COMPONENT_SHORTCUT_KEY,
null);
if (map == null)
map = new HashMap<String, String>();
if (map.containsKey(item.getText()))
map.remove(item.getText());
Iterator<Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Entry<String, String> item = it.next();
if (item.getValue().equals(identifier))
it.remove();
}
map.put(item.getText(), identifier);
ConfigurationManager.getInstance().writeValue(COMPONENT_SHORTCUT_KEY, map);
TreePanel.this.invalidate();
TreePanel.this.repaint();
}
});
shortcutSubmenu.add(item);
}
if (componentType != null) { if (componentType != null) {
popup.add(new SelectAllAction(plugInPort)); popup.add(new SelectAllAction(plugInPort));
popup.add(shortcutSubmenu);
popup.add(new JSeparator()); popup.add(new JSeparator());
List<Template> templates = plugInPort.getTemplatesFor(componentType.getCategory(), componentType.getName()); List<Template> templates = plugInPort.getTemplatesFor(componentType.getCategory(), componentType.getName());
@@ -329,6 +405,7 @@ public class TreePanel extends JPanel {
} }
} }
} else if (selectedNode.isLeaf()) { } else if (selectedNode.isLeaf()) {
popup.add(shortcutSubmenu);
popup.add(new DeleteBlockAction(plugInPort, payload.toString())); popup.add(new DeleteBlockAction(plugInPort, payload.toString()));
} }
} }
@@ -453,6 +530,7 @@ public class TreePanel extends JPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@SuppressWarnings("unchecked")
@Override @Override
public Component getTreeCellRendererComponent(final JTree tree, final Object value, final boolean selected, public Component getTreeCellRendererComponent(final JTree tree, final Object value, final boolean selected,
final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) { final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) {
@@ -476,10 +554,29 @@ public class TreePanel extends JPanel {
+ "<br><br>Left click to instantiate this component, right click for more options" + "</html>"); + "<br><br>Left click to instantiate this component, right click for more options" + "</html>");
setIcon(payload.getComponentType().getIcon()); setIcon(payload.getComponentType().getIcon());
if (payload.isVisible()) if (payload.isVisible())
setPreferredSize(new Dimension(240, 32)); setPreferredSize(new Dimension(180, 32));
else else
setPreferredSize(new Dimension(0, 0)); setPreferredSize(new Dimension(0, 0));
} }
if (payload.isVisible()) {
HashMap<String, String> shortcutMap =
(HashMap<String, String>) ConfigurationManager.getInstance().readObject(TreePanel.COMPONENT_SHORTCUT_KEY,
null);
String identifier =
payload.getComponentType() == null ? "block:" + payload.toString() : payload.getComponentType()
.getInstanceClass().getCanonicalName();
if (shortcutMap != null && shortcutMap.containsValue(identifier)) {
for (String key : shortcutMap.keySet()) {
if (shortcutMap.get(key).equals(identifier)) {
setText("<html>"
+ payload.toString()
+ " <a style=\"text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; background-color: #eeeeee; color: #666666;\"><sup>&nbsp;"
+ key + "&nbsp;</sup></a></html>");
}
}
}
}
} }
return this; return this;
+4
View File
@@ -1702,6 +1702,10 @@
<releaseDate>2017-04-20 20:00:00.000 CET</releaseDate> <releaseDate>2017-04-20 20:00:00.000 CET</releaseDate>
<name></name> <name></name>
<changes> <changes>
<org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType>
<description>Assign F1-F12 keys as shortcuts for frequently used component types or building blocks</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change> <org.diylc.appframework.update.Change>
<changeType>NEW_FEATURE</changeType> <changeType>NEW_FEATURE</changeType>
<description>Show and hide each individual layer</description> <description>Show and hide each individual layer</description>