Java 在创建新元素SWT Draw2d时重新创建以前创建的元素

Java 在创建新元素SWT Draw2d时重新创建以前创建的元素,java,user-interface,drag-and-drop,swt,draw2d,Java,User Interface,Drag And Drop,Swt,Draw2d,我已经编写了允许拖放到画布上的代码。在“放置”时,在画布上的该点绘制一个矩形图形。问题是,当我第二次放到画布上时,屏幕上会出现第一个拖放元素的另一个副本。类似地,第三次,前两个元素被重新创建。(我们知道这一点,这是真的,因为如果你将其中一个元素从其原始位置拖动,你可以看到它下面重新创建的元素)有人能告诉我如何防止这种重新创建发生吗*我添加了简短的可测试代码来说明这个问题 import org.eclipse.draw2d.ColorConstants; import org.eclipse.dr

我已经编写了允许拖放到画布上的代码。在“放置”时,在画布上的该点绘制一个矩形图形。问题是,当我第二次放到画布上时,屏幕上会出现第一个拖放元素的另一个副本。类似地,第三次,前两个元素被重新创建。(我们知道这一点,这是真的,因为如果你将其中一个元素从其原始位置拖动,你可以看到它下面重新创建的元素)有人能告诉我如何防止这种重新创建发生吗*我添加了简短的可测试代码来说明这个问题

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


}

您的问题是由于每次添加新图形时都添加了一个新的
PaintListener
,这是不必要的。事实上,您根本不需要添加任何
PaintListener
。轻量级系统将为您解决这一问题

以下是您的代码,现在运行正常:

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的方式。它更可靠,在不同的窗口大小和屏幕分辨率下工作得更好

请同时阅读: