Я создал пользовательский кнопочный класс, который расширяет JComponent
и вы хотите добавить KeyListener
на mouseEntered
мероприятия (или позже уйдут из mouseExited
). Поэтому моя цель - когда мышь входит в этот JComponent
- тогда, если я нажму Enter, то будет выполнен код, относящийся только к этой кнопке. Как я могу это сделать?Как добавить KeyListener в JComponent при вводе мыши?
ответ
Используйте Key Bindings вместо KeyListeners, так как последний является способом до низкого уровня для Swing
. Просто наведите указатель мыши на JButton
, а затем нажмите ENTER, затем с помощью мыши выйдите за пределы поля JButton
и попробуйте нажать ENTER. Взгляните на этот пример и убедитесь, что это то, что вы хотели:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonBinding {
private JPanel contentPane;
private JTextField tField;
private JButton button;
private KeyStroke keyStroke = KeyStroke.getKeyStroke("ENTER");
private Action action = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Action Performed");
contentPane.setBackground(Color.BLUE);
}
};
private MouseAdapter mouseActions = new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent me) {
System.out.println("Mouse Entered");
JButton button = (JButton) me.getSource();
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "enter");
button.getActionMap().put("enter", action);
}
@Override
public void mouseExited(MouseEvent me) {
System.out.println("Mouse Exited");
JButton button = (JButton) me.getSource();
button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "none");
contentPane.setBackground(Color.RED);
}
};
private void displayGUI() {
JFrame frame = new JFrame("Button Binding Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
contentPane.setOpaque(true);
tField = new JTextField(10);
button = new JButton("Click Me");
button.addMouseListener(mouseActions);
contentPane.add(tField);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new ButtonBinding().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
+1 для приятного примера с использованием keyBindings. Nitpicking: a) действия имеют свойство enabled, поэтому нет необходимости добавлять/удалять привязку. B) mouseEvent несет свой источник, поэтому нет необходимости обращаться к внешнему полю. C) JPanel непрозрачен по умолчанию. – kleopatra
@ kleopatra: Thankyou и KEEP SMILING :-) Хотя я читал в Java Tutorials, что 'JPanel' непрозрачен по умолчанию, хотя и не для всех' LookAndFeels', поэтому я всегда использую, чтобы вызвать это свойство на 'JPanel', установив на него фон :-), как видно в этом [Java Tutorials] (http://docs.oracle.com/javase/tutorial/uiswing/painting/problems.html). Хотя OP сказал, что он/она хочет удалить его в «Mouse Exit», поэтому я сделал это: ( –
). Хороший вопрос о непрозрачности, как правило, забывают, что LAF может решить иначе :-) Что касается требования OP: как правило, это не полностью указано, здесь я думаю, что важная часть заключается в том, что запуск действия должен быть возможен только тогда, когда мышь над компонентом, но это угадывает. – kleopatra
Вы что-то пробовали? – Tala
@ErnestasGruodis: не используйте KeyListeners, используйте [Key Bindings] (http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html). KeyListeners - путь к низкому уровню с точки зрения Swing :-) –
Почему бы вам просто не использовать логическое значение, которое будет контролировать выполнение определенных событий ключа на основе положения мыши? –