Nano Hash - криптовалюты, майнинг, программирование

Перетаскивание фигур на холсте SWT Draw2D

Я написал код, который позволяет перетаскивать на холст и поддерживает перетаскивание сброшенного рисунка внутри самого холста. Проблема в том, что код, реализующий перетаскивание внутри холста, иногда генерирует исключение 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));
            }
        }
    }
}

Ответы:


1

Хорошо, во-первых, я нашел воспроизводимую процедуру получения NPE:

  1. Перетащите две метки (назовем их A и B) на холст.
  2. Перетащите A через B, не отпуская кнопку мыши.
  3. НПЭ

Хорошо, теперь к происхождению NPE:

Вы полагаетесь на last в своем методе mouseDragged(). Эта переменная сначала устанавливается в mousePressed(). Теперь это обычно должно быть хорошо, но когда вы перетаскиваете A поверх B, фокус каким-то образом меняется с A на B. Однако, поскольку вы на самом деле не нажали на B, срабатывает mouseDragged(), хотя mousePressed() не вызывало NPE.

Теперь есть простой способ решить эту проблему, инициализировав last в конструкторе:

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

    Rectangle bounds = figure.getBounds();

    last = new Point(bounds.x, bounds.y);
}
24.07.2014
  • Большое спасибо! Но что вы подразумеваете под изменением фокуса? Также у меня были случаи до этого исправления, когда на холсте был только один элемент, и попытка перетаскивания вызывала NPE. 24.07.2014
  • @Asher Ну, у тебя всегда есть прямоугольник и текст, верно? Это уже две цифры. Что касается изменения фокуса: разве вы не заметили, что когда вы перетаскиваете фигуру поверх другой, вместо нее перетаскивается другая? 24.07.2014
  • @Asher Смена фокуса - это отдельная проблема. Не стесняйтесь опубликовать новый вопрос об этом. Я помню, что имел дело с этим в прошлом, и я, вероятно, смогу откопать его сегодня. 24.07.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..