我正在使用Draw2d库(没有GEF)开发一个小型图形编辑器。一个要求是,您可以通过使用鼠标拖动来移动数字。只要图之间没有(折线)连接,这就可以正常工作。当我添加一个连接时,所有连接都被正确呈现但是无法移动数字。
以下是显示问题的代码示例:
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();
}
}
当两个图形之间存在连接时,是否有人知道如何使拖动成为可能(渲染拖动连接不是必要的)?
答案 0 :(得分:1)
两个问题:
mouseDragged
函数中,您正在更改Figure
的边界,而不是更改父容器中图形的约束。我进行了以下更改并且有效:
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();
}
但我仍然认为实施存在问题,因为如果你移动鼠标的速度太快,你可以设法摆脱图形并停止移动。我要做的是在父图中听鼠标,当鼠标开始在内部图形上移动时(使用父项Figure.findFigureAt()
)捕获,然后在鼠标移动时移动内部图形。