Có ai từng cố gắng sử dụng Swing để xây dựng môi trường kết xuất nhiều bộ đệm thích hợp trên đầu trang mà các yếu tố giao diện người dùng Swing có thể được thêm?JTextFields trên đầu trang của bản vẽ hoạt động trên JPanel, vấn đề luồng
Trong trường hợp này, tôi có hình chữ nhật màu đỏ hoạt hình được vẽ lên nền. Nền không cần phải được cập nhật mỗi khung hình vì vậy tôi đưa nó vào BufferedImage và vẽ lại chỉ phần cần thiết để xóa vị trí trước của hình chữ nhật. Xem mã đầy đủ bên dưới, điều này mở rộng ví dụ được đưa ra bởi @trashgod trong một chủ đề trước, here.
Cho đến nay rất tốt; hoạt hình mượt mà, sử dụng CPU thấp, không nhấp nháy.
Sau đó, tôi thêm JTextField vào Jpanel (bằng cách nhấp vào vị trí bất kỳ trên màn hình) và tập trung vào nó bằng cách nhấp vào bên trong hộp văn bản. Xóa vị trí trước của hình chữ nhật hiện không thành công trên mọi nháy mắt, xem hình ảnh bên dưới.
Tôi tò mò liệu có ai có ý tưởng về lý do tại sao điều này có thể xảy ra hay không?
Đây là trên Mac OS 10.5, Java 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
}
}
Cảm ơn trả lời của bạn. Nếu bạn thêm super.paintComponent (g) và chạy ứng dụng thử nghiệm mà tôi đã cung cấp, bạn sẽ thấy rằng rất tiếc đây không phải là giải pháp. Phương thức paintComponent mặc định của JPanel xóa nền của nó, điều này làm cho nó cần thiết để vẽ lại toàn bộ hình nền, chủ yếu là đánh bại mục đích tạo hình nền trước. Tôi có linh cảm vẽ lại chỉ vùng cần thiết, nhưng có vẻ như có một số vấn đề với vẽ lại trường văn bản trong một chuỗi khác so với vẽ lại hình nền gây ra các tạo phẩm vẽ này .. – Mattijs
Về phụ lục: cảm ơn nhiều lần vì đã dành thời gian để đi sâu vào điều này. Tôi nhận ra rằng quan điểm của bạn, là không có cách nào mà JTextFields vẽ lại tự động sẽ hoạt động chính xác cùng với vẽ lại * nếu không có * bằng cách sử dụng super.paintComponent (g), là chính xác. Tuy nhiên sử dụng super.paintComponent (g) ngụ ý rằng toàn bộ cửa sổ phải được vẽ lại trên mọi khung hình động, làm cho việc sử dụng CPU phụ thuộc vào kích thước cửa sổ, đó là những gì tôi muốn ngăn chặn. Vì vậy, câu hỏi của tôi được trả lời, nhưng vấn đề của tôi vẫn còn đứng. Tôi sẽ tạo một bài đăng mới về điều này. – Mattijs
@Mattijs: Sử dụng setOpaque (false) sẽ tránh được việc điền. Tôi đã cập nhật ví dụ để hiển thị thời gian vẽ. Sự khác biệt là đáng kể, nhưng nó phải được cân nhắc chống lại nỗ lực quản lý cập nhật. – trashgod