我試圖得到一個簡單的JFrame一個按鈕開火時,這些事件的發生的事件:回車鍵是消防用空格鍵一個JButton,或回車鍵,或者鼠標點擊
- 按下並且JButton具有焦點
- 空格鍵被按下且JButton具有焦點
- 單擊JButton。
看來,輸入和空格鍵一起「免費」,以及在JButton上使用addActionListener的默認鼠標點擊;麻煩的是,我讀過關鍵綁定依賴於使用的外觀和感覺。
我試圖通過向JButton的動作地圖添加Enter和空格鍵來獲得LaF的通用行爲,甚至添加了一個隨機密鑰(「m」)來確保ActionMap正在執行這項工作(它是),但現在鼠標點擊丟失了。我似乎能夠獲得所有按鍵和鼠標點擊的唯一方法是同時使用動作貼圖和addActionListener。
有沒有辦法讓這些鍵和鼠標綁定在所有LaF上一致地工作,而不嘗試檢測可能會出現的每個可能的LaF?我可以註冊一個將觸發鍵盤和鼠標事件的單個動作偵聽器嗎?
我最喜歡的解決方案是將鼠標點擊添加到JButton動作地圖,並檢測在動作內部發生了哪個按鍵或鼠標點擊。
我仍然在這裏學習繩索,所以這可能不是最好或最有效的方式來做事情;我相信它是過度設計的。這是一種訓練練習,我正在試驗一切我能得到的東西。歡迎任何和所有的編碼風格評論!
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
public class Example extends JFrame {
// ============================
private class BtnListener extends AbstractAction {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent ae) {
System.out.println("\nclick button listener triggered");
System.out.println(ae.getSource().getClass().toString());
}
} // class BtnListener
private static final int NO_MODIFIER = 0;
private static final boolean ON_KEY_PRESS = false;
private static final KeyStroke ENTER_PRESSED = KeyStroke.getKeyStroke(
KeyEvent.VK_ENTER, NO_MODIFIER, ON_KEY_PRESS);
private static final KeyStroke M_PRESSED = KeyStroke.getKeyStroke(
KeyEvent.VK_M, NO_MODIFIER, ON_KEY_PRESS);
private static final KeyStroke SPACEBAR_PRESSED = KeyStroke.getKeyStroke(
KeyEvent.VK_SPACE, NO_MODIFIER, ON_KEY_PRESS);
private JButton btnButton;
private final AbstractAction btnListener = new BtnListener();
private JPanel buttonPanel;
private JFrame frmMain;
public static void main(String[] args) {
Example ex = new Example();
ex.displayFrame();
}
Action btnActionListener = new AbstractAction() {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
System.out.println("\nkey button action triggerred");
System.out.println(e.getSource().getClass().toString());
if (e.getSource() instanceof JButton) {
System.out.println("button");
} else {
System.out.println("Something else");
}
}
};
public Example() {
initialize();
}
public void displayFrame() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frmMain.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void initialize() {
frmMain = new JFrame();
btnButton = new JButton("Abutton");
// Comment this out, you lose the mouse click
btnButton.addActionListener(btnListener);
// Comment out ActionMaps, but keep addActionListner (above), and
// only lose M_PRESSED
InputMap buttonFocusedMap = btnButton
.getInputMap(JComponent.WHEN_FOCUSED);
buttonFocusedMap.put(ENTER_PRESSED, "blah");
btnButton.getActionMap().put("blah", btnActionListener);
buttonFocusedMap.put(SPACEBAR_PRESSED, "blort");
btnButton.getActionMap().put("blort", btnActionListener);
buttonFocusedMap.put(M_PRESSED, "gaaak");
btnButton.getActionMap().put("gaaak", btnActionListener);
// Is there a way to add a mouse click to the ActionMap?
buttonPanel = new JPanel();
buttonPanel.add(btnButton);
frmMain.getContentPane().add(buttonPanel);
frmMain.setBounds(100, 100, 500, 432);
frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
非常好!感謝您的深入解釋。 –