質問: JTree にキーバインドを追加するとき、各アクションを独自のクラスにする必要があるのはなぜですか? 各アクションで単一の Action クラスを使用できないのはなぜですか? 私の質問/問題を理解するために、以下の問題の短い自己完結型の例を説明することから始めましょう.
addKeyBindings(JTree tree) has the following 2 lines commented out.
//Action addsiblingnodeaction = new RightClickNodeAction("Add SiblingNode");
//Action addchildnodeaction = new RightClickNodeAction("Add ChildNode");
/*These use 1 action class, to do 2 different actions. (I want this because I
find the code to be less verbose)
(They're commented out because they don't work for keybindings)
(The reason I ask question, is because they DO work for JPopupMenu)*/
本当の質問は、なぜ上記の//コメントアウトされたコード//がキーバインディングに対して機能しないのですか? (私の例では、上記のコメントアウトされたコードが JPopupMenu で機能することを示すために JPopupMenu を含めました。私の考えでは、キーバインドでも機能するはずです) (キーバインドを機能させることができた唯一の方法は、AbstractAction クラスを作成することでした)以下のコード例で確認できる各アクション)
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.KeyStroke;
public class StackExchangeQuestion2 {
public static void main(String[] args){
StackExchangeQuestion2 workaround = new StackExchangeQuestion2();
//workaround = compiler didn't like me throwing constructor code in main
}//end main
StackExchangeQuestion2(){
JTree tree = new JTree();
initRightClickMenu(tree);//purpose of existance is to show Action Code is accurate
addKeyBindings(tree);
JFrame window = new JFrame();
window.getRootPane().setContentPane(tree);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setTitle("Stack Exchange Question");
window.setSize(400,500);//variable parameters would be best
window.setVisible(true);
}//constructor
private void initRightClickMenu(JTree tree){
JPopupMenu rightclickmenu = new JPopupMenu();
Action addsiblingnodeaction = new RightClickNodeAction("Add SiblingNode");
Action addchildnodeaction = new RightClickNodeAction("Add ChildNode");
rightclickmenu.add(addsiblingnodeaction);
rightclickmenu.add(addchildnodeaction);
tree.setComponentPopupMenu(rightclickmenu);
}
private void addSiblingNode(){
System.out.println("sibling node added");}
private void addChildNode(){
System.out.println("child node added");}
private void addKeyBindings(JTree tree){
//Action addsiblingnodeaction = new RightClickNodeAction("Add SiblingNode");
Action addsiblingnodeaction = new AddSiblingNodeAction("Add SiblingNode");
tree.getActionMap().put("Add SiblingNode", addsiblingnodeaction);
tree.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "Add SiblingNode");
//Action addchildnodeaction = new RightClickNodeAction("Add ChildNode");
Action addchildnodeaction = new AddChildNodeAction("Add ChildNode");
tree.getActionMap().put("Add ChildNode", addchildnodeaction);
tree.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "Add ChildNode");
}//end addKeyBindins
private class AddSiblingNodeAction extends AbstractAction{
AddSiblingNodeAction(String name){super(name);}
public void actionPerformed(ActionEvent ae) { addSiblingNode(); }}
private class AddChildNodeAction extends AbstractAction{
AddChildNodeAction(String name){super(name);}
public void actionPerformed(ActionEvent ae) { addChildNode(); }}
private class RightClickNodeAction extends AbstractAction{
RightClickNodeAction(String name){super(name);}
public void actionPerformed(ActionEvent ae) {
if(ae.getActionCommand().equals("Add SiblingNode"))addSiblingNode();
if(ae.getActionCommand().equals("Add ChildNode"))addChildNode(); }}
}//end class