2008-09-19 19 views
27

मैं जावा स्विंग एप्लिकेशन के लिए एक एप्लिकेशन विस्तृत कीबोर्ड शॉर्टकट बनाना चाहता हूं। सभी घटकों पर लूपिंग और प्रत्येक पर शॉर्टकट जोड़ने से संबंधित साइड इफेक्ट्स पर ध्यान केंद्रित होता है, और यह एक ब्रूट फोर्स सॉल्यूशन की तरह लगता है।एप्लिकेशन विस्तृत कीबोर्ड शॉर्टकट - जावा स्विंग

किसी के पास क्लीनर समाधान है?

उत्तर

20

एक कस्टम KeyEventDispatcher स्थापित करें। इस कार्यक्षमता के लिए कीबोर्डफोकस प्रबंधक वर्ग भी एक अच्छी जगह है।

KeyEventDispatcher

37

प्रत्येक विंडो के लिए, WHEN_IN_FOCUSED_WINDOW की एक शर्त के साथ JComponent.registerKeyboardAction का उपयोग करें। वैकल्पिक रूप से उपयोग करें:

JComponent.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(keyStroke, command); 
JComponent.getActionMap().put(command,action); 

जैसा कि registerKeyboardAction API docs में वर्णित है।

+0

+1 सबसे अच्छा, सबसे आसान जवाब मैं मिल गया है। मैं इस x1000 –

+3

x1001 को बेहतर बनाउंगा, इस तरह वह कम से कम एक अपवर्तित होगा। – Epaga

+0

@Epaga या 999 बार –

6

आप एक मेनू है, तो आप मेनू आइटम करने के लिए वैश्विक कीबोर्ड शॉर्टकट जोड़ सकते हैं:

JMenuItem item = new JMenuItem(action); 
    KeyStroke key = KeyStroke.getKeyStroke(
     KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK); 
    item.setAccelerator(key); 
    menu.add(item); 
13

लोग (मेरे जैसे) KeyEventDispatcher उपयोग करने के लिए कैसे सोच के लिए, यहाँ एक उदाहरण है कि मैं एक साथ रखा है। यह सभी वैश्विक कार्यों को संग्रहीत करने के लिए हैश मैप का उपयोग करता है, क्योंकि मुझे बड़ी if (key == ..) then .. else if (key == ..) then .. else if (key ==..) .. संरचनाएं पसंद नहीं हैं।

/** map containing all global actions */ 
private HashMap<KeyStroke, Action> actionMap = new HashMap<KeyStroke, Action>(); 

/** call this somewhere in your GUI construction */ 
private void setup() { 
    KeyStroke key1 = KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_DOWN_MASK); 
    actionMap.put(key1, new AbstractAction("action1") { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("Ctrl-A pressed: " + e); 
    } 
    }); 
    // add more actions.. 

    KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 
    kfm.addKeyEventDispatcher(new KeyEventDispatcher() { 

    @Override 
    public boolean dispatchKeyEvent(KeyEvent e) { 
     KeyStroke keyStroke = KeyStroke.getKeyStrokeForEvent(e); 
     if (actionMap.containsKey(keyStroke)) { 
     final Action a = actionMap.get(keyStroke); 
     final ActionEvent ae = new ActionEvent(e.getSource(), e.getID(), null); 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
      a.actionPerformed(ae); 
      } 
     }); 
     return true; 
     } 
     return false; 
    } 
    }); 
} 

SwingUtils.invokeLater के उपयोग() हो सकता है आवश्यक नहीं है, लेकिन यह शायद वैश्विक घटना पाश ब्लॉक करने के लिए नहीं एक अच्छा विचार है।

+0

सबसे आसान समाधान नहीं है, लेकिन निश्चित रूप से सबसे सुरुचिपूर्ण और भरोसेमंद है। –

-1

कोड

ActionListener a=new ActionListener(){ 
    public void actionPerformed(ActionEvent ae) 
    { 
    // your code 
    } 
}; 
getRootPane().registerKeyboardAction(a,KeyStroke.getKeyStroke("ctrl D"),JComponent.WHEN_IN_FOCUSED_WINDOW); 

का निम्न भाग का उपयोग शॉर्टकट आप चाहते हैं के साथ "ctrl डी" बदलें।

+0

नहीं, यह पुराना एपीआई है (jdk 1.2 या 1.3 के बाद actionMap/inputMap से अतिरंजित - पत्थर युग में वापस रास्ता) – kleopatra

+0

@ क्लोपेट्रा हम्म। टिप्पणी के लिए धन्यवाद। मैं कारण जानना चाहता हूं। मुझे यह नहीं मिला! – user12458

+0

काफी समझ में नहीं आता - क्या कारण है? – kleopatra

1

एक छोटी सी सरल उदाहरण:

KeyboardFocusManager keyManager; 

keyManager=KeyboardFocusManager.getCurrentKeyboardFocusManager(); 
keyManager.addKeyEventDispatcher(new KeyEventDispatcher() { 

    @Override 
    public boolean dispatchKeyEvent(KeyEvent e) { 
    if(e.getID()==KeyEvent.KEY_PRESSED && e.getKeyCode()==27){ 
     System.out.println("Esc"); 
     return true; 
    } 
    return false; 
    } 

}); 
संबंधित मुद्दे