1

我正在使用 Draw2d 库(没有 GEF)开发一个小型图形编辑器。一项要求是,您可以通过用鼠标拖动图形来移动它们。只要图形之间没有(Polyline-)连接,它就可以正常工作。当我添加一个连接时,一切都正确呈现,但无法移动数字。

这是一个显示问题的代码示例:

public class Main {

    public static void main(String[] args) {
        Display d = new Display();
        final Shell shell = new Shell(d);
        shell.setSize(400, 400);
        shell.setText("Draw2d Test");
        LightweightSystem lws = new LightweightSystem(shell);
        Figure contents = new Figure();
        XYLayout contentsLayout = new XYLayout();
        contents.setLayoutManager(contentsLayout);

        // create figures
        Figure f1 = new TestFigure("Test 1");
        Figure f2 = new TestFigure("Test 2");

        MouseManager mm = new MouseManager();

        // register mouse listeners
        f1.addMouseMotionListener(mm);
        f1.addMouseListener(mm);
        f2.addMouseMotionListener(mm);
        f2.addMouseListener(mm);

        // set constraints to layout manager
        contentsLayout.setConstraint(f1, new Rectangle(10, 10, -1, -1));
        contentsLayout.setConstraint(f2, new Rectangle(200, 200, -1, -1));

        // add to layout manager
        contents.add(f1);
        contents.add(f2);

        // add connection
        // When uncommenting these lines, dragging works fine
        PolylineConnection c = new PolylineConnection();
        c.setSourceAnchor(new ChopboxAnchor(f1));
        c.setTargetAnchor(new ChopboxAnchor(f2));
        c.setConnectionRouter(new ManhattanConnectionRouter());
        contents.add(c);

        lws.setContents(contents);
        shell.open();
        while (!shell.isDisposed()) {
            while (!d.readAndDispatch()) {
                d.sleep();
            }
        }
    }
}

class MouseManager implements MouseMotionListener, MouseListener {
    Figure selection;
    private Point lastDragLocation;

    @Override
    public void mousePressed(MouseEvent me) {
        System.out.println("mouse pressed");
        selection = (Figure) me.getSource();
    }

    @Override
    public void mouseReleased(MouseEvent me) {
        System.out.println("mouse released");
        selection = null;
        lastDragLocation = null;
    }

    @Override
    public void mouseDragged(MouseEvent me) {
        if (lastDragLocation != null && selection != null) {
            int offsetX = me.getLocation().x - lastDragLocation.x;
            int offsetY = me.getLocation().y - lastDragLocation.y;
            int newX = selection.getLocation().x + offsetX;
            int newY = selection.getLocation().y + offsetY;
            System.out.println(String.format("NewX: %d, NewY: %d", newX, newY));
            selection.setBounds(selection.getBounds().getTranslated(offsetX,
                    offsetY));

        }
        lastDragLocation = me.getLocation();
    }

    // [removed empty implementations of the interface for this post]
}

class TestFigure extends RectangleFigure {
    public Color classColor;

    public TestFigure(String name) {
        ToolbarLayout layout = new ToolbarLayout();
        setLayoutManager(layout);
        setOpaque(true);

        classColor = new Color(null, 255, 255, 206);
        setBackgroundColor(classColor);

        Label lbl_name = new Label(name);
        add(lbl_name);
    }

    @Override
    protected void finalize() throws Throwable {
        classColor.dispose();
        super.finalize();
    }
}

有没有人知道当两个图形之间存在连接时如何使拖动成为可能(不必渲染连接的拖动)?

4

1 回答 1

1

两个问题:

  1. mouseDragged函数中,您正在更改Figure的边界,而不是更改父容器中图形的约束。
  2. 您没有重新验证父级。

我进行了以下更改并且它有效:

public void mouseDragged(MouseEvent me) {
  if(lastDragLocation != null && selection != null) {
    int offsetX = me.getLocation().x - lastDragLocation.x;
    int offsetY = me.getLocation().y - lastDragLocation.y;
    int newX = selection.getLocation().x + offsetX;
    int newY = selection.getLocation().y + offsetY;
    System.out.println(String.format("NewX: %d, NewY: %d", newX, newY));
    // selection.setBounds(selection.getBounds().getTranslated(offsetX, offsetY)); <-- this does not work
    selection.getParent().getLayoutManager()
        .setConstraint(selection, selection.getBounds().getTranslated(offsetX, offsetY));
    selection.getParent().revalidate();

  }
  lastDragLocation = me.getLocation();
}

但是我仍然认为实现存在问题,因为如果您以某种方式将鼠标移动得太快,您可以设法摆脱图形并且它停止移动。我要做的是在父图形中听鼠标,捕捉鼠标何时开始在内部图形顶部移动(使用 parents Figure.findFigureAt()),然后在鼠标移动时移动内部图形。

于 2012-07-19T09:08:55.170 回答