gpt4 book ai didi

java - 在 JavaFX 中实现撤消/重做

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:40:25 24 4
gpt4 key购买 nike

我正在尝试在 JavaFX 中实现撤消/重做 - 我使用 graphicsContext() 绘制所有形状。我环顾四周,发现 Graphics Context 上有一个 save 方法,但它只是保存属性,而不是 Canvas 的实际形状/状态。解决这个问题的最佳方法是什么?

这是我创建圆圈时的代码片段之一,例如:

 public CircleDraw(Canvas canvas, Scene scene, BorderPane borderPane) {
this.borderPane = borderPane;
this.scene = scene;
this.graphicsContext = canvas.getGraphicsContext2D();

ellipse = new Ellipse();
ellipse.setStrokeWidth(1.0);
ellipse.setFill(Color.TRANSPARENT);
ellipse.setStroke(Color.BLACK);

pressedDownMouse = event -> {
startingPosX = event.getX();
startingPosY = event.getY();
ellipse.setCenterX(startingPosX);
ellipse.setCenterY(startingPosY);
ellipse.setRadiusX(0);
ellipse.setRadiusY(0);
borderPane.getChildren().add(ellipse);

};

releasedMouse = event -> {
borderPane.getChildren().remove(ellipse);
double width = Math.abs(event.getX() - startingPosX);
double height = Math.abs(event.getY() - startingPosY);
graphicsContext.setStroke(Color.BLACK);
graphicsContext.strokeOval(Math.min(startingPosX, event.getX()), Math.min(startingPosY, event.getY()), width, height);
removeListeners();
};

draggedMouse = event -> {
ellipse.setCenterX((event.getX() + startingPosX) / 2);
ellipse.setCenterY((event.getY() + startingPosY) / 2);
ellipse.setRadiusX(Math.abs((event.getX() - startingPosX) / 2));
ellipse.setRadiusY(Math.abs((event.getY() - startingPosY) / 2));

};

}

最佳答案

这里的问题是像这样的信息没有保存在 Canvas 中。此外,没有逆向操作可以让您返回到每个抽奖信息的先前状态。当然,您可以描画相同的椭圆形,但使用背景颜色,但是之前绘图信息中的信息可能已被覆盖,例如如果您正在绘制多个相交的椭圆。

不过,您可以使用命令模式存储绘图操作。这使您可以重绘所有内容。

public interface DrawOperation {
void draw(GraphicsContext gc);
}

public class DrawBoard {
private final List<DrawOperation> operations = new ArrayList<>();
private final GraphicsContext gc;
private int historyIndex = -1;

public DrawBoard(GraphicsContext gc) {
this.gc = gc;
}

public void redraw() {
Canvas c = gc.getCanvas();
gc.clearRect(0, 0, c.getWidth(), c.getHeight());
for (int i = 0; i <= historyIndex; i++) {
operations.get(i).draw(gc);
}
}

public void addDrawOperation(DrawOperation op) {
// clear history after current postion
operations.subList(historyIndex+1, operations.size()).clear();

// add new operation
operations.add(op);
historyIndex++;
op.draw(gc);
}

public void undo() {
if (historyIndex >= 0) {
historyIndex--;
redraw();
}
}

public void redo() {
if (historyIndex < operations.size()-1) {
historyIndex++;
operations.get(historyIndex).draw(gc);
}
}
}

class EllipseDrawOperation implements DrawOperation {

private final double minX;
private final double minY;
private final double width;
private final double height;
private final Paint stroke;

public EllipseDrawOperation(double minX, double minY, double width, double height, Paint stroke) {
this.minX = minX;
this.minY = minY;
this.width = width;
this.height = height;
this.stroke = stroke;
}

@Override
public void draw(GraphicsContext gc) {
gc.setStroke(stroke);
gc.strokeOval(minX, minY, width, height);
}

}

DrawBoard 实例而不是 Canvas 传递给您的类并替换

graphicsContext.setStroke(Color.BLACK);
graphicsContext.strokeOval(Math.min(startingPosX, event.getX()), Math.min(startingPosY, event.getY()), width, height);

drawBoard.addDrawOperation(new EllipseDrawOperation(
Math.min(startingPosX, event.getX()),
Math.min(startingPosY, event.getY()),
width,
height,
Color.BLACK));

undoredo 在历史中移动。

关于java - 在 JavaFX 中实现撤消/重做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40638845/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com