我對Swing的使用並不陌生,但我對它做了大量的工作,並且正在設計一個新的應用程序。這是一個繪圖應用程序。它將允許用戶在空白的「查看器」窗口中的特定位置點擊,使用鍵盤輸入字母和符號,從而編輯查看器窗口某處的文本。使用KeyBindings將所有字符映射到動作
因爲我沒有使用JComponent
來顯示這個文本,所以我需要一個可靠的方式讓我的應用程序接受輸入。我選擇了使用KeyBindings。但我的特殊查看器組件以空輸入映射和空動作映射開始。
我的問題。什麼是最簡單的方式來映射所有的字母和符號,我可以使用我的鍵盤鍵入AbstractAction
的使用ActionMap和InputMap?該動作圖需要使用WHEN_IN_FOCUSED_WINDOW
來捕捉接口的所有輸入。
編輯: 我曾經使用的KeyListener爲了做到這一點,但我沒有在獲得模塊化的 方式,我想
我看不上的代碼。徹底拋棄它。我相信這是在SSCCE:
import java.awt.event.KeyEvent;
import static java.awt.event.KeyEvent.*;
public class MyKeysHandler extends KeyListener {
//blah blah blah
//blah blah blah
public void keyPressed(KeyEvent ke)
{
// please excuse if the boolean logic of my use of masks is off
// their proper use doesn't come to me easily
// I hope you can get the jist
if((ke.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) != 0) {
switch(ke.getKeyCode()) {
// handle capital letters
case VK_DELETE : editor.handleThisSpecialKey(ke.getKeyCode);
case VK_BACK_SLASH : // handle back slash
case VK_7 : // handle the ampersand
case VK_8 : // handle the asterisk character
default : // if just a normal letter...
editor.handleThisNormalKeyPlease(KeyEvent.getKeyText(ke.getKeyCode()).toUpperCase());
}
}
else {
switch(ke.getKeyCode()) {
case VK_DELETE : // handle the shift-delete command
case VK_BACK_SLASH : // handle the question mark
case VK_7 : // handle the 7
case VK_8 : // handle the 8
defualt :
if(ke.getKeyCode() == VK_C && ke.getModifiersEX() & KeyEvent.CTRL_DOWN_MASK) != 0) {
editor.handleTheCopyCommandPlease();
}
else
editor.handleThisKeyPlease(KeyEvent.getKeyText(ke.getKeyCode).toLowerCase());
}
}
}
}
但這真的很麻煩。每當你添加一個密鑰時,你必須確保它不會與相同方法中的一些其他密鑰代碼發生衝突,並且對於你必須爲任何應用程序製作的每一個keylistener,你都必須包含這個細緻的「VK」開關代碼。
我的應用程序也會有菜單,而且我也想爲那些有時間的人安裝新的鍵盤綁定或加速器(或任何他們稱之爲助記符?)。爲了移動文本並刪除它們,只需要一些特殊的組合鍵就可以了。至於你在上面看到的關鍵組合?你可以想象這對我來說有多大的噩夢。
我向你保證沒有發佈更多的代碼,我試圖遵循良好的可重用計算機編程實踐模型。我有一個模型在下面運行,實際上處理編輯,以及上面運行並處理菜單按鈕代碼的視圖。
不幸的是,我希望Java不必像上面顯示的那樣麻煩。鍵盤上的所有鍵除了大多數鍵都需要不同的響應,具體取決於您所按的鍵,並且KeyBindings中支持ctrl和shift之類的組合。
我的希望是有一個循環解決方案。然後,也許有一個解決方案使用WHEN-IN-ANCESTOR
,也可以工作。我正在使用的輸入映射是組件根窗格,但我也打算儘可能遠地查看組件本身(一個JPanel)並獲得其實例,但我還沒有這樣做,因爲我'實驗。
我目前訪問項目的方式是這樣的:這適用於我。但它不處理符號。也許如果我增加了for循環中的字符跨度?或者手動添加幾個?我不知道。
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;
public void initKeyBindingsTheEasyWay() {
JRootPane rootPane = mainPane.getRootPane();
InputMap theWIMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap theAMap = rootPane.getActionMap();
for(char c = 'A'; c <= 'Z'; c++) {
// lower case
KeyStroke little = KeyStroke.getKeyStroke("pressed " + c);
theWIMap.put(little, ""+Character.toLowerCase(c));
theAMap.put(""+Character.toLowerCase(c), new LetterAction(Character.toLowerCase(c)));
}
}
public static class LetterAction extends AbstractAction
{
char theLetter;
public LetterAction(char letter)
{
theLetter = letter;
}
public void actionPerformed(ActionEvent ae)
{
System.out.print(theLetter);
}
}
這實際上並不是真正的關鍵綁定。如果你必須有一個gloabl級別的關鍵偵聽器,你可以考慮使用AWTListener而不是 – MadProgrammer
@MadProgrammer看看我上面的編輯。 – JonAar
愚蠢的問題,你爲什麼要監視這麼多鍵? – MadProgrammer