キーボードショートカットを作る(Java)
何も考えずにKeyListenerを使ってやってみる
import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.MutableTreeNode; @SuppressWarnings( "serial" ) public class TreeSample extends JFrame implements KeyListener { public TreeSample(MutableTreeNode treeNode) { JTree tree = new JTree(treeNode); add(tree); tree.addKeyListener(this); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("新世界"); setBounds(100, 100, 250, 200); setVisible(true); } public static void main(String[] args) { DefaultMutableTreeNode root = new DefaultMutableTreeNode("世界の国々"); for ( String child : new String[]{ "日本", "アメリカ", "ドイツ", "おそロシア" } ) root.add(new DefaultMutableTreeNode(child)); for ( String leaf : new String[]{ "アメリカ村", "ドイツ村" } ) root.getNextNode().add(new DefaultMutableTreeNode(leaf)); new TreeSample(root); } /** * jまたはkが押されたらtreeの選択を移動する * @param e */ @Override public void keyTyped(KeyEvent e) { if( tree.isSelectionEmpty() ) return; char getKey = e.getKeyChar(); int index = tree.getSelectionRows()[0]; switch ( getKey ) { case 'j': { if ( index != tree.getRowCount() - 1 ) tree.setSelectionRow(++index); break; } case 'k': { if ( index != 0 ) tree.setSelectionRow(--index); break; } } } @Override public void keyPressed(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } }
結構めんどくさい!
上のコードと等価なやつをActionMapとInputMapを使って書いてみる
import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JFrame; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.MutableTreeNode; @SuppressWarnings( "serial" ) public class TreeSample extends JFrame { public TreeSample(MutableTreeNode treeNode) { JTree tree = new JTree(treeNode); add(tree); Action treeDown = new AbstractAction() { public void actionPerformed(ActionEvent e) { int index = tree.getSelectionRows()[0]; if ( index != tree.getRowCount() - 1 ) tree.setSelectionRow(++index); } }; Action treeUp = new AbstractAction() { public void actionPerformed(ActionEvent e) { int index = tree.getSelectionRows()[0]; if ( index != 0 ) tree.setSelectionRow(--index); } }; ActionMap amc = tree.getActionMap(); amc.put("treeUp",treeUp); amc.put("treeDown", treeDown); InputMap imc = tree.getInputMap(); imc.put(KeyStroke.getKeyStroke('j'), "treeDown"); imc.put(KeyStroke.getKeyStroke('k'), "treeUp"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("新世界"); setBounds(100, 100, 250, 200); setVisible(true); } public static void main(String[] args) { DefaultMutableTreeNode root = new DefaultMutableTreeNode("世界の国々"); for ( String child : new String[]{ "日本", "アメリカ", "ドイツ", "おそロシア" } ) root.add(new DefaultMutableTreeNode(child)); for ( String leaf : new String[]{ "アメリカ村", "ドイツ村" } ) root.getNextNode().add(new DefaultMutableTreeNode(leaf)); new TreeSample(root); } }
ちょっとだけ短くなった
でも、キーボードの↑ボタンとかを押しても移動できるみたいなので、
今度はその挙動をパクってみます
KeyStrokeを使ってキーボードの↑ボタンと↓ボタンの挙動をそっくりそのまま拝借してみる
import java.awt.event.KeyEvent; import javax.swing.InputMap; import javax.swing.JFrame; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.MutableTreeNode; @SuppressWarnings( "serial" ) public class TreeSample extends JFrame { public TreeSample(MutableTreeNode treeNode) { JTree tree = new JTree(treeNode); add(tree); //↓キーと↑キーの挙動を取得する KeyStroke downKey = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0); KeyStroke upKey = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0); InputMap imc = tree.getInputMap(); imc.put(KeyStroke.getKeyStroke('j'), imc.get(downKey)); imc.put(KeyStroke.getKeyStroke('k'), imc.get(upKey)); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("新世界"); setBounds(100, 100, 250, 200); setVisible(true); } public static void main(String[] args) { DefaultMutableTreeNode root = new DefaultMutableTreeNode("世界の国々"); for ( String child : new String[]{ "日本", "アメリカ", "ドイツ", "おそロシア" } ) root.add(new DefaultMutableTreeNode(child)); for ( String leaf : new String[]{ "アメリカ村", "ドイツ村" } ) root.getNextNode().add(new DefaultMutableTreeNode(leaf)); new TreeSample(root); } }
結構短くなった!
もともとどんなキーが登録されているかは
System.out.println(java.util.Arrays.toString(tree.getRegisteredKeyStrokes()));
をすれば見えるはず
最後に
ActionMapとInputMapとKeyStrokeは結構便利なんじゃないかと思った