我正在编写一个功能,该功能可以将画布的选定部分移到另一点,这是项目的一部分,该项目包括开发诸如paint之类的程序。
这是应该允许移动的功能的类
public class TraslationTool {
private Canvas canvas;
private GraphicsContext gc;
private List<Canvas> list;
private double x1;
private double y1;
private double x2;
private double y2;
public TraslationTool(List<Canvas> list, double x1, double y1, double x2, double y2) {
canvas = list.get(list.size() - 1);
gc = canvas.getGraphicsContext2D();
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.list = list;
}
public void traslate(double posX, double posY) {
if (posX > 0 && posY > 0 && checkSelection()) {
int width = (int) x2 - (int) x1;
int height = (int) y2 - (int) y1;
Rectangle2D bound = new Rectangle2D(x1, y1, width, height);
SnapshotParameters params = new SnapshotParameters();
params.setViewport(bound);
params.setFill(Color.TRANSPARENT);
WritableImage write = new WritableImage(width, height);
Image image = canvas.snapshot(params, write);
gc.clearRect(x1, y1, width, height);
gc.drawImage(image, posX, posY);
}
}
private boolean checkSelection() {
if(this.x1 == 0 || this.y1 == 0 || this.x2 == 0 || this.y2 == 0) {
return false;
}
if (this.x1 > this.x2) {
double tempX = this.x1;
this.x1 = this.x2;
this.x2 = tempX;
}
if (this.y1 > this.y2) {
double tempY = this.y1;
this.y1 = this.y2;
this.y2 = tempY;
}
return true;
} }
这是控制器处理画布的部分
drawingCanvas.setOnMousePressed(event -> {
Canvas c = new Canvas(drawingCanvasWidth, drawingCanvasHeight);
c.setOnMousePressed(drawingCanvas.getOnMousePressed());
c.setOnMouseDragged(drawingCanvas.getOnMouseDragged());
c.setOnMouseReleased(drawingCanvas.getOnMouseReleased());
c.setOnMouseMoved(drawingCanvas.getOnMouseMoved());
c.setOnMouseExited(drawingCanvas.getOnMouseExited());
try {
if (list.contains(list.get(++counter))) {
for (int i = list.size() - 1; i >= counter; i--) {
list.remove(i);
}
}
} catch (IndexOutOfBoundsException e) {
}
list.add(c);
anchorPane.getChildren().add(c);
gc = c.getGraphicsContext2D();
gc.setLineWidth(size);
x1 = event.getX();
y1 = event.getY();
if (event.getButton() == MouseButton.PRIMARY) {
gc.setStroke(primaryColor);
shapeDrawer.setCanvas(c, primaryColor);
} else if (event.getButton() == MouseButton.SECONDARY) {
gc.setStroke(secondaryColor);
shapeDrawer.setCanvas(c, secondaryColor);
}
Color wantedColor = (Color) gc.getStroke();
if (toolIsPressed) {
if (toolPressed == hboxRubber) {
gc.setStroke(Color.WHITE);
} else if (toolPressed == hboxPencil) {
gc.setLineWidth(0.25 * size);
} else if (toolPressed == hboxDropper) {
DropperTool dropperTool = new DropperTool(list, (int) event.getX(), (int) event.getY());
Color tempColor = dropperTool.getColor();
shapeDrawer.setCanvas(c, tempColor);
if (event.getButton() == MouseButton.PRIMARY) {
shapeDrawer.setCanvas(c, primaryColor);
primaryColor = tempColor;
defColor1.setStyle("-fx-border-color: gray; -fx-background-color: " + hexToRgb(tempColor));
} else if (event.getButton() == MouseButton.SECONDARY) {
shapeDrawer.setCanvas(c, secondaryColor);
secondaryColor = tempColor;
defColor2.setStyle("-fx-border-color: gray; -fx-background-color: " + hexToRgb(tempColor));
}
gc.setStroke(tempColor);
} else if (toolPressed == hboxPolygon) {
if (!polygonIsFirst) {
x1 = x2;
y1 = y2;
} else {
polyX = x1;
polyY = y1;
}
} else if (toolPressed == hboxBucket) {
BucketTool bucketTool = new BucketTool(list, (int) event.getX(), (int) event.getY(), wantedColor);
bucketTool.paint();
}
}
gc.beginPath();
gc.moveTo(x1, y1);
changesMade = true;
});
//Logic for show/unshow the Drawing Grid
hboxGrid.setOnMousePressed(event -> {
if (gridIsPressed) {
gridIsPressed = false;
grid.setGridLinesVisible(gridIsPressed);
} else {
gridIsPressed = true;
grid.setGridLinesVisible(gridIsPressed);
}
});
/*
Handle shapes.
*/
drawingCanvas.setOnMouseReleased(event -> {
x2 = event.getX();
y2 = event.getY();
if (x1 == x2 && y1 == y2 && toolIsPressed) {
return;
}
changesMade = true;
double width = x2 - x1;
double height = y2 - y1;
if (toolPressed == hboxLine) {
shapeDrawer.drawLine(x2, y2);
} else if (toolPressed == hboxRectangle) {
shapeDrawer.drawRectangle(x1, y1, width, height);
} else if (toolPressed == hboxOval) {
shapeDrawer.drawOval(x1, y1, width, height);
} else if (toolPressed == hboxCircle) {
shapeDrawer.drawCircle(x1, y1, width, height);
} else if (toolPressed == hboxSquare) {
shapeDrawer.drawSquare(x1, y1, width, height);
} else if (toolPressed == hboxTriangle) {
shapeDrawer.drawTriangle(x1, y1, x2, y2, width);
} else if (toolPressed == hboxRoundRectangle) {
shapeDrawer.drawRoundRectangle(x1, y1, width, height);
} else if (toolPressed == hboxPolygon) {
if (polygonIsFirst) {
polygonIsFirst = false;
}
if (x2 >= polyX - 10 && x2 <= polyX + 10 && y2 <= polyY + 10 && y2 >= polyY - 10) {
gc.lineTo(polyX, polyY);
gc.stroke();
polygonIsFirst = true;
return;
}
gc.lineTo(x2, y2);
gc.stroke();
} else if (toolPressed == hboxMove) {
TraslationTool move = new TraslationTool(list, x1, y1, x2, y2);
move.traslate(50, 50);
}
});
}
我使用的是画布的分层系统,以启用撤消/重做功能。 为了允许移动功能,我对Canvas的所需部分进行了快照,然后将此快照写入所需的坐标中。问题在于,当我执行代码时,在TraslationTool类上的调用仅创建一个新的Canvas层,而不执行移动功能。 我的想法是在创建新层时出现了问题,但是我不能理解它是什么。抱歉,很长的帖子,请提前解决。
答案 0 :(得分:0)
我已经通过改变方法解决了我的问题。画布移动部分的问题归因于撤消/重做功能的实现(画布的分层系统在渲染WritableImage时产生了问题)。我已经使用This Solution更改了撤消/重做功能的实现,通过这种方式,Class TraslationTool可以工作。
这是我用于翻译画布一部分的代码:
public class MovingTool implements DrawOperation {
private final Canvas canvas;
private double x1;
private double y1;
private double x2;
private double y2;
private final double posX;
private final double posY;
public MovingTool(Canvas canvas, double x1, double y1, double x2, double y2, double posX, double posY) {
this.canvas = canvas;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.posX = posX;
this.posY = posY;
}
@Override
public void draw(GraphicsContext gc) {
if ((posX >= 0) && (posY >= 0)) {
checkSelection();
int width = (int) x2 - (int) x1;
int height = (int) y2 - (int) y1;
Rectangle2D bound = new Rectangle2D(x1, y1, width, height);
SnapshotParameters params = new SnapshotParameters();
params.setViewport(bound);
params.setFill(Color.TRANSPARENT);
WritableImage write = new WritableImage(width, height);
Image image = canvas.snapshot(params, write);
gc.clearRect(x1, y1, width, height);
gc.drawImage(image, x1, y1);
}
}
private void checkSelection() {
if (this.x1 > this.x2) {
double tempX = this.x1;
this.x1 = this.x2;
this.x2 = tempX;
}
if (this.y1 > this.y2) {
double tempY = this.y1;
this.y1 = this.y2;
this.y2 = tempY;
}
}}