Как остановить пробел от запуска эффекта нажатия на кнопку?
Я создал 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);
}
}