Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在画布SWT Draw2D中拖动图形_Java_User Interface_Canvas_Swt_Draw2d - Fatal编程技术网

Java 在画布SWT Draw2D中拖动图形

Java 在画布SWT Draw2D中拖动图形,java,user-interface,canvas,swt,draw2d,Java,User Interface,Canvas,Swt,Draw2d,我已经编写了允许拖放到画布上的代码,并支持在画布本身中拖动拖放的图形。问题在于,在画布中实现拖动的代码偶尔会抛出NullPointerException。我试图孤立这起触发事件,但徒劳。就方法论而言,我也看不出有什么不对劲。我知道这是一个很长的机会,但有人能告诉我正确的方向来解决这个问题吗?非常感谢。我添加了简短的可测试代码,但NPE只是偶尔抛出 public class RepeatDrop { private Shell shell; private Displ

我已经编写了允许拖放到画布上的代码,并支持在画布本身中拖动拖放的图形。问题在于,在画布中实现拖动的代码偶尔会抛出NullPointerException。我试图孤立这起触发事件,但徒劳。就方法论而言,我也看不出有什么不对劲。我知道这是一个很长的机会,但有人能告诉我正确的方向来解决这个问题吗?非常感谢。我添加了简短的可测试代码,但NPE只是偶尔抛出

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

好的,首先,我找到了一个可复制的程序来获得NPE:

  • 将两个标签(我们称之为
    A
    B
    )拖到画布上
  • B
    上拖动
    A
    ,而不释放鼠标按钮
  • NPE
  • 好的,现在来看看NPE的起源:

    您依赖于
    mouseDragged()
    方法中的
    last
    。此变量首先在
    mousePressed()
    中设置。现在这通常是可以的,但是当你把
    A
    拖到
    B
    上时,焦点会从
    A
    变为
    B
    。但是,由于您没有实际单击
    B
    mouseDragged()
    会被激发,尽管
    mousedpressed()
    没有引起NPE

    现在有一种简单的方法可以通过初始化构造函数中的
    last
    来解决此问题:

    public Dragger(IFigure figure)
    {
        figure.addMouseMotionListener(this);
        figure.addMouseListener(this);
    
        Rectangle bounds = figure.getBounds();
    
        last = new Point(bounds.x, bounds.y);
    }
    

    非常感谢你!但你所说的焦点改变是什么意思?在这个修复之前,我也有过这样的例子,画布上只有一个元素,试图拖动它时抛出了一个NPE。@Asher,你总是有矩形和文本,对吗?这已经是两位数了。至于焦点的改变:你没有注意到当你把一个图形拖到另一个图形上时,另一个图形反而被拖走了吗?@Asher焦点的改变是另一个问题。请随意发布一个关于它的新问题。我记得在过去曾经处理过这个问题,今天我可能会把它挖出来。