使用鼠标事件

时间:2016-02-24 18:51:00

标签: java canvas swt draw draw2d

我想创建一个应用程序,以便使用Java SWT Canvas在paint中绘制表单(矩形,线条,方形,箭头)。我正在使用鼠标事件(向上,向下和移动)来获取画布Y和X的位置。我有一个按钮,每个表单类型获得画布鼠标位置,并使用鼠标事件绘制选定的表单。我的问题是,当我绘制第一个表格(圆形,方形,线条)时,一切正常,但是当绘制第二个表格时,第一个擦除。如何在重绘画布后使第一个表单保持绘制状态?

变量:

private static boolean drag = false;
private Canvas compCanvas;
private Button btnSend, btnAdd,btnFreeHand,btnArrow,btnCircle,btnSquare,btnLine;
private Composite mainPanel;
compCanvas = new Canvas(mainPanel, SWT.NONE);

mouseEvents():

private void mouseEvents(){
    compCanvas.addListener(SWT.MouseDown, new Listener(){
        public void handleEvent(Event e){
            System.out.println("Mouse event on canvas DOWN: X VALUE:"+e.x+"Y VALUE:"+e.y);
            startY = e.y;
            startX = e.x;
            drag = true;
        }
    });

    compCanvas.addListener(SWT.MouseUp, new Listener(){
        public void handleEvent(Event e){
            System.out.println("Mouse event on canvas UP: X VALUE:"+e.x+"Y VALUE:"+e.y);
            endY = e.y;
            endX = e.x;
            drag = false;

            //compCanvas.redraw();
        }
    });

    compCanvas.addListener(SWT.MouseMove, new Listener(){
        public void handleEvent(Event e){
            System.out.println("Mouse event on canvas MOVE: X VALUE:"+e.x+"Y VALUE:"+e.y);
            if(drag){
                endY = e.y;
                endX = e.x;

                compCanvas.redraw();
            }
        }
    });
};

btnSquare.selectionListener()和声明:

btnSquare = new Button(compSendAdd, SWT.NONE);
            btnSquare.setLayoutData(new RowData(25, 25));
            btnSquare.setImage(squareIcon);
            btnSquare.addSelectionListener(new SelectionListener(){
                private void btnSquare(){
                    mouseEvents();
                    //LightweightSystem lws = new LightweightSystem(compCanvas);
                    compCanvas.addListener(SWT.Paint, new Listener(){
                        public void handleEvent(Event e){
                            if(drag){
                                GC gc = e.gc;
                                //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);
                            }
                        }
                    });
                }
                public void widgetSelected(SelectionEvent event) {
                    btnSquare();
                }
                public void widgetDefaultSelected(SelectionEvent event) {
                    btnSquare();
                }
            });

2 个答案:

答案 0 :(得分:0)

默认情况下,每次调用SWT.Paint侦听器时,控件都会以当前背景颜色填充。你需要关闭它。

通过在SWT.NO_BACKGROUND

上指定Canvas样式来执行此操作
compCanvas = new Canvas(mainPanel, SWT.NO_BACKGROUND);

您还需要在第一次绘制画布时填充背景。

答案 1 :(得分:0)

使用x,y,width,height字段创建类形状

class Shape {
    public int x; // coordiates
    public int y;
    public int width;
    public int heigth;
    String type; // "rect" for example
    public Shape(int x, int y, int width, int height, String type) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.heigth = height;
        this.type = type;
    }
}

鼠标按下后,根据选择的按钮将您的形状存储在列表中

List<Shape> shapes = new ArrayList<Shape>();
shapes.add(new Shape(x, y, width, height, getType()));

在PainListener中你必须重新绘制列表中的所有形状

for(Shape s: shapes) {
    //draw shape s
}