ProgramingTip

JFrame 용 응답하지 않는 KeyListener

bestdevel 2020. 10. 13. 08:11
반응형

JFrame 용 응답하지 않는 KeyListener


나는를 구현하기 위해 노력하고있어 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거기에없는 것처럼 다른 메시지 가-display되지 않습니다.

나는 점점 더 많은 것이 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구성 요소가 생성되고 가장 분명한 콘텐츠 창입니다. JComboBoxUI도 방식 방식으로 구현되는 경우가 있습니다.

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

수행해야 할 작업에 대한 자세한 내용은 애플리케이션 전체 키보드 단축키 -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;
    }
}

흠 .. 생성자는 어떤 클래스입니까? 아마도 JFrame을 확장하는 클래스일까요? 물론 창 포커스는 창에 있지만 그게 문제라고 생각하지 않습니다.

코드를 확장하고 실행하려고했지만 작동했습니다. 키를 누르면 인쇄 출력이됩니다. (Eclipse를 통해 Ubuntu로 실행) :

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의 하위 클래스 인스턴스를 만들고 표시하도록 설정 한 후 기본 메서드에 추가합니다.


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

addKeyListener (이);

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


커스텀 JComponents가 부모 JFrame을 포커스 가능하게 설정하도록 할 수 있습니다.

생성자를 추가하고 JFrame을 전달하십시오. 그런 다음 paintComponent에서 setFocusable ()을 호출합니다.

이런 식으로 JFrame은 다른 구성 요소를 눌렀는지 여부에 관계없이 항상 KeyEvents를 수신합니다.

참고 URL : https://stackoverflow.com/questions/286727/unresponsive-keylistener-for-jframe

반응형