Frage

Ich versuche, einen KeyListener für meinen JFrame zu implementieren. Auf dem Konstruktor, verwende ich diesen Code ein:

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

Wenn ich es laufen, kommt die test Nachricht in meiner Konsole nach oben. Allerdings, wenn ich eine Taste drücken, ich habe nicht eine der anderen Nachrichten erhalten, als ob die KeyListener nicht einmal da war.

Ich dachte, dass es sein könnte, da der Fokus nicht auf dem JFrame
ist und so hat sie KeyListener keine Events erhalten. Aber, ich bin ziemlich sicher, dass es ist.

Gibt es etwas, das ich vermisst?

War es hilfreich?

Lösung

Sie müssen Ihre keyListener zu jeder Komponente hinzufügen, die Sie benötigen. Nur die Komponente mit dem Fokus wird diese Ereignisse senden. Zum Beispiel, wenn Sie nur eine TextBox in Ihrer JFrame haben, hat die TextBox den Fokus. So müssen Sie auch eine KeyListener zu dieser Komponente hinzuzufügen.

Das Verfahren ist das gleiche:

myComponent.addKeyListener(new KeyListener ...);

Hinweis: Einige Komponenten sind nicht fokussierbar wie JLabel

.

Für sie einstellen Fokussierbare Sie müssen:

myComponent.setFocusable(true);

Andere Tipps

Wenn Sie keinen Hörer auf jede Komponente registrieren möchten,
Sie können fügen Sie Ihre eigenen KeyEventDispatcher zum 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 und ActionMaps wurden entwickelt, um die wichtigsten Ereignisse für die Komponente zu erfassen, sie und alle seine Unterkomponenten oder das gesamte Fenster. Dies wird gesteuert durch die Parameter in JComponent.getInputMap (). Siehe Wie Key Bindings für die Dokumentation verwenden.

Die Schönheit dieser Konstruktion ist, dass man wählen kann und entscheiden, welche Tastenanschläge wichtig sind, zu überwachen und haben unterschiedliche Aktionen für diese Tastenanschläge fired basiert.

Dieser Code wird () aufrufen, auf einem JFrame entsorgen, wenn die Escape-Taste irgendwo im Fenster getroffen wird. JFrame nicht von JComponent ableiten, so dass Sie eine weitere Komponente in der JFrame verwenden müssen, um die Bindung der Schlüssel zu erstellen. Der Inhaltsbereich könnte eine solche Komponente sein.

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 ist niedriges Niveau und gilt nur für eine einzelne Komponente. Trotz aller Versuche, es verwendbaren JFrame zu machen erstellt eine Reihe von Komponenten Komponenten, die offensichtlichste ist der Inhaltsbereich. JComboBox UI wird oft auch in ähnlicher Weise umgesetzt werden.

Es ist erwähnenswert, die Mausereignisse auf eine seltsame Weise arbeiten etwas anders wichtige Ereignisse.

Weitere Informationen darüber, was Sie tun sollen, siehe meine Antwort auf Anwendung breiter Tastatur Abkürzung -. Java Swing

Ich habe das gleiche Problem, bis ich, dass das eigentliche Problem lesen Sie über die Ihre JFrame wird FOCUS hat Hörer bereits hinzugefügt, aber Tour Rahmen ist nie Fokus, weil Sie eine Menge von Komponenten im Inneren des JFrame bekam, die auch fokussierbar sind so versuchen:

JFrame.setFocusable(true);

Good Luck

Deion (und alle anderen, eine ähnliche Frage zu stellen), könnten Sie Peters Code oben, aber statt Druck auf die Standardausgabe, Sie testen, für den Schlüsselcode GEPRESSTE, FREIGEGEBEN, oder getippte verwenden.

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

, um Schlüsselereignisse aller Textfelder zu erfassen in einem JFrame , man kann ein Schlüsselereignis Postprozessor verwenden. Hier ist ein funktionierendes Beispiel, nachdem Sie hinzufügen, die offensichtlich enthalten.

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

Hmm .. was Klasse ist Ihr Konstruktor? Wahrscheinlich erstreckt einige Klasse JFrame? Das Fenster Fokus am Fenster sein soll, natürlich, aber ich glaube nicht, das ist das Problem.

I erweitert Ihren Code, versucht, es zu laufen und es funktionierte - die Tastendrücke zur Folge als Druckausgabe. (Läuft mit Ubuntu durch Eclipse):

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

Dies sollte helfen,

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

Ich habe das gleiche Problem gehabt. Ich folgte Bruno Rat an Sie und festgestellt, dass ein KeyListener Zugabe nur auf die „ersten“ in der JFrame (dh links oben) den Trick. Aber ich stimme mit Ihnen es irgendwie beunruhigende Lösung. So fummelte ich mich um und entdeckte eine sauberere Weg, es zu beheben. Fügen Sie einfach die Zeile

myChildOfJFrame.requestFocusInWindow();

auf Ihre Haupt-Methode, nachdem Sie Ihre Instanz Ihrer Unterklasse von JFrame erstellt haben und setzen Sie ihn sichtbar.

lol .... alles, was Sie tun müssen, ist sicher, dass

addKeyListener (this);

korrekt im Code platziert.

Sie können auch eigene JComponents haben setzen ihre Eltern JFrame fokussierbar.

Sie einfach einen Konstruktor hinzufügen und in der JFrame übergeben. Dann einen Anruf zu setFocusable machen () in paintcomponent.

Auf diese Weise die JFrame wird immer KeyEvents unabhängig davon, ob andere Komponenten erhalten gedrückt werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top