문제

나는 구현하려고 노력하고있다 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에 텍스트 상자가 하나만 있으면 해당 텍스트 상자에 중점을 둡니다. 따라서이 구성 요소에 키일리스트를 추가해야합니다.

프로세스는 동일합니다.

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);
    }
}

입력 맵 및 액션 맵은 구성 요소, IT 및 모든 하위 구성 요소 또는 전체 창의 주요 이벤트를 캡처하도록 설계되었습니다. 이것은 jcomponent.getInputMap ()의 매개 변수를 통해 제어됩니다. 보다 키 바인딩을 사용하는 방법 문서화 용.

이 디자인의 아름다움은 주요 스트로크를 기반으로 모니터링하고 다른 동작을 발사하는 데 중요한 키 스트로크를 선택하고 선택할 수 있다는 것입니다.

이 코드는 Escape 키가 창의 어느 곳에서나 누르면 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는 종종 비슷한 방식으로 구현됩니다.

마우스 이벤트가 주요 이벤트와 약간 다른 방식으로 작동한다는 점에 주목할 가치가 있습니다.

해야 할 일에 대한 자세한 내용은 내 답변을 참조하십시오. 애플리케이션 넓은 키보드 단축키 -Java Swing.

실제 문제는 JFrame이 이미 청취자를 추가 한 초점에 관한 것임을 읽을 때까지 같은 문제를 겪었지만 JFrame 내부에 많은 구성 요소가있어 초점을 맞추기 때문에 투어 프레임은 결코 초점이 맞지 않습니다.

JFrame.setFocusable(true);

행운을 빕니다

Deion (및 비슷한 질문을하는 다른 사람)은 위의 Peter의 코드를 사용할 수 있지만 표준 출력으로 인쇄하는 대신 키 코드를 누르거나 릴리스 또는 타이핑하는 것을 테스트합니다.

@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;
    }
}

흠 .. 당신의 생성자는 어떤 클래스입니까? 아마도 JFrame을 확장하는 클래스일까요? 창은 창문에 있어야하지만 물론 나는 그것이 문제라고 생각하지 않습니다.

코드를 확장하고 실행하려고 시도했으며 작동했습니다. 주요 프레스는 인쇄 출력으로 이어졌습니다. (이클립스를 통해 우분투와 함께 실행) :

public class MyFrame extends JFrame {
    public MyFrame() {
        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");
            }
        });
    }

    public static void main(String[] args) {
        MyFrame f = new MyFrame();
        f.pack();
        f.setVisible(true);
    }
}

이것은 도움이 될 것입니다

    yourJFrame.setFocusable(true);
    yourJFrame.addKeyListener(new java.awt.event.KeyAdapter() {


        @Override
        public void keyTyped(KeyEvent e) {
            System.out.println("you typed a key");
        }

        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println("you pressed a key");
        }

        @Override
        public void keyReleased(KeyEvent e) {
            System.out.println("you released a key");
        }
    });

나는 같은 문제를 겪고있다. 나는 Bruno의 조언을 따랐으며 jframe (즉, 왼쪽 상단)의 "첫 번째"버튼에 Keylistener를 추가하는 것이 트릭을 수행했다는 것을 알았습니다. 그러나 나는 그것이 당신에게 일종의 불안한 해결책이라는 데 동의합니다. 그래서 나는 주위를 가로 질러 그것을 고칠 수있는 깔끔한 방법을 발견했습니다. 줄을 추가하십시오

myChildOfJFrame.requestFocusInWindow();

주요 방법으로, JFrame의 서브 클래스 인스턴스를 만든 후에는 볼 수 있습니다.

LOL .... 당신이해야 할 일은

AddKeylistener (this);

코드에 올바르게 배치됩니다.

사용자 정의 jcomponents가 부모 JFrame을 집중시킬 수 있습니다.

생성자를 추가하고 JFrame을 통과하기 만하면됩니다. 그런 다음 PaintComponent에서 setFocusable ()를 호출하십시오.

이런 식으로 JFrame은 다른 구성 요소를 누르는지 여부에 관계없이 항상 키 이벤트를받습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top