2011-02-02 14 views
5

मेरे पास एक स्विंग ऐप है जिसे नियंत्रण या alt कुंजी दबाए जाने के आधार पर नियंत्रण के विभिन्न सेट प्रदर्शित करने की आवश्यकता होती है। मैंने मुख्य घटक में एक KeyListener जोड़ा, लेकिन यह केवल तभी अधिसूचित किया जाता है जब उस घटक का चयन किया गया हो, न कि उपसंवेदनशील का चयन किया गया हो। क्या एक घटक और सभी वंश के लिए घटनाओं को सुनने का कोई तरीका है?किसी घटक पदानुक्रम के लिए महत्वपूर्ण घटनाओं को सुनना

संपादित करें:

मैं मुख्य घटक के InputMap उपयोग करने की कोशिश, लेकिन जब एक आपरिवर्तक कुंजी दबाने कोई घटना निकाल दिया जाता है। विशेष रूप से, मैं निम्नलिखित कोड है:

InputMap inputMap = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 
inputMap.put(KeyStroke.getKeyStroke("pressed CONTROL"), "test1"); 
inputMap.put(KeyStroke.getKeyStroke("released CONTROL"), "test2"); 
ActionMap actionMap = panel.getActionMap(); 
actionMap.put("test1", new AbstractAction() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("pressed"); 
    } 
}); 
actionMap.put("test2", new AbstractAction() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("released"); 
    } 
}); 

जब दबाकर और नियंत्रण कुंजी को रिहा, इस प्रिंट होगा "जारी" लेकिन "दबाया"। किसी भी इनपुट मैप में कुछ भी पंजीकरण नहीं कर रहा है, इसलिए ऐसा नहीं है कि एक ही कुंजी स्ट्रोक के लिए कुछ और पंजीकृत है।

उत्तर

2

आप KeyListeners की बजाय कुंजी बाध्यकारी उपयोग करने का प्रयास करना चाह सकते हैं। कुंजी बाध्यकारी एक उच्च स्तरीय निर्माण है और कुंजी प्रेस के लिए सुन सकता है भले ही "सुनता" घटक का ध्यान केंद्रित न हो - KeyListeners के विपरीत। आप स्विंग ट्यूटोरियल पर इन पर और अधिक पा सकते हैं: How to use key bindings

2

आप कुछ स्विंग घटकों के the InputMap and ActionMap का उपयोग करने पर विचार कर सकते हैं। आप JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT के साथ निर्दिष्ट कर सकते हैं यह इंगित करने के लिए कि आप दिए गए कीस्ट्रोक का जवाब देना चाहते हैं, जब घटक या उसके उप-संयोजक फोकस में हों।

आप InputMap या ActionMap का उपयोग नहीं करना चाहते हैं, तो आप सिर्फ KeyListener सभी बच्चे घटकों के लिए जोड़ सकते हैं:

for (Component child : parent.getComponents()) 
{ 
child.addKeyListener(keyListener); 
} 
+0

यह "जारी नियंत्रण" KeyStrokes के लिए काम करता है लेकिन "दबाए गए नियंत्रण" के लिए नहीं। इसी प्रकार alt और shift के लिए। –

+0

@Adam Crume Well, कुछ नियंत्रण स्वयं को ctrl, alt, या shift में सुन सकते हैं। हालांकि, कम से कम अन्य कीस्ट्रोक के साथ परीक्षण, यह कुंजी प्रेस पर दी गई कार्रवाई शुरू करता है। माना जाता है कि, हालांकि, यह कीस्ट्रोक दबाए जाने पर बार-बार लॉन्च होगा। –

+0

इनपुट मैप और एक्शनमैप के साथ जैक का उल्लेख कुंजी बाइंडिंग का उपयोग कर रहा है। फिर, ट्यूटोरियल की जांच करें जो आपकी समस्या का समाधान करेगी। –

4

बस इतना की तरह अपने getKeyStroke(...) मंगलाचरण बदलने के लिए:

InputMap inputMap = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, KeyEvent.CTRL_DOWN_MASK, false), "test1"); 
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, 0, true), "test2"); 
ActionMap actionMap = panel.getActionMap(); 
actionMap.put("test1", new AbstractAction() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("pressed"); 
    } 
}); 
actionMap.put("test2", new AbstractAction() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("released"); 
    } 
}); 

मैं मेरे परीक्षण और त्रुटि के एक बहुत ले लिया सही मंत्र साथ आने के लिए।

बच्चे और गहरे विजेट को सुनने में सक्षम होने के लिए getInputMap (JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) का उपयोग करना महत्वपूर्ण है।

नियंत्रण कुंजी प्रेस घटनाओं की तलाश करते समय KeyEvent.VK_CONTROL के अलावा KeyEvent.CTRL_DOWN_MASK निर्दिष्ट करना विशेष रूप से महत्वपूर्ण है। यह विशेष विवरण आपके संशोधित कोड उदाहरण से गायब था।

+0

मुझे 'WHEN_ANCESTOR_OF_FOCUSED_COMPONENT' के साथ समस्याएं थीं और 'WHEN_IN_FOCUSED_WINDOW' का उपयोग करने के लिए इसे और अधिक उपयोगी पाया। – jan

संबंधित मुद्दे