सूत्रण क्या कभी किसी ने शीर्ष जिनमें से स्विंग उपयोगकर्ता इंटरफ़ेस तत्वों जोड़ा जा सकता है पर एक उचित बहु बफ़र प्रतिपादन पर्यावरण निर्माण करने के लिए स्विंग का उपयोग करने की कोशिश की है?JTextFields, समस्याओं
इस मामले में मेरे पास एक पृष्ठभूमि पर एक एनिमेटिंग लाल आयत है। पृष्ठभूमि को हर फ्रेम को अपडेट करने की आवश्यकता नहीं है, इसलिए मैं इसे बुफर्ड इमेज पर प्रस्तुत करता हूं और आयताकार के पिछले स्थान को साफ़ करने के लिए केवल आवश्यक भाग को दोबारा हटा देता हूं। नीचे पूरा कोड देखें, यह पिछले थ्रेड में @trashgod द्वारा दिए गए उदाहरण को बढ़ाता है, here।
अब तक इतना अच्छा है; चिकनी एनीमेशन, कम सीपीयू उपयोग, कोई झिलमिलाहट।
फिर मैं जेपीएलएल में एक जेटीक्स्टफिल्ड जोड़ता हूं (स्क्रीन पर किसी भी स्थिति पर क्लिक करके), और टेक्स्ट बॉक्स के अंदर क्लिक करके उस पर ध्यान केंद्रित करें। आयताकार के पिछले स्थान को साफ़ करना अब प्रत्येक कर्सर झपकी पर विफल रहता है, नीचे दी गई छवि देखें।
मुझे उत्सुकता है कि अगर किसी को यह पता चल जाए कि ऐसा क्यों हो सकता है (स्विंग थ्रेड-सुरक्षित नहीं है? छवि को अतुल्यकालिक रूप से चित्रित किया जा रहा है?) और संभावित समाधानों को किस दिशा में देखना है।
यह, जावा 1,6
JPanel redraw fail http://www.arttech.nl/javaredrawerror.png
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
public class NewTest extends JPanel implements
MouseListener,
ActionListener,
ComponentListener,
Runnable
{
JFrame f;
Insets insets;
private Timer t = new Timer(20, this);
BufferedImage buffer1;
boolean repaintBuffer1 = true;
int initWidth = 640;
int initHeight = 480;
Rectangle rect;
public static void main(String[] args) {
EventQueue.invokeLater(new NewTest());
}
@Override
public void run() {
f = new JFrame("NewTest");
f.addComponentListener(this);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
createBuffers();
insets = f.getInsets();
t.start();
}
public NewTest() {
super(true);
this.setPreferredSize(new Dimension(initWidth, initHeight));
this.setLayout(null);
this.addMouseListener(this);
}
void createBuffers() {
int width = this.getWidth();
int height = this.getHeight();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
buffer1 = gc.createCompatibleImage(width, height, Transparency.OPAQUE);
repaintBuffer1 = true;
}
@Override
protected void paintComponent(Graphics g) {
int width = this.getWidth();
int height = this.getHeight();
if (repaintBuffer1) {
Graphics g1 = buffer1.getGraphics();
g1.clearRect(0, 0, width, height);
g1.setColor(Color.green);
g1.drawRect(0, 0, width - 1, height - 1);
g.drawImage(buffer1, 0, 0, null);
repaintBuffer1 = false;
}
double time = 2* Math.PI * (System.currentTimeMillis() % 5000)/5000.;
g.setColor(Color.RED);
if (rect != null) {
g.drawImage(buffer1, rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, this);
}
rect = new Rectangle((int)(Math.sin(time) * width/3 + width/2 - 20), (int)(Math.cos(time) * height/3 + height/2) - 20, 40, 40);
g.fillRect(rect.x, rect.y, rect.width, rect.height);
}
@Override
public void actionPerformed(ActionEvent e) {
this.repaint();
}
@Override
public void componentHidden(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void componentMoved(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void componentResized(ComponentEvent e) {
int width = e.getComponent().getWidth() - (insets.left + insets.right);
int height = e.getComponent().getHeight() - (insets.top + insets.bottom);
this.setSize(width, height);
createBuffers();
}
@Override
public void componentShown(ComponentEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
JTextField field = new JTextField("test");
field.setBounds(new Rectangle(e.getX(), e.getY(), 100, 20));
this.add(field);
repaintBuffer1 = true;
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
आपके उत्तर के लिए धन्यवाद। यदि आप super.paintComponent (g) जोड़ते हैं और प्रदान किए गए परीक्षण एप्लिकेशन को चलाते हैं, तो आप देखेंगे कि दुर्भाग्यवश यह समाधान नहीं है। जेपीनल की डिफ़ॉल्ट पेंट कॉम्पोनेंट विधि अपनी पृष्ठभूमि को साफ़ करती है, जो पूरे पृष्ठभूमि छवि को फिर से तैयार करना आवश्यक बनाता है, जो ज्यादातर पृष्ठभूमि छवि को पूर्व-प्रस्तुत करने के उद्देश्य को हरा देती है। मेरे पास एक झुकाव है कि केवल आवश्यक क्षेत्र को फिर से निकालना संभव होना चाहिए, लेकिन ऐसा लगता है कि पृष्ठभूमि चित्र को दोबारा बनाने के बजाय टेक्स्टफील्ड को फिर से लिखने के साथ कुछ समस्या है जो इन ड्राइंग कलाकृतियों का कारण बनता है .. – Mattijs
परिशिष्ट के संबंध में: इस में गोता लगाने के लिए समय लेने के लिए बहुत धन्यवाद। मुझे लगता है कि आपका मुद्दा यह है कि ऐसा कोई तरीका नहीं है कि स्वचालित रूप से पुन: प्रयास करने वाले JTextFields super.paintComponent (g) का उपयोग करके सक्रिय रीड्रॉइंग * के बिना सही ढंग से काम करेंगे, सही है। फिर भी super.paintComponent (g) का उपयोग करने का तात्पर्य है कि पूरी विंडो को प्रत्येक एनीमेशन फ्रेम पर फिर से खींचा जाना है, जिससे सीपीयू का उपयोग खिड़की के आकार पर निर्भर करता है, जो मैं रोकना चाहता हूं। तो मेरे प्रश्न का उत्तर दिया गया है, लेकिन मेरी समस्या अभी भी खड़ी है। मैं इसके बारे में एक नई पोस्ट कर दूंगा। – Mattijs
@ मैटिज: सेटऑपाक (झूठा) का उपयोग भरने से बच जाएगा। मैंने पेंट टाइम दिखाने के लिए उदाहरण अपडेट किया है। अंतर काफी है, लेकिन इसे अद्यतनों को प्रबंधित करने के प्रयास के खिलाफ वजन घटाना चाहिए। – trashgod