我在合成上使用 MouseMoveListener
来更新另一个 Canvas 上的图像。基本上,如果用户将 Composite1 拖动到屏幕上的某个位置,每次鼠标移动时都会调用 mouseMoveEventListener,这将获取鼠标的 x、y 位置,使用 Awt.robot.captureScreenRegion
截取屏幕截图>,并尝试通过调用其 repaint()
方法来更新 Canvas1 的图像。目的只是在用户拖动时向用户展示复合 Material 下的内容的预览。
问题来了。当 mouseMove 回调被调用,它依次截取屏幕截图并及时调用 repaint 方法时, Canvas 的实际 paintControl()
监听器方法(监听其 Paint 事件)并未被调用每次鼠标移动。即,如果您拖动复合 Material ,然后暂停几秒钟,将调用重绘方法。但是,如果您只是将它一直拖到屏幕左侧而没有暂停,则不会在每次鼠标移动时调用重绘方法,它只会在您停止/暂停移动暂停时调用。
是否有解决方案,即是否可以在每次鼠标移动时强制发生 paint 事件?我应该为重新绘制/预览启动一个新线程吗?预览 shell 和主 shell 都是两个独立的 shell。
编辑: 绘制图像的方法:
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()
Forces all outstanding paint requests for the widget to be processed before this method returns.
关于java - 如何在 SWT Canvas 中显示快速变化的图像? (没有快速调用 paintControl() 监听器方法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18952545/