मेरे समझ: घटकों का सबसे विपरीत/JComponent.repaint() करने के लिए स्विंग कॉल में आपरेशन धागा सुरक्षित यानी हालांकि एक रीपेंट अनुरोध (यानी EDT से नहीं) एक और धागे से बना है, वास्तविक चित्र में क्या होता है केवल ईडीटी। कोड स्निपेट के नीचे यह दर्शाता है।जावा स्विंग में JComponent.paintImedimedi() काम कैसे करता है?
public class PaintingDemo {
public static void main(String[] args) {
final JFrame frame = new JFrame();
final JPanel p = new MyPanel();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
frame.add(p, BorderLayout.CENTER);
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
new Thread("MyThread") {
public void run() {
while (true) {
// Below statements are important to show the difference
p.repaint();
p.paintImmediately(p.getBounds());
try {
Thread.sleep(1000);
} catch(Exception e) {}
}
}
}.start();
}
}
class MyPanel extends JPanel {
@Override
public void paint(Graphics g) {
System.out.println("paint() called in "+ Thread.currentThread().getName());
super.paint(g);
}
}
उत्पादन यह ज्ञात है कि पेंटिंग EDT में किया जाता है जब रीपेंट() की जो धागे से यह कहा जाता है, भले ही शुरू हो जाती है से - तो कोई समस्या नहीं। लेकिन, पेंट के मामले में तुरंत() - पेंटिंग उसी धागे में होती है जिससे इसे कहा जाता है।
एक ऐसे मामले पर विचार करें जहां ईडीटी एक घटक की स्थिति बदल रहा है और दूसरा धागा (जिसमें से पेंट तुरंत() लगाया जाता है) एक ही घटक को चित्रित कर रहा है।
मेरे प्रश्न: paintImmediately() के मामले में, कैसे घटना डिस्पैचर थ्रेड (EDT) और अन्य धागे के बीच तुल्यकालन नियंत्रित किया जाता है?
Component c = this;
Component parent;
if(!isShowing()) {
return;
}
JComponent paintingOigin = SwingUtilities.getPaintingOrigin(this);
if (paintingOigin != null) {
Rectangle rectangle = SwingUtilities.convertRectangle(
c, new Rectangle(x, y, w, h), paintingOigin);
paintingOigin.paintImmediately(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
return;
}
while(!c.isOpaque()) {
parent = c.getParent();
if(parent != null) {
x += c.getX();
y += c.getY();
c = parent;
} else {
break;
}
if(!(c instanceof JComponent)) {
break;
}
}
if(c instanceof JComponent) {
((JComponent)c)._paintImmediately(x,y,w,h);
} else {
c.repaint(x,y,w,h);
}
तो, जब तक कि यह एक JComponent
नहीं है, आप _paintImmediately()
जो paint(Graphics)
बुला समाप्त होता है बुला अंत स्टैक ट्रेस पता चलता है के रूप में:
+1 आपने इसे खींचा। मुझे आश्चर्य है कि क्यों 'JComponent' दस्तावेज़ संदर्भ' पेंट तुरंत() 'और 'repaint (..)' जहां स्रोत अलग है। मुझे आपके स्निपेट में हालांकि पूछना चाहिए कि हम कभी भी 'जेकंपोनेंट' के 'पेंट (..)' को ओवरराइड नहीं करेंगे, तो आपने 'पेंट कॉम्पोनेंट' का उपयोग क्यों नहीं किया (यह अभी भी परिणाम पुन: पेश करता है)? और एक और सवाल क्यों 'नींद (int milis) बढ़ाना क्यों टक्कर में वृद्धि नहीं करेगा? और आप ईडीटी के अलावा किसी थ्रेड से 'पेंट तुरंत' क्यों कहते हैं, (क्योंकि मुझे एक बार ईडीटी पर कॉल नहीं किया जाता है, कोई शून्य नहीं होगा)? –
धन्यवाद @Guillaume इसे अपने आप को आजमाने और अपने शोध को साझा करने के लिए।मैं मानता हूं कि पेंट का उपयोग करने के कई कारण नहीं हैं() लेकिन मैं बस यह समझने की कोशिश कर रहा था कि "यह कैसे काम करता है?" चूंकि जावाडोक कहता है ... "यह विधि तब उपयोगी होती है जब किसी को वर्तमान घटना प्रेषित होने पर डिस्प्ले अपडेट करने की आवश्यकता होती है।" साथ ही, यह विधि सार्वजनिक है और इसकी चेतावनी के बारे में कहीं भी कोई चेतावनी नहीं दी गई है; कम से कम जावाडोक भ्रामक है। अब मैं पेंट को तुरंत समझता हूं() को ईडीटी के भीतर बुलाया जाना चाहिए और यह रीडेंट() के विपरीत थ्रेड-सुरक्षित नहीं है। – Learner
@DavidKroukamp बिल्कुल 'पेंट कॉम्पोनेंट' की बजाय 'पेंट' को ओवरराइड करने का कोई अच्छा कारण नहीं है, मैंने सोचा कि यह देखने के प्रयास में कि' पेंट तुरंत 'क्यों' पेंट 'कहता है, स्टैक कॉल में' पेंट कॉम्पोनेंट 'को अतिरिक्त कॉल जोड़ना अनावश्यक था और मनाए गए परिणाम वही बने रहेंगे। तो जानकारी से किसी भी "शोर" को हटाने के लिए और अधिक था, और जैसा कि मैंने अपने स्निपेट से पहले कहा था, यह स्विंग का उपयोग करने के लिए उचित तरीका नहीं दिखाता है। चीयर्स ;-) –