2014-07-21 66 views
0

我已经编写了允许拖放到画布上的代码。在“放下”时,画布上将绘制一个RectangleFigure。问题是,当我第二次放置在画布上时,屏幕上会创建第一个放置元素的另一个副本。同样,第三次,前两个元素被重新创建(我们知道这是真实的,因为如果从原始位置拖动其中一个元素,您可以看到它下面的重新创建的元素)有人可以告诉我如何防止这种娱乐发生? *我已加入的短片可测试的代码说明以前创建的元素在创建新元素时的娱乐SWT Draw2d

import org.eclipse.draw2d.ColorConstants; 
import org.eclipse.draw2d.Figure; 
import org.eclipse.draw2d.IFigure; 
import org.eclipse.draw2d.LightweightSystem; 
import org.eclipse.draw2d.MouseEvent; 
import org.eclipse.draw2d.MouseListener; 
import org.eclipse.draw2d.MouseMotionListener; 
import org.eclipse.draw2d.RectangleFigure; 
import org.eclipse.draw2d.geometry.Dimension; 
import org.eclipse.draw2d.geometry.Point; 
import org.eclipse.draw2d.geometry.Rectangle; 
import org.eclipse.swt.SWT; 


import org.eclipse.swt.dnd.DND; 
import org.eclipse.swt.dnd.DragSource; 
import org.eclipse.swt.dnd.DragSourceEvent; 
import org.eclipse.swt.dnd.DragSourceListener; 
import org.eclipse.swt.dnd.DropTarget; 
import org.eclipse.swt.dnd.DropTargetEvent; 
import org.eclipse.swt.dnd.DropTargetListener; 
import org.eclipse.swt.dnd.TextTransfer; 
import org.eclipse.swt.dnd.Transfer; 
import org.eclipse.swt.events.PaintEvent; 
import org.eclipse.swt.events.PaintListener; 
import org.eclipse.swt.graphics.GC; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 
import org.eclipse.swt.widgets.Menu; 
import org.eclipse.swt.widgets.Group; 
import org.eclipse.swt.widgets.Canvas; 
import org.eclipse.wb.swt.SWTResourceManager; 
import org.eclipse.swt.widgets.Label; 

/** 
* 
*Shortest complete testable code demonstrating the repeated creation problem 
*/ 
public class RepeatDrop 
{ 
/** 
* Launch the application. 
* 
* @param args 
*/ 

private Shell shell; 
private Display display; 
private Menu menu; 
private Group grpPalette; 
private final Label lblUnicorn; 
private Group grpCanvas; 
private final Canvas canvas; 

public static void main(String args[]) { 
    new RepeatDrop(); 
} 

/** 
* Create the shell. 
* 
* @param display 
*/ 
public RepeatDrop() { 
    display = new Display(); 
    shell = new Shell(display); 
    shell.setText("SWT Application"); 
    shell.setSize(450, 393); 

    Group grpPalette = new Group(shell, SWT.NONE); 
    grpPalette.setText("Palette"); 
    grpPalette.setBounds(0, 0, 88, 325); 

    lblUnicorn = new Label(grpPalette, SWT.BORDER | SWT.HORIZONTAL 
      | SWT.CENTER); 
    lblUnicorn.setText("UNICORN"); 
    // ADDED A FINAL HERE!! 
    lblUnicorn.setAlignment(SWT.CENTER); 
    lblUnicorn.setBounds(10, 24, 68, 53); 

    final Group grpCanvas = new Group(shell, SWT.NONE); 
    grpCanvas.setText("Canvas"); 
    grpCanvas.setBounds(94, 0, 330, 325); 

    canvas = new Canvas(grpCanvas, SWT.NONE); 
    canvas.setBackground(SWTResourceManager.getColor(253, 245, 230)); 
    canvas.setBounds(10, 20, 320, 295); 


    LightweightSystem lws = new LightweightSystem(canvas); // 
    final IFigure panel = new Figure(); // 
    lws.setContents(panel); // 

    DragSource dragSource1 = new DragSource(lblUnicorn, DND.DROP_COPY); 
    Transfer[] transfers1 = new Transfer[] { TextTransfer.getInstance() }; 
    dragSource1.setTransfer(transfers1); 
    dragSource1.addDragListener(new DragSourceListener() { 
     public void dragStart(DragSourceEvent event) { 
      if (lblUnicorn.getText().length() == 0) { 
       event.doit = false; 
      } 
     } 

     public void dragSetData(DragSourceEvent event) { 
      if (TextTransfer.getInstance().isSupportedType (event.dataType)) { 
       event.data = lblUnicorn.getText(); 
      } 
     } 

     public void dragFinished(DragSourceEvent event) { 
     } 
     }); 

    Transfer[] types = new Transfer[] { TextTransfer.getInstance() }; 
    DropTarget dropTarget = new DropTarget(canvas, DND.DROP_COPY 
      | DND.DROP_DEFAULT); 
    dropTarget.setTransfer(types); 



    dropTarget.addDropListener(new DropTargetListener() { 
     public void dragEnter(DropTargetEvent event) { 
      if (event.detail == DND.DROP_DEFAULT) { 
       if ((event.operations & DND.DROP_COPY) != 0) { 
        event.detail = DND.DROP_COPY; 
       } else { 
        event.detail = DND.DROP_NONE; 
       } 
      } 
     } 

     public void dragLeave(DropTargetEvent event) { 
     } 

     public void dragOperationChanged(DropTargetEvent event) { 
     } 

     public void dragOver(DropTargetEvent event) { 
     } 



     public void drop(DropTargetEvent event) { 
     } 


     public void dropAccept(final DropTargetEvent event) 
     { 

      if (TextTransfer.getInstance().isSupportedType(
        event.currentDataType)) { 
       String d = (String) TextTransfer.getInstance() 
         .nativeToJava(event.currentDataType); 

       final String finald= d; 

       GC gc = new GC(canvas); 
       canvas.redraw(); 




       canvas.addPaintListener(new PaintListener() { 
        public void paintControl(PaintEvent e) { 


org.eclipse.swt.graphics.Point droppoint = canvas.toControl(event.x, event.y); 

         //DRAW 2D SECTION 
         RectangleFigure node1 = new RectangleFigure(); 
         Rectangle rect=new Rectangle(droppoint.x, droppoint.y, 20, 20); 
         Rectangle rect2=new Rectangle(droppoint.x, droppoint.y, 100, 25); 
         node1.setBounds(rect); 
         node1.setBackgroundColor(ColorConstants.cyan); 


         org.eclipse.draw2d.Label droppedName= 
           new org.eclipse.draw2d.Label(finald); 
         droppedName.setLocation(new Point(droppoint.x, droppoint.y)); //draw2d. point 
         droppedName.setBounds(rect2); 

         node1.add(droppedName); 
         panel.add(node1); 
         panel.add(droppedName); 

         Dragger fig = new Dragger(node1); 
         Dragger caption = new Dragger(droppedName); 
         //DRAW 2D SECTION 

        } 

       }); 
      } 
     } 
    }); 


    shell.pack(); 
    shell.open(); 

    while (!shell.isDisposed()) { 
     if (!display.readAndDispatch()) { 
      display.sleep(); 
     } 
    } 

} 

static class Dragger extends MouseMotionListener.Stub implements MouseListener 
{ 

     public Dragger(IFigure figure){ 
      figure.addMouseMotionListener(this); 
      figure.addMouseListener(this); 
     } 

     Point last; 
     public void mouseReleased(MouseEvent e){ 
     } 
     public void mouseClicked(MouseEvent e){ 
     } 
     public void mouseDoubleClicked(MouseEvent e){ 
     } 
     public void mousePressed(MouseEvent e){ 
      last = e.getLocation(); 
     } 

     public void mouseDragged(MouseEvent e){ 
      Point p = e.getLocation(); 
      Dimension delta = p.getDifference(last); 
      { 
       last = p; 
       Figure f = ((Figure)e.getSource()); 
       f.setBounds(f.getBounds().getTranslated(delta.width, delta.height)); 
      } 
     } 
} 


} 

回答

0

你的问题是由您添加每次添加一个新的身影时新PaintListener的事实导致的问题。这没有必要。实际上,您根本不需要添加任何PaintListenerLightweightSystem将为您照顾。

这里是你的代码现在工作正常:

public class RepeatDrop 
{ 
    private Shell  shell; 
    private Display  display; 
    private final Label lblUnicorn; 
    private final Canvas canvas; 

    public static void main(String args[]) 
    { 
     new RepeatDrop(); 
    } 

    public RepeatDrop() 
    { 
     display = new Display(); 
     shell = new Shell(display); 
     shell.setText("SWT Application"); 
     shell.setLayout(new GridLayout(2, false)); 

     Group grpPalette = new Group(shell, SWT.NONE); 
     grpPalette.setText("Palette"); 
     grpPalette.setLayout(new GridLayout()); 
     grpPalette.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, true)); 

     lblUnicorn = new Label(grpPalette, SWT.BORDER | SWT.HORIZONTAL | SWT.CENTER); 
     lblUnicorn.setText("UNICORN"); 
     // ADDED A FINAL HERE!! 
     lblUnicorn.setAlignment(SWT.CENTER); 

     final Group grpCanvas = new Group(shell, SWT.NONE); 
     grpCanvas.setText("Canvas"); 
     grpCanvas.setLayout(new GridLayout()); 
     grpCanvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 

     canvas = new Canvas(grpCanvas, SWT.NONE); 
     canvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 

     LightweightSystem lws = new LightweightSystem(canvas); // 
     final IFigure panel = new Figure(); // 
     lws.setContents(panel); // 

     DragSource dragSource1 = new DragSource(lblUnicorn, DND.DROP_COPY); 
     Transfer[] transfers1 = new Transfer[] { TextTransfer.getInstance() }; 
     dragSource1.setTransfer(transfers1); 
     dragSource1.addDragListener(new DragSourceListener() 
     { 
      public void dragStart(DragSourceEvent event) 
      { 
       if (lblUnicorn.getText().length() == 0) 
       { 
        event.doit = false; 
       } 
      } 

      public void dragSetData(DragSourceEvent event) 
      { 
       if (TextTransfer.getInstance().isSupportedType(event.dataType)) 
       { 
        event.data = lblUnicorn.getText(); 
       } 
      } 

      public void dragFinished(DragSourceEvent event) 
      { 
      } 
     }); 

     Transfer[] types = new Transfer[] { TextTransfer.getInstance() }; 
     DropTarget dropTarget = new DropTarget(canvas, DND.DROP_COPY | DND.DROP_DEFAULT); 
     dropTarget.setTransfer(types); 

     dropTarget.addDropListener(new DropTargetListener() 
     { 
      public void dragEnter(DropTargetEvent event) 
      { 
       if (event.detail == DND.DROP_DEFAULT) 
       { 
        if ((event.operations & DND.DROP_COPY) != 0) 
        { 
         event.detail = DND.DROP_COPY; 
        } 
        else 
        { 
         event.detail = DND.DROP_NONE; 
        } 
       } 
      } 

      public void dragLeave(DropTargetEvent event) 
      { 
      } 

      public void dragOperationChanged(DropTargetEvent event) 
      { 
      } 

      public void dragOver(DropTargetEvent event) 
      { 
      } 

      public void drop(DropTargetEvent event) 
      { 
      } 

      public void dropAccept(final DropTargetEvent event) 
      { 

       if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) 
       { 
        String d = (String) TextTransfer.getInstance().nativeToJava(event.currentDataType); 

        org.eclipse.swt.graphics.Point droppoint = canvas.toControl(event.x, event.y); 

        // DRAW 2D SECTION 
        RectangleFigure node1 = new RectangleFigure(); 
        Rectangle rect = new Rectangle(droppoint.x, droppoint.y, 20, 20); 
        Rectangle rect2 = new Rectangle(droppoint.x, droppoint.y, 100, 25); 
        node1.setBounds(rect); 
        node1.setBackgroundColor(ColorConstants.cyan); 

        org.eclipse.draw2d.Label droppedName = new org.eclipse.draw2d.Label(d); 
        droppedName.setLocation(new Point(droppoint.x, droppoint.y)); // draw2d. 
                        // point 
        droppedName.setBounds(rect2); 

        node1.add(droppedName); 
        panel.add(node1); 
        panel.add(droppedName); 

        new Dragger(node1); 
        new Dragger(droppedName); 

        canvas.redraw(); 
       } 
      } 
     }); 

     shell.pack(); 
     shell.setSize(400, 300); 
     shell.open(); 

     while (!shell.isDisposed()) 
     { 
      if (!display.readAndDispatch()) 
      { 
       display.sleep(); 
      } 
     } 
    } 

    static class Dragger extends MouseMotionListener.Stub implements MouseListener 
    { 
     public Dragger(IFigure figure) 
     { 
      figure.addMouseMotionListener(this); 
      figure.addMouseListener(this); 
     } 

     Point last; 

     public void mouseReleased(MouseEvent e) 
     { 
     } 

     public void mouseClicked(MouseEvent e) 
     { 
     } 

     public void mouseDoubleClicked(MouseEvent e) 
     { 
     } 

     public void mousePressed(MouseEvent e) 
     { 
      last = e.getLocation(); 
     } 

     public void mouseDragged(MouseEvent e) 
     { 
      Point p = e.getLocation(); 
      Dimension delta = p.getDifference(last); 
      { 
       last = p; 
       Figure f = ((Figure) e.getSource()); 
       f.setBounds(f.getBounds().getTranslated(delta.width, delta.height)); 
      } 
     } 
    } 
} 

请看看我用Layout S上的方式。它更可靠,并且可以在不同的窗口大小和屏幕分辨率下更好地工作。

请同时阅读:Understanding Layouts in SWT