【发布时间】:2016-05-24 14:49:02
【问题描述】:
我正在使用 UndoFX 和 ReactFX 为我的 2D 形状应用程序实现 Undo/Redo 功能。
问题是当我移动我的形状时,EventStream 会记录移动的每个 X/Y 像素。我只想记录最后一个位置(当用户释放拖动时)。
到目前为止我所尝试的:
而不是使用changesOf(rect.xProperty()).map(c -> new xChange(c)); 和
changesOf(rect.yProperty()).map(c -> new yChange(c));
我创建了一个DoubleProperty x,y,并在释放用户鼠标时将形状 x,y 属性保存到这些变量中。
最后,我将 changesOf 更改为:changesOf(this.x).map(c -> new xChange(c)); 和 changesOf(this.y).map(c -> new yChange(c));
但这不起作用,它的行为和以前一样。
....
private class xChange extends RectangleChange<Double> {
public xChange(Double oldValue, Double newValue) {
super(oldValue, newValue);
}
public xChange(Change<Number> c) {
super(c.getOldValue().doubleValue(), c.getNewValue().doubleValue());
}
@Override void redo() { rect.setX(newValue); }
@Override xChange invert() { return new xChange(newValue, oldValue); }
@Override Optional<RectangleChange<?>> mergeWith(RectangleChange<?> other) {
if(other instanceof xChange) {
return Optional.of(new xChange(oldValue, ((xChange) other).newValue));
} else {
return Optional.empty();
}
}
@Override
public boolean equals(Object other) {
if(other instanceof xChange) {
xChange that = (xChange) other;
return Objects.equals(this.oldValue, that.oldValue)
&& Objects.equals(this.newValue, that.newValue);
} else {
return false;
}
}
}
...
EventStream<xChange> xChanges = changesOf(rect.xProperty()).map(c -> new xChange(c));
EventStream<yChange> yChanges = changesOf(rect.yProperty()).map(c -> new yChange(c));
changes = merge(widthChanges, heightChanges, xChanges, yChanges);
undoManager = UndoManagerFactory.unlimitedHistoryUndoManager(
changes, // stream of changes to observe
c -> c.invert(), // function to invert a change
c -> c.redo(), // function to undo a change
(c1, c2) -> c1.mergeWith(c2)); // function to merge two changes
【问题讨论】:
-
我建议合并相同类型的后续更改(此处移动形状)为一个更改。它在demo 中得到了演示(参见
CenterXChange和CenterYChange中的mergeWith方法)。 -
我刚试过,没有用 :( 再次出现相同的行为!实际上,确切的问题是当我同时水平和垂直移动形状时。如果我将它完全移动到一个方向,那么它的工作原理很好。
-
哇,我刚刚意识到你是创建 UndoFX 的人:D。感谢您的工作伙伴!