Как остановить пробел от запуска эффекта нажатия на кнопку?

Я создал jframe и добавил кнопку, которая после нажатия на нее просит вас нажать любую кнопку, которая также отображается на кнопке.
(его показы должны выглядеть следующим образом -> "Нажмите меня" -> "Нажмите любую кнопку" -> "Пробел")
Моя проблема № 1 заключается в том, что я не хочу переходить от "Нажмите меня" к "Нажмите любую кнопку", нажав пробел.
И моя проблема № 2 заключается в том, что, когда я нахожусь в "Нажмите любую кнопку" и нажимаю пробел, при отпускании он возвращается к "Нажмите любую кнопку" вместо того, чтобы оставаться в "Пробел".
Вот мой код

    public class Test {

/**
 * @param args the command line arguments
 */

static class starton implements ActionListener {
    private JButton button;
    private JFrame frame;

    public starton(JButton button, JFrame frame) {
        this.button = button;
        this.frame = frame;
    }

    public void actionPerformed(ActionEvent e) {
        button.setText("Press A Button");
        button.setSize(button.getPreferredSize());
        button.addKeyListener(
        new KeyListener() {
            @Override 
            public void keyPressed(KeyEvent e){
                String text = null;

                    char a = e.getKeyChar();
                    text = ""+a+"";
                    if (a == ' '){
                        text = "Space Bar";
                    }

                button.setText(""+text+"");
                button.setSize(button.getPreferredSize());
                button.removeKeyListener(this);
            }

            @Override
            public void keyTyped(KeyEvent e) {
            }

            @Override
            public void keyReleased(KeyEvent ke) {
            }
        });
    }
}

public static void main(String[] args) throws IOException {

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    double width = screenSize.getWidth();
    double height = screenSize.getHeight();
    int frame1w = 600;
    int frame1h = 400;

    JFrame frame1 = new JFrame("Foo");
    frame1.setSize(frame1w, frame1h);
    frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel contentPane = new JPanel();
    contentPane.setBackground(Color.WHITE);
    contentPane.setLayout(null);
    frame1.setContentPane(contentPane);

    JButton button1 = new JButton("Click Me");
        button1.setSize(button1.getPreferredSize());
        button1.addActionListener(new starton(button1, frame1));
            // add more code here
        contentPane.add(button1);
        frame1.setVisible(true);
}

}

2 ответа

JButton устанавливает серию привязок клавиш для управления вводом пользователя

Вы можете проверить, что они используют что-то вроде...

JButton btn = new JButton("Test");
InputMap im = btn.getInputMap();
for (KeyStroke ik : im.allKeys()) {
    System.out.println(ik + " = " + im.get(ik));
}

В моей системе это печатает

pressed SPACE = pressed
released SPACE = released

Это говорит мне, что пробел связан с клавишами действий pressed а также released

Для того, чтобы отключить эти ключи, вам нужно предоставить собственную привязку...

Action blankAction = new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
    }
};

ActionMap am = btn.getActionMap();
am.put("pressed", blankAction);
am.put("released", blankAction);

Это просто заменяет pressed а также released привязки с пустым Action который ничего не делает.

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

Что касается вашей второй проблемы, то button все еще использует то же самое ActionListener вы изначально зарегистрированы, поэтому всякий раз, когда вы нажимаете пробел, это вызывает ActionListener снова и добавление нового KeyListener который собирается усугубить ваши проблемы

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

нет, я имею в виду, если я отключу "нажатие" для пробела, смогу ли я нажать его, когда я нахожусь в "Нажмите любую кнопку"?

Самое простое решение - использовать две разные кнопки, одну с ActionListener который настроил другую кнопку, которая имела KeyListener прикреплен к нему.

Если по какой-то причине вы "действительно" не хотите этого делать, вам нужно удалить ActionListener с кнопки, когда она впервые сработала

static class starton implements ActionListener {

    //...

    public void actionPerformed(ActionEvent e) {
        button.setText("Press A Button");
        button.setSize(button.getPreferredSize());
        button.addKeyListener(...);
        button.removeActionListener(this);
    }
}

Проблема возникает из-за вашего вложенного контроля над KeyListener в слушателе действия. Поскольку клавиша пробела является кнопкой клавиатуры по умолчанию для эквивалента нажатия кнопки, каждый раз, когда вы нажимаете клавишу пробела actionPerformed метод кнопок ActionListener уволен. Вы можете увидеть это, если получите actionCommand из ActionEvent уволили и распечатали его. Вы также можете использовать это, чтобы контролировать, какой код выполняется. Как это:

public void actionPerformed(ActionEvent e) 
{
    System.out.println("Button Action: " + e.getActionCommand());
    if(e.getActionCommand().equals("Click Me"))
    {
        //Your existing code but remove this line
        //button.removeKeyListener(this);
    }
}
Другие вопросы по тегам