2010-03-01 13 views
5

मेरे पास एक प्रोग्राम है, जो लोड करने में लंबा समय लगता है। इस वजह से, मैं एक स्पलैश स्क्रीन विकसित करना चाहता था जो लोड होने वाले उपयोगकर्ता को फीडबैक प्रदान कर सके। एक छवि, लेबल और जेपी प्रोग्रेसबार के साथ एक साधारण जेफ्रेम।कस्टम जावा स्प्लैश स्क्रीन "फ्रीज" जब तक पूरे एप्लिकेशन को लोड नहीं किया गया है

मैं प्रयोग किया गया है और सबसे अच्छा परिणाम रहा था मेरी main() में यह कर रहे हैं:

SwingUtilities.invokeAndWait(new Runnable() { 

    public void run() { 

     new SplashScreen(); 
    } 
}); 

SwingUtilities.invokeAndWait(new Runnable() { 

    public void run() { 

     //Code to start system 
     new MainFrame(); 
     //.. etc 
    } 
}); 
दोनों SplashScreen और मेनफ्रेम

JFrame का विस्तार वर्ग हैं। मैं पुस्तकालय के रूप में सबस्टेंस का भी उपयोग कर रहा हूं।

स्पलैशस्क्रीन का कन्स्ट्रक्टर खुद को जेएलएबल और जेपी प्रोग्रेसबार जोड़ता है, पैक करता है और दृश्यमान सेट करता है। जेपी प्रोग्रेसबार setIndeterminate(true) है;

जब मैं अपना प्रोग्राम चलाता हूं, तो मेरी स्पलैशस्क्रीन प्रदर्शित होती है लेकिन प्रोग्रेसबार लॉक हो जाता है, यह तब तक नहीं चलता है जब तक कि शेष कार्यक्रम शुरू नहीं हो जाता है, यह अपेक्षा के अनुसार आगे बढ़ना शुरू कर देता है।

मुझे यहां क्या याद आ रही है? मैंने जो खोज किया है, वह इस समस्या का उल्लेख नहीं करता है और अधिकांश "कस्टम स्पलैश स्क्रीन" कार्यान्वयन मेरे बारे में एक बहुत ही समान तरीके से जाते हैं।

उत्तर

1

अन्य उत्तरों में से अधिकांश इसमें शामिल हैं लेकिन संक्षेप में आपकी समस्या यह है कि आप स्विंग इवेंट प्रेषण धागे में "सिस्टम प्रारंभ करने के लिए कोड" चला रहे हैं। सभी जीयूआई से संबंधित कोड (घटक निर्माण सहित) ईडीटी पर चलाना चाहिए लेकिन अन्य सभी कोड ईडीटी पर नहीं चलना चाहिए। अपने कार्यक्रम बदल रहा है यह करने के लिए प्रयास करें:

SwingUtilities.invokeAndWait(new Runnable() { 
    public void run() { 
     new SplashScreen(); 
    } 
}); 
// Code to start system (nothing that touches the GUI) 
SwingUtilities.invokeAndWait(new Runnable() { 
    public void run() { 
     new MainFrame(); 
    } 
}); 
//.. etc 
3

invokeAndWait स्विंग थ्रेड को तब तक स्थिर कर देगा जब तक इसे पूरा नहीं किया जाता है। इसलिए, मेनफ्रेम बनने तक आपकी प्रगति पट्टी 100% जमेगी होगी।

आपको एक गैर-स्विंग थ्रेड उत्पन्न करना चाहिए जो स्प्रिंग स्क्रीन को स्विंगउटिविटीजवोक (बाद में | एंडवेट) का उपयोग करके अपडेट करता है।

new Thread(new Runnable() { public void run() { 
    // Create MainFrame here 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     updateProgressHere(); 
     } 
    }); 

    // Do other initialization 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     updateProgressHere(); 
     } 
    }); 
}).start(); 
+0

प्रतिक्रिया के लिए धन्यवाद, नगण्य मैं इस काम के लिए है, लेकिन केवल मादक द्रव्यों का उपयोग किए बिना का एक सा के बाद। करते हैं, अपने कोड का उपयोग, मेरे पास है: SwingUtilities.invokeLater (नई Runnable() { सार्वजनिक शून्य रन() { कोशिश { UIManager.setLookAndFeel (नई SubstanceSaharaLookAndFeel()); } पकड़ (UnsupportedLookAndFeelException पूर्व) { \t लॉगर.getLogger (Main.class.getName()) लॉग (स्तर .SEVERE, शून्य, पूर्व); } } }); मुझे त्रुटि मिलती है "इवेंट डिस्पैच थ्रेड पर घटक निर्माण किया जाना चाहिए" –

+1

पदार्थ घटक निर्माण थ्रेडिंग नियमों को लागू करता है - आपको स्विंग ईडीटी पर सभी जीयूआई घटक बनाना होगा। मेरा जवाब देखें –

1

दूसरों mentiones है जिनकी वजह से आपके प्रगति बार अवरुद्ध है, मैं एक वैकल्पिक समाधान Java6 javaw और जावा लांचर के लिए splash screen handling built in है ...

स्प्लैश स्क्रीन भी JVM और इससे पहले कि प्रदर्शित किया जाता है का सुझाव देगा एप्लिकेशन की कक्षाएं लोड की जाती हैं, और फिर एक बार शुरू होने के बाद एप्लिकेशन इसे आंतरिक लोडिंग स्थिति को प्रतिबिंबित करने के लिए अपडेट कर सकता है, और तैयार होने पर इसे बंद कर सकता है।

वैकल्पिक रूप से, विंडोज़-केवल समाधानों के लिए, Winrun4J java launcher में एक स्पलैश स्क्रीन सुविधा भी है।

+0

बिल्ट-इन स्प्लैशस्क्रीन सिर्फ एक छवि है, और इस प्रकार लोडिंग प्रोग्रेस बार प्रदर्शित करने के लिए बेकार है। – Powerlord

+0

वास्तव में नहीं, मेरे लिंक से: "स्पलैशस्क्रीन क्लास का उपयोग स्प्लैश स्क्रीन में पेंट करने के लिए किया जाता है।" – CuriousPanda

3

सिर्फ एलन के सही उत्तर से थोड़ा अधिक सामान्य होने का प्रयास करने के लिए।

आपके सिस्टम में एक धागा है जो कानूनी रूप से जीयूआई अपडेट कर सकता है।

यदि आप अपने सिस्टम को आरंभ करने के लिए उस थ्रेड का उपयोग कर रहे हैं, तो guis अपडेट नहीं होगा।

यदि आप अपने मुख्य थ्रेड से अपने जीयूआई को अपडेट करने का प्रयास कर रहे हैं, तो कुछ भी सही नहीं होगा।

हमेशा जागरूक रहें कि आपका जीयूआई किस धागे पर है और सुनिश्चित करें कि उस धागे पर काम न करें।

इस तरह से जीयूआई अद्यतन की तरह देखें:

  • अपने गैर जीयूआई धागा एक मूल्य आप प्रदर्शित कर रहे हैं (प्रतिशत किया कहते हैं) अद्यतन करता है।
  • यह invokeLater के माध्यम से एक अद्यतन पोस्ट करता है, फिर अन्य काम के साथ जारी है।
  • जीयूआई थ्रेड आपके invokeLater को निष्पादित करता है जो गैर-जीयूआई थ्रेड
  • से गुजरने वाले डेटा के साथ आपके जीयूआई को अपडेट करता है जो जीयूआई थ्रेड निकलता है! यह सिस्टम के अन्य असंबंधित हिस्सों को जीयूआई को अद्यतन करने की अनुमति देता है जब उन्हें आवश्यकता होती है।

गैर जीयूआई धागे सबसे अधिक बार Thread.start से थ्रेड और एक पारित कर रहे हैं करने के लिए "मुख्य"

जीयूआई धागा एक एक जीयूआई ईवेंट से अपनी "invokeLater" और कुछ भी आप के लिए पारित क्रियान्वित है (बटन दबाया गया, जीयूआई टाइमर, कोई स्विंग श्रोताओं।)

इस वजह से, अक्सर जीयूआई को अपडेट करने का समय होने पर आप पहले ही जीयूआई थ्रेड पर हैं - बस स्टार्टअप अनुक्रमण और स्थानों के लिए देखें जहां थ्रेड चाहते हैं प्रदर्शन अद्यतन करें।

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