2012-09-16 33 views
7

मेरे पास एक स्विंग टाइमर (javax.swing.Timer) है जिसका उपयोग कस्टम स्विंग घटक के भीतर कुछ एनीमेशन करने के लिए किया जाता है।एक घटक छुपाए जाने पर एक स्विंग टाइमर को रोकना

हालांकि, यह समस्याएं पैदा कर रहा है - विशेष रूप से ऐसा लगता है कि सभी विंडो बंद होने के बाद भी लाइव टाइमर थ्रेड के कारण एप्लिकेशन को समाप्त करने से रोकना प्रतीत होता है। एनीमेशन को देखा नहीं जा सकता है जब छुपे ऑब्जेक्ट्स पर चलने वाले टाइमर के ओवरहेड से बचना अच्छा होगा।

आदर्श रूप में मैं निम्न कार्य करना चाहते हैं:

  • टाइमर बंद करें जब घटक
  • प्रारंभ समय फिर जब भी घटक दिखाई

हो जाता है छिपा हुआ है करने के लिए यह संभव है (पाठ्यक्रम के थ्रेड-सुरक्षित तरीके में!)

+4

हम्म .. क्या एक ancestorListener साथ कुछ गड़बड़ है (जो मेरा पहला विचार होगा)? – kleopatra

+0

या आप इसे एक [कंपोनेंट लिस्टनर] (http://docs.oracle.com/javase/7/docs/api/java/awt/event/ComponentListener.html) जोड़ सकते हैं और ** timer.start()/रोकें() इसके घटक के अंदर हैड (...) और घटकशोउन (...) विधियों ** –

+1

@ गगनदीप बालिन एक घटक लिस्टनर केवल एक प्रकार की संपत्ति है चेंजलिस्टर एक घटक की दृश्यमान संपत्ति के लिए, जो कि अगर नहीं बदला जाता हैएक पूर्वज छुपा/दिखाया गया है। – kleopatra

उत्तर

5

मुझे आपके पहले आधार पर संदेह है: यह सरल counter-example दिखाता है कि चल रहा है javax.swing.TimerEXIT_ON_CLOSE को रोकता नहीं है। पैकेज-निजी, साझा javax.swing.TimerQueue एक डेमॉन थ्रेड शुरू करता है, जो Program Exit की अनुमति देता है। आप कार्यान्वयन विस्तार पर भरोसेमंद पर समझदारी से अनिच्छुक हो सकते हैं, लेकिन यह संभव है कि आपका प्रोग्राम बाहर निकलने में विफल रहता है।

यदि AncestorListener पर @ क्लोपेट्रा को रोकें; यह आपको वांछित के रूप में Timer को नियंत्रित करने की अनुमति देनी चाहिए। एक घटक एनीमेशन का कर्तव्य चक्र सामान्य रूप से काफी हल्का होता है, और यह आमतौर पर प्रतिपादन का प्रभुत्व है; जब घटक दिखाई नहीं देता है तो उत्तरार्द्ध का ओवरहेड छोटा होता है। यह सत्यापित करने के लिए प्रोफाइलिंग योग्य हो सकता है कि प्रस्तावित अनुकूलन प्रयास के लायक है। यदि ऐसा है, तो एक निष्क्रिय या प्रतिष्ठित विंडो में गतिविधि को कम करने के लिए WindowListener पर विचार करें।

अनुपूरक: अब एक हटाए गए उत्तर टाइमर की स्थिति के लिए setVisible() ओवरराइड करने का सुझाव दिया गया है। सतही रूप से आकर्षक होने पर, दृष्टिकोण भंगुर और स्केल खराब है। श्रोता दृष्टिकोण observer pattern आमतौर पर Swing architecture में उपयोग किया जाता है।

+0

धन्यवाद, इस दृष्टिकोण ने अच्छी तरह से काम किया (वास्तव में मैंने कुछ अन्य कार्यक्रमों को पकड़ने में सक्षम होने के लिए एक हीरार्ची लिस्टनर का उपयोग किया लेकिन मुझे लगता है कि सिद्धांत समान है)। मुझे यह भी लगता है कि आप टाइमर पर भी सही हैं, लेकिन जैसा कि आप कहते हैं कि यह सबसे अच्छा हो सकता है कि उस व्यवहार पर भरोसा न करें! – mikera

+1

संदर्भ के लिए, यहां एक संबंधित [उदाहरण] (http://stackoverflow.com/q/10880326/230513) है जो वर्णित तीन श्रोताओं की तुलना करता है। – trashgod

1

शर्टडाउन शुरू होने के लिए इवेंट कतार एक सेकंड के लिए शांत होना चाहिए। यह AWTAutoShutdown कक्षा में एक हार्ड कोड कोड है।

तो यदि आपका स्विंग टाइमर घटनाओं को उत्पन्न करता रहता है, तो एक सेकंड अलग होता है, जो एप्लिकेशन को समाप्त होने से रोकता है।

इस उदाहरण को देखें (नीचे)। यह समाप्त नहीं होगा, क्योंकि धागा, भले ही इसे डीमोन के रूप में चिह्नित किया गया हो, कतार में घटनाओं को जोड़ता रहता है। अगर हम नींद को 1500 (1.5 सेकेंड) तक बढ़ाते हैं - तो यह खुशी से समाप्त हो जाएगा।

public static void main(String[] args) 
{ 
    Thread thread = new Thread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      while (true) 
      { 
       // Submit an empty event to the queue 
       EventQueue.invokeLater(new Runnable() 
       { 
        @Override 
        public void run() 
        { 
        } 
       }); 
       try 
       { 
        Thread.sleep(500); 
       } 
       catch (InterruptedException e) 
       { 
        throw new IllegalStateException(e); 
       } 
      } 
     } 
    }); 
    thread.setDaemon(true); 
    thread.start(); 
} 
1

हम इसे इस तरह कार्य करें:

private static final class DisplayabilityListener implements HierarchyListener { 
    private final JComponent component; 
    private final Timer timer; 

    private DisplayabilityListener(JComponent component, Timer timer) { 
    this.component = component; 
    this.timer = timer; 
    } 

    @Override 
    public void hierarchyChanged(HierarchyEvent e) { 
    if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) > 0) { 
     if (component.isDisplayable()) { 
      timer.start(); 
     } else { 
      timer.stop(); 
     } 
    } 
    } 

}

+0

मैं 'if ((x और y)> 0)' 'if ((x और y)! = 0) में बदलूंगा, क्योंकि यह वाईएस के एमएसबी सेट के जरिए काम नहीं करेगा। – Matthieu

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