2

I want to make an application in order to draw forms (rectangle, line, square, arrow) like in paint using Java SWT Canvas. I'm using mouse events (Up, Down and move) to get the canvas Y and X position. And i have a button for each form types that get canvas mouse position and draw the selected form using the mouse events. My problem is, when i draw the first form (Circle, square, line) everything works, but when draw the second, the first erase. How can I make the first form stay on drawn after redraw the canvas?

Variables:

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() and Declaration:

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();
                }
            });
vinistig
  • 21
  • 3

2 Answers2

0

By default controls are filled with current background color each time the SWT.Paint listener is called. You need to turn this off.

Do this by specifying the SWT.NO_BACKGROUND style on the Canvas

compCanvas = new Canvas(mainPanel, SWT.NO_BACKGROUND);

You will also need to fill the background the first time the canvas is drawn.

greg-449
  • 109,219
  • 232
  • 102
  • 145
  • Hi Greg, thanks for your answer. I specify `SWT.NONE` because i set `Canvas` background image on App Launch and before i need to draw the forms above the image, and i need to save it; Setting canvas background code: `compCanvas.setBackground(new Color(Display.getDefault(), 54, 54,54)); compCanvas.setBackgroundImage(canvasBcg); compCanvas.setBackgroundMode(SWT.INHERIT_FORCE);` – vinistig Feb 24 '16 at 19:49
  • Have another way to do that? – vinistig Feb 24 '16 at 19:58
0

Create class shape with x, y, width, height fields

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

After mouse up store your shape in list according to which button is selected

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

In PainListener You MUST redraw all shapes from your list

for(Shape s: shapes) {
    //draw shape s
}
Kuba
  • 517
  • 4
  • 16