2012-12-15 4 views
1

JButton에서 ActionListener를 통해 일부 작업을 수행했습니다. Action을 사용하여 키보드 단축키 (this 다음)를 바인드하려고하면 마우스를 클릭하면 작동하지만 키보드는 반응하지 않습니다.키 바인딩이 작동하지 않습니다.

코드 패널 내에서 생성

버튼 전에의 actionListener 덧붙였다.

private FooActionListener actionListener = new FooActionListener(); 

buttonLeft = new JButton("Left"); 
up.addActionListener(actionListener); 

그런 다음, 메인 클래스 외부 FooActionListener 클래스 내에서 actionPerformed 메소드 :

public void actionPerformed(ActionEvent e) { 
    Object source = e.getSource(); 
    if (source == buttonLeft) { thing.move(Direction.LEFT); } 
} 

코드 후

final String leftText = "Left"; 
final Action left = new AbstractAction() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     thing.move(Direction.LEFT); 
    } 
}; 

buttonLeft = new JButton(left); 
buttonLeft.setText(leftText); 
KeyStroke keyLeft = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0); 
buttonLeft.getInputMap(buttonLeft.WHEN_IN_FOCUSED_WINDOW).put(keyLeft, 
    "Left"); 
buttonLeft.getActionMap().put("Left", left); 

업데이트 : 나는 새로운 코드가 실제로으로 수행하는 것을 확실히 확인 마우스를해야합니다. 클릭 한 번으로 25 픽셀 이동해야하는 오브젝트가 원래 코드에서 수행된다고 가정 해 보겠습니다. 그러나 새로운 동작으로 각 클릭에 대해 두 번 또는 세 번 움직이는 것으로 보입니다. 이는 동작의 이상한 동작을 암시합니다.

답변

2

버튼이 매핑을 흡수하고있을 가능성이 있습니다. 그러나 약간 다르게 적용 할 수 있습니다.

(올바르게) Action을 사용했기 때문에 운동 논리는 대부분 중앙 집중화되어 있습니다.

대신 간단히 매핑을 주 컨테이너에 적용합니다.

public class TestKeybindings01 { 

    public static void main(String[] args) { 
     new TestKeybindings01(); 
    } 

    public TestKeybindings01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private JLabel label; 
     private JButton left; 
     private JButton right; 

     public TestPane() { 

      label = new JLabel("Make a choice"); 
      label.setHorizontalAlignment(JLabel.CENTER); 

      LeftAction leftAction = new LeftAction(label); 
      RightAction rightAction = new RightAction(label); 

      InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); 
      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left"); 
      im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right"); 

      ActionMap am = getActionMap(); 
      am.put("left", leftAction); 
      am.put("right", rightAction); 

      left = new JButton(leftAction); 
      right = new JButton(rightAction); 

      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridx = 0; 
      gbc.gridy = 0; 
      gbc.gridwidth = 2; 
      gbc.anchor = GridBagConstraints.CENTER; 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      add(label, gbc); 

      gbc.gridy++; 
      gbc.gridwidth = 1; 
      add(left, gbc); 
      gbc.gridx++; 
      add(right, gbc); 


     } 

    } 

    public abstract class AbstractDirectionAction extends AbstractAction { 

     private JLabel label; 

     public AbstractDirectionAction(JLabel label) { 
      this.label = label; 
     } 

     public JLabel getLabel() { 
      return label; 
     } 

     public void setDirection(String text) { 
      getLabel().setText(text); 
     } 

    } 

    public class LeftAction extends AbstractDirectionAction { 

     public LeftAction(JLabel label) { 
      super(label); 
      putValue(NAME, "<<"); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      setDirection("Left"); 
     } 

    } 

    public class RightAction extends AbstractDirectionAction { 

     public RightAction(JLabel label) { 
      super(label); 
      putValue(NAME, ">>"); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      setDirection("Right"); 
     } 

    } 

} 
+0

매핑을 흡수하는 것이 무엇인지 자세히 설명해 주실 수 있습니까? 또한, 질문에 대한 업데이트를 확인하고, 그 힌트가 있는지 확인하십시오. 그리고이 EventQueue.invokeLater 사업은 무엇입니까? – theUg

+0

버튼 구현이 니모닉 지원에 대한 지원의 일부로 가능한 키 이벤트를 "흡수"하여 키 바인딩에 대한 이벤트를 발생시키지 못하게 할 수 있습니다. 이런 반복되는 이벤트에 대해 내가 생각할 수있는 유일한 이유는 키를 누르고 있다는 것입니다. 'EventQueue.invokeLater'는 Swing이 단일 스레드 API이고 UI에 대한 모든 업데이트가 Event Dispatching Thread 내에서 이루어져야 만하기 때문입니다. 'main'이 실행될 때, 당신은 EDT가 없다는 것을 보증합니다. – MadProgrammer

+0

반복 할 때, 나는이 시점에서 마우스 클릭에 대해 이야기하고 있습니다. 원본 코드와 똑같은 마우스 클릭을하지만, 동일한 클릭에 대해 thing.move 메서드를 두 번 호출하는 것처럼 보입니다. 디버깅 할 수있는 방법이 있습니까? – theUg

관련 문제