나는를 구현하기 위해 노력하고있어 KeyListener
내을 위해 JFrame
. 생성자에서 다음 코드를 사용하고 있습니다.
System.out.println("test");
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) { System.out.println( "tester"); }
public void keyReleased(KeyEvent e) { System.out.println("2test2"); }
public void keyTyped(KeyEvent e) { System.out.println("3test3"); }
});
실행하면 test
콘솔에 메시지가 나타납니다. 그러나 키를 누르면 마치 KeyListener
거기에없는 것처럼 다른 메시지 가 표시되지 않습니다.
나는 초점이에 없기 때문에이 될 수 있다고 생각 JFrame
하고 그들이 있도록 KeyListener
이벤트를 수신하지 않습니다. 그러나 나는 그것이 확실합니다.
내가 놓친 것이 있습니까?
답변
필요한 모든 구성 요소에 keyListener를 추가해야합니다. 포커스가있는 구성 요소 만 이러한 이벤트를 보냅니다. 예를 들어 JFrame에 TextBox가 하나만있는 경우 해당 TextBox에 포커스가 있습니다. 따라서이 구성 요소에도 KeyListener를 추가해야합니다.
과정은 동일합니다.
myComponent.addKeyListener(new KeyListener ...);
참고 : 일부 구성 요소는 JLabel과 같이 초점을 맞출 수 없습니다.
초점을 맞출 수 있도록 설정하려면 다음을 수행해야합니다.
myComponent.setFocusable(true);
답변
당신은 모든 구성 요소에 리스너를 등록하지 않으려면,
당신은 할 수 자신을 추가KeyEventDispatcher
받는 사람 KeyboardFocusManager
:
public class MyFrame extends JFrame {
private class MyDispatcher implements KeyEventDispatcher {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
System.out.println("tester");
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
System.out.println("2test2");
} else if (e.getID() == KeyEvent.KEY_TYPED) {
System.out.println("3test3");
}
return false;
}
}
public MyFrame() {
add(new JTextField());
System.out.println("test");
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new MyDispatcher());
}
public static void main(String[] args) {
MyFrame f = new MyFrame();
f.pack();
f.setVisible(true);
}
}
답변
InputMaps 및 ActionMaps는 구성 요소, 구성 요소 및 모든 하위 구성 요소 또는 전체 창에 대한 주요 이벤트를 캡처하도록 설계되었습니다. 이것은 JComponent.getInputMap ()의 매개 변수를 통해 제어됩니다. 문서는 키 바인딩 사용 방법을 참조하십시오 .
이 디자인의 장점은 모니터링에 중요한 키 입력을 선택하고 해당 키 입력에 따라 다른 작업을 실행할 수 있다는 것입니다.
이 코드는 이스케이프 키가 창의 아무 곳에서나 치면 JFrame에서 dispose ()를 호출합니다. JFrame은 JComponent에서 파생되지 않으므로 JFrame에서 다른 구성 요소를 사용하여 키 바인딩을 만들어야합니다. 컨텐츠 창은 이러한 구성 요소 일 수 있습니다.
InputMap inputMap;
ActionMap actionMap;
AbstractAction action;
JComponent component;
inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
actionMap = component.getActionMap();
action = new AbstractAction()
{
@Override
public void actionPerformed(ActionEvent e)
{
dispose();
}
};
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dispose");
actionMap.put("dispose", action);
답변
KeyListener
낮은 수준이며 단일 구성 요소에만 적용됩니다. 더 유용하게 만들려는 시도에도 불구하고 많은 JFrame
구성 요소 구성 요소가 생성되지만 가장 분명한 것은 콘텐츠 창입니다. JComboBox
UI도 유사한 방식으로 구현되는 경우가 많습니다.
마우스 이벤트가 키 이벤트와 약간 다른 이상한 방식으로 작동한다는 점은 주목할 가치가 있습니다.
수행해야 할 작업에 대한 자세한 내용은 Application wide keyboard shortcut-Java Swing 에 대한 내 답변을 참조하십시오 .
답변
JFrame이 이미 리스너를 추가 한 FOCUS에 대한 실제 문제라는 것을 읽을 때까지 동일한 문제가 발생했지만 JFrame 내에 초점을 맞출 수있는 구성 요소가 많기 때문에 투어 프레임이 초점에 있지 않습니다.
JFrame.setFocusable(true);
행운을 빕니다
답변
Deion (및 유사한 질문을하는 다른 사람)은 위의 Peter의 코드를 사용할 수 있지만 표준 출력으로 인쇄하는 대신 키 코드 PRESSED, RELEASED 또는 TYPED를 테스트합니다.
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
} else if (e.getID() == KeyEvent.KEY_TYPED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
}
return false;
}
답변
JFrame 의 모든 텍스트 필드의 주요 이벤트를 캡처하기 위해 주요 이벤트 포스트 프로세서를 사용할 수 있습니다. 다음은 명백한 포함을 추가 한 후 작동하는 예입니다.
public class KeyListenerF1Demo extends JFrame implements KeyEventPostProcessor {
public static final long serialVersionUID = 1L;
public KeyListenerF1Demo() {
setTitle(getClass().getName());
// Define two labels and two text fields all in a row.
setLayout(new FlowLayout());
JLabel label1 = new JLabel("Text1");
label1.setName("Label1");
add(label1);
JTextField text1 = new JTextField(10);
text1.setName("Text1");
add(text1);
JLabel label2 = new JLabel("Text2");
label2.setName("Label2");
add(label2);
JTextField text2 = new JTextField(10);
text2.setName("Text2");
add(text2);
// Register a key event post processor.
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addKeyEventPostProcessor(this);
}
public static void main(String[] args) {
JFrame f = new KeyListenerF1Demo();
f.setName("MyFrame");
f.pack();
f.setVisible(true);
}
@Override
public boolean postProcessKeyEvent(KeyEvent ke) {
// Check for function key F1 pressed.
if (ke.getID() == KeyEvent.KEY_PRESSED
&& ke.getKeyCode() == KeyEvent.VK_F1) {
// Get top level ancestor of focused element.
Component c = ke.getComponent();
while (null != c.getParent())
c = c.getParent();
// Output some help.
System.out.println("Help for " + c.getName() + "."
+ ke.getComponent().getName());
// Tell keyboard focus manager that event has been fully handled.
return true;
}
// Let keyboard focus manager handle the event further.
return false;
}
}
