【发布时间】:2011-04-14 03:38:56
【问题描述】:
以前没有这样做过,所以显然我很烂。在这里,当前鼠标位置周围的 64 像素在窗体上被绘制得更大一些。问题是,它有点“慢”,我不知道从哪里开始修复。
除此之外,我还创建了一个线程,它会在完成后不断调用更新图形和类似文本的一点 fps,以显示绘制的速度有多快。
图片示例:(图片来自 Eclipse 中的字母“a”)
代码示例:
@SuppressWarnings("serial")
public static class AwtZoom extends Frame {
private BufferedImage image;
private long timeRef = new Date().getTime();
Robot robot = null;
public AwtZoom() {
super("Image zoom");
setLocation(new Point(640, 0));
setSize(400, 400);
setVisible(true);
final Ticker t = new Ticker();
this.image = (BufferedImage) (this.createImage(320, 330));
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
t.done();
dispose();
}
});
try {
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
t.start();
}
private class Ticker extends Thread {
public boolean update = true;
public void done() {
update = false;
}
public void run() {
try {
while (update == true) {
update(getGraphics());
// try {
// Thread.sleep(200);
// } catch (InterruptedException e) {
// e.printStackTrace();
// return;
// }
}
} catch (Exception e) {
update=false;
}
}
}
public void update(Graphics g) {
paint(g);
}
boolean isdone = true;
public void paint(Graphics g) {
if (isdone) {
isdone=false;
int step = 40;
Point p = MouseInfo.getPointerInfo().getLocation();
Graphics2D gc = this.image.createGraphics();
try {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
gc.setColor(robot.getPixelColor(p.x - 4 + x, p.y
- 4 + y));
gc.fillOval(x * step, y * step, step - 3, step - 3);
gc.setColor(Color.GRAY);
gc.drawOval(x * step, y * step, step - 3, step - 3);
}
}
} catch (Exception e) {
e.printStackTrace();
}
gc.dispose();
isdone = true;
iter++;
}
g.drawImage(image, 40, 45, this);
g.setColor(Color.black);
StringBuilder sb = new StringBuilder();
sb.append(iter)
.append(" frames in ")
.append((double) (new Date().getTime() - this.timeRef) / 1000)
.append("s.");
g.drawString(sb.toString(), 50, 375);
}
int iter = 0;
}
所做的更改:
* 添加“gc.dispose();”
* 添加了“isdone”,因此不能更快地调用重绘,那么它应该。
* 添加 this link 到 thrashgod 源代码重写
* 添加 this link 到 thrashgod 源代码重写 2
【问题讨论】:
-
为什么不只在鼠标移动事件发生时重绘?
-
你为什么在
paint期间调用垃圾收集器? -
真的很想绘制鼠标附近的东西,并希望它可以在鼠标所在的任何地方工作(尽可能快,即使在视频上)。我假设你发现的问题是,paint 事件也可以不被线程 t 调用。我认为,这不是问题,但无论如何添加“isdone”来解决它。
-
一些通用指针 (1) 你应该只在 Event Dispatch Thread 上绘画,但你似乎是在 Ticker Thread 上绘画。 (2) 您不应该需要“done”变量,因为单个线程不能同时运行两位代码。 (3) 尝试将其分成一个模型(一个 8*8 的颜色数组)和视图(您要求在模型更新时重新绘制)。 (4) 考虑使用 repaint(x, y, w, h),它指定了一个剪切区域,因此重绘速度更快。
-
我做了一些分析——robot.getPixelColor(..) 在我的 Mac 上很慢。这是开始寻找改进的好地方