Использование связывания клавиш

Я занимаюсь базовым программированием, просто пытаюсь изучить основные принципы связывания клавиш. Все это кажется очень простым, но что-то не так с моей логикой или структурой, которая мешает моему коду исполняться так, как я хочу.

Вот мой код

public class Board {

ButtonListener buttonlistener;  
EnterAction enterAction;

public Board(){

    JFrame skeleton = new JFrame();
    skeleton.setDefaultCloseOperation(EXIT_ON_CLOSE);
    skeleton.setVisible(true);
    skeleton.setSize(400, 400);

    buttonlistener = new ButtonListener();
    enterAction = new EnterAction();

    JPanel panel = new JPanel();
    panel.setBackground(Color.BLACK);

    JButton button = new JButton("button");
    button.addActionListener(buttonlistener);
    panel.add(button);
    skeleton.add(panel);        
    panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");
    panel.getActionMap().put("doEnterAction", enterAction);

}

public class ButtonListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent arg0) {     
        System.out.println("button pressed");
    }       
}

public class EnterAction extends AbstractAction{
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("enter pressed");    
    }       
}

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

Так что все должно быть довольно просто. Как вы можете видеть, я просто пытаюсь заставить его печатать "нажата кнопка ввода" всякий раз, когда вы нажимаете клавишу ввода, но ничего не печатается (если вы не нажмете кнопку, также показанную в коде выше). Кроме того, в eclipse класс EnterAction подчеркнут желтым, я думаю, что он может быть вызван неправильно, но я не знаю, почему это не так.

Любая помощь приветствуется, спасибо.

3 ответа

Решение

Непосредственная проблема, которую я вижу, заключается в следующем утверждении

panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");

KeyStroke.getKeyStroke("s") собирается вернуться null, Требования к String Переданные этому методу очень специфичны и плохо документированы (ИМХО).

Вы могли бы использовать KeyStroke.getKeyStroke("S") вместо этого, но я предпочитаю использовать KeyStroke.getKeyStroke(KeyEvent.VK_S, 0) поскольку в заявлении нет шансов на двусмысленность.

Я бы также рекомендовал вам определить границы фокуса для входной карты...

Вместо panel.getInputMap() попробуйте использовать panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) чтобы гарантировать, что ключевое событие будет запущено, если окно сфокусировано

Взгляни на JComponent#getInputMap Больше подробностей.

Если вы еще этого не сделали, вам также следует взглянуть на Как использовать привязки клавиш

+ Изменить

panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");

к

panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "doEnterAction");

Также

skeleton.setDefaultCloseOperation(EXIT_ON_CLOSE);

параметр должен быть JFrame.EXIT_ON_CLOSE или просто поставить номер 3,

Я думаю, что Azad и MadProgrammer верны, мне нужно было сделать еще одно простое изменение в дополнение к тому, что они рекомендовали запустить программу. Я перечислил три элемента для вас в качестве комментария в коде: (скопируйте и вставьте, и все готово).

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class Board {

    ButtonListener buttonlistener;
    EnterAction enterAction;

    public Board() {

        JFrame skeleton = new JFrame();
        //Change #1 below 
        skeleton.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        skeleton.setVisible(true);
        skeleton.setSize(400, 400);

        buttonlistener = new ButtonListener();
        enterAction = new EnterAction();

        JPanel panel = new JPanel();
        panel.setBackground(Color.BLACK);

        JButton button = new JButton("button");
        button.addActionListener(buttonlistener);
        panel.add(button);
        skeleton.add(panel);
        //Change #2 below
        panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke("S"), "doEnterAction");
        panel.getActionMap().put("doEnterAction", (Action) enterAction);

    }

    public class ButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            System.out.println("button pressed");
        }
    }

    public class EnterAction extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("enter pressed");
        }
    }

    public static void main(String[] args) {
        new Board();
    }
    //Change #3 below
}

вот скриншот:

Другие вопросы по тегам