[英]java swing key bindings - missing action for released key
注冊了“SPACE”和“已發布的SPACE”的鍵綁定,當空間是唯一按下/釋放的鍵時,按照廣告的方式工作,我注意到按下空格,然后按ctrl(或任何其他修改鍵),然后釋放空間,最后釋放ctrl將導致執行與“SPACE”關聯的操作,但不會執行與“已釋放的SPACE”關聯的操作。
一旦不再按空格(或同時按下修改鍵),導致動作執行的首選方法是什么? 我只在Windows 7,64位上試過這個。
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.AbstractAction;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
import java.awt.Cursor;
class Bind extends JPanel {
{
getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressed");
getInputMap().put(KeyStroke.getKeyStroke("released SPACE"), "released");
getActionMap().put("pressed", new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) {
System.out.println("pressed");
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
}
});
getActionMap().put("released", new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) {
System.out.println("released");
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
JFrame f = new JFrame("Key Bindings");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Bind());
f.setSize(640, 480);
f.setVisible(true);
}
});
}
}
更新 :這是在釋放空間之前意外點擊ctrl,alt或shift時避免粘滯空間的方法:
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.AbstractAction;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
import java.awt.Cursor;
class Bind extends JPanel {
{
getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressed");
getInputMap().put(KeyStroke.getKeyStroke("released SPACE"), "released");
getInputMap().put(KeyStroke.getKeyStroke("ctrl released SPACE"), "released");
getInputMap().put(KeyStroke.getKeyStroke("shift released SPACE"), "released");
getInputMap().put(KeyStroke.getKeyStroke("shift ctrl released SPACE"), "released");
getInputMap().put(KeyStroke.getKeyStroke("alt released SPACE"), "released");
getInputMap().put(KeyStroke.getKeyStroke("alt ctrl released SPACE"), "released");
getInputMap().put(KeyStroke.getKeyStroke("alt shift released SPACE"), "released");
getInputMap().put(KeyStroke.getKeyStroke("alt shift ctrl released SPACE"), "released");
getActionMap().put("pressed", new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) {
System.out.println("pressed");
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
}
});
getActionMap().put("released", new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) {
System.out.println("released");
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override public void run() {
JFrame f = new JFrame("Key Bindings");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Bind());
f.setSize(640, 480);
f.setVisible(true);
}
});
}
}
有意義的是,當Control鍵仍然按下時,不會觸發released SPACE
事件。 我希望control released SPACE
事件被解雇。
將以下內容添加到您的代碼中:
getInputMap().put(KeyStroke.getKeyStroke("control released SPACE"), "released");
出於同樣的原因,如果您先按住Control鍵, SPACE
事件將不會觸發。 因此,您還需要為control SPACE
添加綁定。
您需要對所有修改鍵執行此操作,這可能是也可能不是跟蹤關鍵事件的簡單解決方案。
您的操作系統可能不會觸發keyReleased
事件,而只會keyTyped
keyPressed
和keyTyped
事件或其他組合,因此請先檢查該事件。 您可能只需要檢查keyTyped
事件而不是keyReleased
,您將完成它。
簡短回答:
使用位掩碼或數組來跟蹤當前處於“已按下”狀態的鍵,然后使用那些值來觸發事件。 也就是說,不要直接使用Swing事件來觸發應用程序中的響應 - 您需要一個基本上存儲鍵盤狀態的額外層,並從該狀態開始執行相關操作。
還有一些方法可用( 參見本教程結尾 - “isAltDown”,“isCtrlDown”等 )來檢查當您收到按下“Space”鍵之類的事件時是否按下了修改鍵。
答案很長:
你按下並釋放按鍵時會觸發事件是正確的。 它必須以這種方式工作,以便您可以支持應該單獨處理這些事件的應用程序,而不是一起處理。 一個例子(雖然這不是唯一一個)是PC上的視頻游戲,你可能會同時按下多個字母/修改鍵(例如, A
向左移動, W
向前移動)游戲必須對待這兩個事件作為不同的輸入,而不是復合輸入,導致你的前進 - 左移動。
所以,你基本上想做的事情,如果你需要處理復合輸入,就有一個簡單的應用程序需要響應的動作數組,以及它們相關的鍵綁定(無論是單鍵還是多鍵都不重要) )。 當按下某個鍵時,你基本上會打開該鍵的標志,表示它當前處於“按下”狀態,並在釋放時清除該標志。
然后,要觸發您的事件,您只需檢查所有按下的鍵(通過檢查哪些鍵“標志”處於活動狀態),如果按下特定事件的鍵組合,則觸發事件。
如果你有少於32個觸發事件的鍵,那么你實際上可以使用位掩碼和32位int
值,而不是數組。 事實上,如果可以的話,這樣做會簡單得多。 如果您需要多達64個密鑰,請使用long
執行相同的操作。 如果您觸發事件的鍵很少(例如8或更少),則可以使用8位short
類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.