2008-11-13 13 views
75

के लिए उत्तरदायी कुंजीलिस्टर मैं अपने JFrame के लिए KeyListener लागू करने की कोशिश कर रहा हूं।जेएफआरएएम

System.out.println("test"); 
addKeyListener(new KeyListener() { 
    public void keyPressed(KeyEvent e) { System.out.println("tester"); } 

    public void keyReleased(KeyEvent e) { System.out.println("2test2"); } 

    public void keyTyped(KeyEvent e) { System.out.println("3test3"); } 
}); 

जब मैंने इसे चलाने के लिए, test संदेश मेरे कंसोल में आता है: निर्माता पर, मैं इस कोड का उपयोग कर रहा हूँ। हालांकि, जब मैं एक कुंजी दबाता हूं, तो मुझे कोई अन्य संदेश नहीं मिलता है, जैसे कि KeyListener वहां भी नहीं था।

मैं सोच रहा था कि यह हो सकता है कि क्योंकि ध्यान JFrame
पर नहीं है और इसलिए वे KeyListener किसी भी घटनाओं प्राप्त नहीं होता है। लेकिन, मुझे यकीन है कि यह है।

क्या ऐसा कुछ है जो मुझे याद नहीं है?

उत्तर

45

आपको अपनी कुंजी लिस्टनर को आवश्यक प्रत्येक घटक में जोड़ना होगा। केवल फोकस वाला घटक इन घटनाओं को भेज देगा। उदाहरण के लिए, यदि आपके जेएफआरएएम में केवल एक टेक्स्टबॉक्स है, तो टेक्स्टबॉक्स में फोकस है। इसलिए आपको इस घटक में एक KeyListener भी जोड़ना होगा।

प्रक्रिया में ही है:

myComponent.addKeyListener(new KeyListener ...); 

नोट: कुछ घटक JLabel तरह फ़ोकस करने योग्य नहीं हैं।

आप फ़ोकस करने योग्य करने के लिए उन्हें स्थापित करने के लिए की जरूरत है:

myComponent.setFocusable(true); 
+1

हाँ, आप सही थे, जब प्रोग्राम शुरू होता है तो आप थोड़ा सा देख सकते हैं कि फोकस बटन ए पर है। प्रत्येक बटन को एक कुंजीलिस्टर जोड़कर इसे ठीक किया गया है। यह थोड़ा अजीब है, मुझे लगता है कि JFrame में एक keylistener जोड़ना काम करेगा, लेकिन मुझे नहीं लगता। धन्यवाद! – Tomek

+0

मैंने जेएफआरएएम पर एक श्रोता बनाया है जो कीबोर्ड से सुनता है। मैं इसे निष्क्रिय मोड में काम करना चाहता हूं, भले ही खिड़की सामने नहीं है (केंद्रित)। JFrame निष्क्रिय मोड में नहीं सुन रहा है। – Usman

3

हम्म .. आपके कन्स्ट्रक्टर के लिए कौन सा वर्ग है? शायद कुछ वर्ग जेएफआरएएम का विस्तार कर रहे हैं? खिड़की का ध्यान खिड़की पर होना चाहिए, लेकिन मुझे नहीं लगता कि यह समस्या है।

मैंने आपके कोड का विस्तार किया, इसे चलाने की कोशिश की और यह काम किया - मुख्य प्रेस के परिणामस्वरूप प्रिंट आउटपुट हुआ। (ग्रहण के माध्यम से उबंटू के साथ चलाएं):

public class MyFrame extends JFrame { 
    public MyFrame() { 
     System.out.println("test"); 
     addKeyListener(new KeyListener() { 
      public void keyPressed(KeyEvent e) { 
       System.out.println("tester"); 
      } 

      public void keyReleased(KeyEvent e) { 
       System.out.println("2test2"); 
      } 

      public void keyTyped(KeyEvent e) { 
       System.out.println("3test3"); 
      } 
     }); 
    } 

    public static void main(String[] args) { 
     MyFrame f = new MyFrame(); 
     f.pack(); 
     f.setVisible(true); 
    } 
} 
+0

मैं भी संदेशों उत्पादन के सभी मिलता है। विंडोज कमांड लाइन में चलाएं। – Darrel

+1

आपको सभी संदेश मिलते हैं क्योंकि इस उदाहरण में जेएफआरएएम का ध्यान केंद्रित है। JFrame में टेक्स्टबॉक्स घटक जोड़ने का प्रयास करें और देखें कि क्या होता है। –

10

KeyListener निम्न स्तर है और केवल एक ही घटक पर लागू होता है। इसे और अधिक उपयोगी बनाने के प्रयासों के बावजूद JFrame कई घटक घटक बनाता है, सामग्री फलक सबसे स्पष्ट है। JComboBox यूआई को भी इसी तरह लागू किया जाता है।

माउस घटनाओं को महत्वपूर्ण घटनाओं के लिए थोड़ा अलग तरीके से काम करने के लायक है।

आपको क्या करना चाहिए इसके विवरण के लिए, Application wide keyboard shortcut - Java Swing पर मेरा उत्तर देखें।

10

मुझे तब तक एक ही समस्या मिली जब तक कि मैंने पढ़ा कि असली समस्या यह है कि आपके जेएफआरएम ने पहले ही श्रोताओं को जोड़ा है, लेकिन टूर फ्रेम कभी फोकस पर नहीं है क्योंकि आपके पास अपने जेएफआरएएम के अंदर बहुत सारे घटक हैं जो फोकस करने योग्य हैं इसलिए कोशिश करें:

JFrame.setFocusable(true); 

गुड लक

+1

मैंने पाया कि यह तब तक काम करता है जब तक कि मैं अपने जेएफआरएएम पर कुछ उपयोग नहीं करता तब कुंजीलिस्टर अब – user3328784

124

आप हर घटक पर एक श्रोता रजिस्टर करने के लिए नहीं करना चाहते हैं,
आप जोड़ सकता है अपनी खुद की KeyEventDispatcherKeyboardFocusManager रहे हैं:

public class MyFrame extends JFrame {  
    private class MyDispatcher implements KeyEventDispatcher { 
     @Override 
     public boolean dispatchKeyEvent(KeyEvent e) { 
      if (e.getID() == KeyEvent.KEY_PRESSED) { 
       System.out.println("tester"); 
      } else if (e.getID() == KeyEvent.KEY_RELEASED) { 
       System.out.println("2test2"); 
      } else if (e.getID() == KeyEvent.KEY_TYPED) { 
       System.out.println("3test3"); 
      } 
      return false; 
     } 
    } 
    public MyFrame() { 
     add(new JTextField()); 
     System.out.println("test"); 
     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 
     manager.addKeyEventDispatcher(new MyDispatcher()); 
    } 

    public static void main(String[] args) { 
     MyFrame f = new MyFrame(); 
     f.pack(); 
     f.setVisible(true); 
    } 
} 
+4

का जवाब नहीं देता है कीबोर्डफोकसमेनर आवेदन विस्तृत है, यदि आपके पास बहु फ्रेम हैं, तो आपको परेशानी होगी? – neoedmund

+1

तो यह काम करना चाहिए, कुछ ऐसा: foreach ("फ्रेम में फोकस करने योग्य घटक" _ के रूप में) {_.addkeylistener (frameKeylistener);} – neoedmund

2

मुझे एक ही समस्या है।मैंने ब्रूनो की सलाह का पालन किया और पाया कि JFrame (यानी, ऊपर बाईं ओर) "पहले" बटन पर केवल एक KeyListener जोड़ना चाल था। लेकिन मैं आपसे सहमत हूं कि यह एक परेशान समाधान है। तो मैं चारों ओर झुका और इसे ठीक करने के लिए एक साफ रास्ता खोजा। बस

myChildOfJFrame.requestFocusInWindow(); 

अपनी मुख्य विधि में, जेएफआरएएम के अपने उप-वर्ग का उदाहरण बनाने के बाद और इसे दृश्यमान सेट करने के बाद।

+0

धन्यवाद, वही समस्या थी। विचित्र रूप से घटक फोकस खो देता है भले ही यह सामग्री फलक है ... – Androbin

8

डीओन (और कोई अन्य प्रश्न पूछता है), आप ऊपर पीटर के कोड का उपयोग कर सकते हैं लेकिन मानक आउटपुट पर प्रिंट करने की बजाय, आप कुंजी कोड PRESSED, रिलीज़, या टाइपेड के लिए परीक्षण करते हैं।

@Override 
public boolean dispatchKeyEvent(KeyEvent e) { 
    if (e.getID() == KeyEvent.KEY_PRESSED) { 
     if (e.getKeyCode() == KeyEvent.VK_F4) { 
      dispose(); 
     } 
    } else if (e.getID() == KeyEvent.KEY_RELEASED) { 
     if (e.getKeyCode() == KeyEvent.VK_F4) { 
      dispose(); 
     } 
    } else if (e.getID() == KeyEvent.KEY_TYPED) { 
     if (e.getKeyCode() == KeyEvent.VK_F4) { 
      dispose(); 
     } 
    } 
    return false; 
} 
4

आदेश में एक JFrame में सभी पाठ क्षेत्रों में महत्वपूर्ण घटनाओं पर कब्जा करने में, एक एक महत्वपूर्ण घटना के बाद प्रोसेसर को रोजगार कर सकते हैं। स्पष्ट रूप से जोड़ने के बाद, यहां एक कामकाजी उदाहरण है।

public class KeyListenerF1Demo extends JFrame implements KeyEventPostProcessor { 
    public static final long serialVersionUID = 1L; 

    public KeyListenerF1Demo() { 
     setTitle(getClass().getName()); 

     // Define two labels and two text fields all in a row. 
     setLayout(new FlowLayout()); 

     JLabel label1 = new JLabel("Text1"); 
     label1.setName("Label1"); 
     add(label1); 

     JTextField text1 = new JTextField(10); 
     text1.setName("Text1"); 
     add(text1); 

     JLabel label2 = new JLabel("Text2"); 
     label2.setName("Label2"); 
     add(label2); 

     JTextField text2 = new JTextField(10); 
     text2.setName("Text2"); 
     add(text2); 

     // Register a key event post processor. 
     KeyboardFocusManager.getCurrentKeyboardFocusManager() 
       .addKeyEventPostProcessor(this); 
    } 

    public static void main(String[] args) { 
     JFrame f = new KeyListenerF1Demo(); 
     f.setName("MyFrame"); 
     f.pack(); 
     f.setVisible(true); 
    } 

    @Override 
    public boolean postProcessKeyEvent(KeyEvent ke) { 
     // Check for function key F1 pressed. 
     if (ke.getID() == KeyEvent.KEY_PRESSED 
       && ke.getKeyCode() == KeyEvent.VK_F1) { 

      // Get top level ancestor of focused element. 
      Component c = ke.getComponent(); 
      while (null != c.getParent()) 
       c = c.getParent(); 

      // Output some help. 
      System.out.println("Help for " + c.getName() + "." 
        + ke.getComponent().getName()); 

      // Tell keyboard focus manager that event has been fully handled. 
      return true; 
     } 

     // Let keyboard focus manager handle the event further. 
     return false; 
    } 
} 
+0

एक कामकाजी उदाहरण के लिए आप आयात जोड़ने पर विचार कर सकते हैं। मैं उन्हें कम रखने के लिए आमतौर पर 'पैकेज आयात' जोड़ता हूं। अन्यथा, +1। दिलचस्प तकनीक। –

-1

lol .... तुम सब करने की है सुनिश्चित करें कि है कि

addKeyListener (this);

आपके कोड में सही ढंग से रखा गया है।

+7

आपको इसे एक उपयोगी उत्तर देने के लिए वास्तव में "सही स्थान" की व्याख्या करनी चाहिए। – Till

-1

आप कस्टम जेकंपोनेंट्स को अपने माता-पिता जेएफआरएएम को फोकस करने योग्य सेट कर सकते हैं।

बस एक कन्स्ट्रक्टर जोड़ें और जेएफआरएएम में पास करें। फिर पेंट कॉम्पोनेंट में सेट फोकसबल() को कॉल करने के लिए कॉल करें।

इस तरह जेएफआरएएम हमेशा अन्य तत्वों को दबाए जाने के बावजूद KeyEvents प्राप्त करेगा।

+2

-1 निश्चित रूप से नहीं - यह एक से अधिक सम्मान में पूर्ण <मजबूत शब्द सेंसर> है: ए) अश्लील subclassing बी) अश्लील संदर्भ उत्तीर्ण सी) चित्रकला के दौरान अनुचित राज्य परिवर्तन डी) .. – kleopatra

15

इनपुट मैप्स और एक्शनमैप्स घटक, यह और उसके सभी उप-घटकों, या पूरी विंडो के लिए महत्वपूर्ण घटनाओं को कैप्चर करने के लिए डिज़ाइन किए गए थे। यह JComponent.getInputMap() में पैरामीटर के माध्यम से नियंत्रित किया जाता है। दस्तावेज के लिए How to Use Key Bindings देखें।

इस डिज़ाइन की सुंदरता यह है कि कोई भी चुन सकता है और चुन सकता है कि कौन से महत्वपूर्ण स्ट्रोक मॉनिटर करने के लिए महत्वपूर्ण हैं और उन महत्वपूर्ण स्ट्रोक के आधार पर अलग-अलग कार्रवाइयों को निकाल दिया गया है।

यह कोड विंडो में कहीं भी हिट कुंजी को हिट करते समय JFrame पर निपटान() को कॉल करेगा। JFrame JComponent से प्राप्त नहीं होता है इसलिए आपको कुंजी बाध्यकारी बनाने के लिए JFrame में एक और घटक का उपयोग करना होगा। सामग्री फलक ऐसा घटक हो सकता है।

InputMap inputMap; 
ActionMap actionMap; 
AbstractAction action; 
JComponent component; 

inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 
actionMap = component.getActionMap(); 

action = new AbstractAction() 
{ 
    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     dispose(); 
    } 
}; 

inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dispose"); 
actionMap.put("dispose", action); 
3

यह मदद करनी चाहिए

yourJFrame.setFocusable(true); 
    yourJFrame.addKeyListener(new java.awt.event.KeyAdapter() { 


     @Override 
     public void keyTyped(KeyEvent e) { 
      System.out.println("you typed a key"); 
     } 

     @Override 
     public void keyPressed(KeyEvent e) { 
      System.out.println("you pressed a key"); 
     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      System.out.println("you released a key"); 
     } 
    }); 
+0

सबसे अच्छा Slution कभी। धन्यवाद। – biv

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