我正在使用复合上的MouseMoveListener
来更新另一个画布上的图像。基本上,如果用户将 Composite1 拖动到屏幕上的某个位置,则每次鼠标移动时都会调用 mouseMoveEventListener,这将获取鼠标的 x,y 位置,使用 Awt.robot.captureScreenRegion
截取屏幕截图,并尝试通过调用其 repaint()
方法来更新 Canvas1 的图像。目的只是向用户显示拖动复合物时内容的预览。
问题来了。当调用 mouseMove 回调并依次获取屏幕截图并及时调用重绘方法时,画布的实际paintControl()
侦听器方法(侦听其 Paint 事件)不会在每次鼠标移动时调用。即,如果您拖动合成,然后暂停几秒钟,这将调用重绘方法。但是,如果您只是将其一直拖动到屏幕左侧而不暂停,则不会在每次鼠标移动时调用重绘方法,只会在您停止/暂停移动暂停时调用它。
有没有解决方案,即每次鼠标移动时都可以强制发生绘画事件吗?我应该开始一个新线程来重新绘制/预览吗?预览外壳和主外壳都是两个独立的外壳。
编辑:绘制图像的方法:
canvas.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
if (img != null)
e.gc.drawImage(img, 0, 0);
}
});
(在调用 repaint() 之前,图像从 BufferedImage 转换为 Image。从system.out.println日志中,我可以看到所有事情都正确发生,只有paintControl()
中的日志在我停止移动鼠标之前不会打印。
编辑 2:事件处理代码:
public void mouseMove(MouseEvent e)
{
if (e.stateMask == 0)
return;
//Just some wrapper methods to do shell.setLocation(), shell.getBounds().x, shell.getBounds.y
setLocation(getX() + e.x, getY() + e.y);
}
public void controlMoved(ControlEvent e)
{
updatePreview();
}
public void updatePreview()
{
//Just a wrapper around Awt.robot, uses selectionCanvas's toDisplay() to get coordinates, takes
//screenshot, converts it from BufferedImage to Image, and returns.
Image img =
ImgUtility.getScreenShot( selectionCanvas );
this.image = img;
//Upto this point it works fine.
canvas.redraw(); //this calls the preview canvas's redraw method which
//should call the PaintListener previously described, but doesn't.
}
只需在canvas.redraw()
之后调用canvas.update()
。
public void update()
强制在此方法返回之前处理小部件的所有未完成的绘制请求。
找到了解决方案,结果非常简单!
刚刚更改了controlMoved
:
public void controlMoved(ControlEvent e)
{
updatePreview();
}
对此:
public void controlMoved(ControlEvent e)
{
Runnable r = new Runnable()
{
@Override
public void run()
{
updatePreview();
}
};
Display.getDefault().asyncExec(r);
}
现在它完美地工作了!