简体   繁体   English

SWT Java:在画布上通过矩形选择图像而无需快速重绘

[英]SWT Java: Rectangular Selection over Image on Canvas without rapid repaint

I have an image on a canvas: 我在画布上有一张图片:

    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);
            }
        }
    });

When a GUI button is pressed, reDraw() is called and image is loaded. 当按下GUI按钮时,将调用reDraw()并加载图像。

I also have a mouse events for getting a rectangular selection. 我也有一个获取矩形选择的鼠标事件。 They draw a rectangular selection over the image: canvas.addListener(SWT.MouseDown, new Listener() { 他们在图像上绘制了一个矩形选择: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);
            }
        }
    });

The problem is, that the image keeps flickering as I drag the mouse across. 问题是,当我拖动鼠标时,图像一直闪烁。

Can you suggest a fix? 您可以提出解决办法吗?

Update: 更新:

By passing SWT.DOUBLE_BUFFERED to the Canvas constructor, it enabled double buffering!!! 通过将SWT.DOUBLE_BUFFERED传递给Canvas构造函数,它启用了双重缓冲!

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

Looks like you're adding two SWT.Paint listeners to the same Canvas and they are competing against each other. 好像您要在同一个Canvas添加两个SWT.Paint侦听器,并且它们彼此竞争。

Your first listener paints the "background" and the second one paints the "foreground". 您的第一个听众绘制了“背景”,第二个听众绘制了“前景”。 The flickering you see is most likely the two of them painting alternatingly. 您看到的闪烁很有可能是两个人交替绘画的。

Consider something like this with just one paint listener: 仅使用一个绘画侦听器考虑这样的事情:

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

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

If this doesn't change anything, try using SWT.DOUBLE_BUFFERED as the style of the Canvas . 如果这没有任何改变,请尝试使用SWT.DOUBLE_BUFFERED作为Canvas的样式。

To answer to this was very simple!!! 回答这个问题很简单!!! By passing SWT.DOUBLE_BUFFERED to the Canvas constructor, it enabled double buffering!!! 通过将SWT.DOUBLE_BUFFERED传递给Canvas构造函数,它启用了双重缓冲!

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

This completely removed the flicker effect 这完全消除了闪烁效果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM