2012-11-19 43 views
5

मुझे लगता है कि जैसे एक कोड है:repaint() तुरंत "पुनः पेंट" नहीं करता है?

// In MyPanel.java 
public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    // Draw something 
    mypanel_count++; 
} 

// In Test.java 
public void testLargeData() 
{ 
    while (notDone) 
    { 
     panel.repaint(); 
     // do huge work 
     test_count++; 
     System.out.println("Test_count: " + test_count + ", MyPanel_count: " + mypanel_count); 
    } 
} 

// Output !!! 
Test_count: 752, MyPanel_count: 23 
Test_count: 753, MyPanel_count: 23 
Test_count: 754, MyPanel_count: 23 
Test_count: 755, MyPanel_count: 24 

लेकिन जब मैं panel.paintComponent(panel.getGraphics()) को panel.repaint() बदलने के लिए, बाहर सही है:

Test_count: 752, MyPanel_count: 752 
Test_count: 753, MyPanel_count: 753 
Test_count: 754, MyPanel_count: 754 
Test_count: 755, MyPanel_count: 755 

क्यों? paintComponent विधि काम करता है, लेकिन कभी-कभी यह अंधा होता है, इसलिए मैं इसका उपयोग नहीं करना चाहता हूं। कोई मुझे कुछ सुझाव दे सकता है? धन्यवाद!

+0

http://stackoverflow.com/questions/9389187/difference-between-paint-paintcomponent-and-paintcomponents-in-swing। – Raghunandan

+0

@ रघुनाथन: आपके उत्तर के लिए धन्यवाद, लेकिन यह मेरी परेशानी नहीं है। –

+0

आपने कोशिश की [JComponent.html # पेंट तुरंत (int, int, int, int)] (http://docs.oracle.com/javase/6/docs/api/javax/swing/JComponent.html#paintImmediately%28int ,% 20int,% 20int,% 20int% 29) – mKorbel

उत्तर

9

आप repaint के प्रलेखन ध्यान से पढ़ें, तो आप देखेंगे यह कहा गया है कि कि (जोर मेरा): इस घटक एक हल्के घटक है

हैं, तो इस विधि इस घटक के रंग पद्धति के लिए एक कॉल जितनी जल्दी हो सके कारण बनता है। अन्यथा, यह विधि इस घटक की अद्यतन विधि पर जितनी जल्दी हो सके पर कॉल का कारण बनती है।

इसका मतलब है कि एडब्ल्यूटी/स्विंग को तेजी से उत्तराधिकार में अनुरोध किए गए पश्चातापों को विलय करके पुनर्भुगतान को अनुकूलित करने की अनुमति है। repaint(long time) विधि भी है, जो आपको यह नियंत्रित करने की अनुमति देती है कि आपके पुन: अनुरोध के पूर्ण होने के साथ कितनी देर तक एडब्ल्यूटी/स्विंग को प्रतीक्षा करने की अनुमति है। यह अभी भी अनुरोधों को मर्ज कर सकता है, खासकर अगर आप उन्हें लूप में करते हैं।

लेख "Painting in AWT and Swing" लेख पढ़ने में मददगार हो सकता है, जो शामिल विभिन्न अवधारणाओं को समझाने की कोशिश करता है।

प्रत्येक पुनरावृत्ति के लिए पैनल को पुनर्निर्मित करने के लिए, आपको एक पेंट होने की प्रतीक्षा करनी होगी और फिर अपने लूप के साथ आगे बढ़ना होगा। इसका मतलब है कि आपको अपने प्रोसेसिंग थ्रेड (लूप) और एडब्ल्यूटी/स्विंग थ्रेड के बीच कुछ सिंक्रनाइज़ेशन की आवश्यकता है। एक अजीब विचार के रूप में, आप उदाहरण के लिए wait() अपने लूप के अंत में पैनल ऑब्जेक्ट पर कर सकते हैं अगर इसे repaint() पर अंतिम कॉल के बाद से पुनर्निर्मित नहीं किया गया है और अपने पैनल के paintComponent() विधि के अंत में notifyAll() पर कॉल करें। हालांकि, यह सही लागू करने के लिए मुश्किल हो सकता है, इसलिए आपको केवल यह करना चाहिए यदि आपको वास्तव में अपने घटक के "रीयल-टाइम" को फिर से निकालना होगा। वैकल्पिक रूप से, paintImmediately(...) इस्तेमाल किया जा सकता है, लेकिन आप इस तरह घटना भेजने धागा में अपने सभी प्रसंस्करण करने के लिए, होगा:

SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     while(notDone) { 
      // Do your processing 
      panel.paintImmediately(...); 
     } 
    } 
}); 

ध्यान दें कि यह माउस और कार्रवाई की जा रही से कीबोर्ड इनपुट सहित किसी भी घटना प्रसंस्करण बंद हो जाएगा जबकि आपका लूप चल रहा है। आप "Concurrency in Swing"

0

समझते हैं कि आप पूरा नियंत्रण अपने हाथ में नहीं है कि अगर या जब रंग (...) के नाम से मिलता है, और कहा कि रीपेंट() कॉल केवल एक पेंट करने के लिए JVM करने के लिए सुझाव है। भी कई रीपेंट() में आते हैं अनुरोध और वे टिके रहते हैं के रूप में तुम्हारा क्या कर रहे हैं, तो वे

संयोजित कर दिया जाएगा, तो देखें: https://stackoverflow.com/a/13256847/1423083

1

में स्विंग और थ्रेडिंग के बारे में अधिक पढ़ सकते हैं जैसा कि अन्य उत्तरों कहते हैं: यह एक समस्या है जब एडब्ल्यूटी paint() पर कॉल कर रहा है।

यदि आप कुछ काम करते हैं जिन्हें पेंट किए गए/लेआउट किए गए घटक से जानकारी की आवश्यकता होती है, तो इस काम को एक कार्यकर्ता थ्रेड में रखने में क्या मदद मिलती है जो चित्रकला होने तक प्रतीक्षा करता है।

panel.repaint(); 

SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     // do huge work 
     test_count++; 
     System.out.println("Test_count: " + test_count 
      + ", MyPanel_count: " + mypanel_count); 
    } 
}); 

हालांकि मुझे यकीन है कि यह कैसे अपने while पाश से व्यवहार करते हैं नहीं कर रहा हूँ:

अपने मामले ऐसा ही कुछ होगा में