SWT Java:在没有快速重绘的情况下对画布上的图像进行矩形选择

时间:2016-05-26 11:54:49

标签: java swt

我在画布上有一个图像:

    canvas = new Canvas(top, SWT.V_SCROLL | SWT.H_SCROLL | SWT.NO_REDRAW_RESIZE);
    GridData canvasGridData = new GridData(GridData.VERTICAL_ALIGN_FILL);
    canvasGridData.verticalSpan = 15;
    canvasGridData.horizontalAlignment = GridData.FILL;
    canvasGridData.verticalAlignment = GridData.FILL;
    canvasGridData.grabExcessHorizontalSpace = true;
    canvasGridData.grabExcessVerticalSpace = true;
    canvas.setLayoutData(canvasGridData);
    canvas.addPaintListener(new PaintListener() {
        public void paintControl(PaintEvent e) {
            if (buttonPressed) {
                GC gc = e.gc;
                image = GetMyImagetoDisplay();
                gc.drawImage(image, 10, 10);
            }
        }
    });

按下GUI按钮时,会调用reDraw()并加载图像。

我还有一个用于获取矩形选区的鼠标事件。他们在图像上绘制一个矩形选区:         canvas.addListener(SWT.MouseDown,new Listener(){

        @Override
        public void handleEvent(Event event) {
            startX = event.x;
            startY = event.y;

            drag = true;
        }
    });

    canvas.addListener(SWT.MouseUp, new Listener() {

        @Override
        public void handleEvent(Event event) {
            endX = event.x;
            endY = event.y;

            drag = false;

            canvas.redraw();
        }
    });

    canvas.addListener(SWT.MouseMove, new Listener() {

        @Override
        public void handleEvent(Event event) {


            if(drag)
            {
                endX = event.x;
                endY = event.y;


                canvas.redraw();
            }
        }
    });

    canvas.addListener(SWT.Paint, new Listener() {

        @Override
        public void handleEvent(Event event) {
            if(drag)
            {
                GC gc = event.gc;

                //gc.setBackground(top.getDefault().getSystemColor(SWT.COLOR_BLACK));
                gc.setAlpha(128);

                int minX = Math.min(startX, endX);
                int minY = Math.min(startY, endY);

                int maxX = Math.max(startX, endX);
                int maxY = Math.max(startY, endY);

                int width = maxX - minX;
                int height = maxY - minY;

                gc.fillRectangle(minX, minY, width, height);
            }
        }
    });

问题是,当我将鼠标拖过时,图像会一直闪烁。

你能建议修复吗?

更新

通过将SWT.DOUBLE_BUFFERED传递给Canvas构造函数,它启用了双缓冲!!!

imageCanvas = new Canvas(top, SWT.V_SCROLL | SWT.H_SCROLL | SWT.NO_REDRAW_RESIZE | SWT.DOUBLE_BUFFERED);

2 个答案:

答案 0 :(得分:2)

您似乎正在向同一SWT.Paint添加两个Canvas听众,他们互相竞争。

你的第一个听众描绘了“背景”,第二个描绘了“前景”。你看到的闪烁很可能是他们两个交替画画。

只用一个绘图监听器来考虑这样的事情:

canvas.addListener(SWT.Paint, new Listener() {
    @Override
    public void handleEvent(Event event)
    {
        // paint background

        if(drag)
        {
            // paint foreground
        }
    }
});

如果这不会改变任何内容,请尝试使用SWT.DOUBLE_BUFFERED作为Canvas的样式。

答案 1 :(得分:0)

回答这个问题非常简单!通过将SWT.DOUBLE_BUFFERED传递给Canvas构造函数,它启用了双缓冲!!!

imageCanvas = new Canvas(top, SWT.V_SCROLL | SWT.H_SCROLL | SWT.NO_REDRAW_RESIZE | SWT.DOUBLE_BUFFERED);

这完全消除了闪烁效应