我找到了解决办法。
我认为正在发生的事情是:每当需要更新JTextfield(即在每个光标上眨眼)时,JPanel的重写的ploytComponent()就会被调用,但它使用的图形参数与由reploy()调用时不同。因此,在每一个光标闪烁,我的矩形被清除和重新绘制在一个错误的图形实例,留下在屏幕上看到的图形无效。
这说得通吗?如果是的话,这难道不是挥杆带来的奇怪的不便吗?
无论如何,通过保持一个布尔值(activeRedraw)调用的来源,看起来我设法解决了这个问题。因此,我似乎终于找到了一种方法来进行主动绘图,而无需在每一帧上重新绘制整个屏幕区域,这意味着CPU使用率低,与窗口大小无关!
在这里完成代码: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;
boolean activeRedraw = true;
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) {
//super.paintComponent(g);
int width = this.getWidth();
int height = this.getHeight();
if (activeRedraw) {
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);
activeRedraw = false;
}
}
@Override
public void actionPerformed(ActionEvent e) {
activeRedraw = true;
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
}}