2

我在MouseMoveListener合成上使用 a 来更新另一个画布上的图像。基本上,如果用户将 Composite1 拖到他屏幕上的某个位置,每次鼠标移动时都会调用 mouseMoveEventListener,这将获取鼠标的 x,y 位置,使用 截取屏幕截图Awt.robot.captureScreenRegion,并尝试通过调用更新 Canvas1 的图像它的repaint()方法。其目的只是在用户拖动合成时向用户显示合成下的预览。

这就是问题所在。虽然调用了 mouseMove 回调,并且它依次截取屏幕截图并及时调用 repaint 方法,但paintControl()每次鼠标移动时都不会调用画布的实际侦听器方法(侦听其 Paint 事件)。即,如果您拖动合成,然后暂停几秒钟,这将调用重绘方法。但是,如果你只是将它一直拖到屏幕左侧而不暂停,则不会在每次 mousemove 时调用 repaint 方法,它只会在你停止/暂停移动暂停时调用。

有没有解决办法,即每次鼠标移动时是否可以强制发生绘制事件?我应该为重绘/预览创建一个新线程吗?预览外壳和主外壳都是两个独立的外壳。

编辑:绘制图像的方法:

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.
}
4

2 回答 2

1

canvas.update()之后打电话canvas.redraw()

public void update()

强制在此方法返回之前处理小部件的所有未完成的绘制请求。

于 2013-09-25T20:32:08.340 回答
0

找到了解决方案,结果真的很简单!

刚刚改变了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);
}

现在它完美地工作了!

于 2013-09-23T12:49:54.160 回答