Java 在画布上画边框

Java 在画布上画边框,java,canvas,javafx,Java,Canvas,Javafx,我正在编写一个(本质上)模仿MS Paint的应用程序;你可以选择铅笔工具,画一条笔划为3的线;可以选择标记工具并绘制笔划为7的直线,等等 我想在画布上画一个边框。这很简单,是的。然而,用我的其他方法,我能想到的实现这一点的唯一方法是在划定边界后进行大量抽查。有没有一种有效的方法可以在不与已选择工具的笔划/颜色冲突的情况下执行此操作 以下是drawBorder()方法: private void drawBorder(GraphicsContext g) { final double c

我正在编写一个(本质上)模仿MS Paint的应用程序;你可以选择铅笔工具,画一条笔划为3的线;可以选择标记工具并绘制笔划为7的直线,等等

我想在画布上画一个边框。这很简单,是的。然而,用我的其他方法,我能想到的实现这一点的唯一方法是在划定边界后进行大量抽查。有没有一种有效的方法可以在不与已选择工具的笔划/颜色冲突的情况下执行此操作

以下是
drawBorder()
方法:

private void drawBorder(GraphicsContext g) {
    final double canvasWidth = g.getCanvas().getWidth();
    final double canvasHeight = g.getCanvas().getHeight();

    g.setStroke(Color.BLACK);
    g.setLineWidth(4);
    g.strokeRect(0, 0, canvasWidth, canvasHeight);

    //sets the color back to the currently selected ColorPicker color
    g.setStroke(selectedColor);
}
但是,此代码将与我的
clear()
操作冲突

clearTool.setOnAction(e -> {
            graphics.clearRect(0, 0,
                canvas.getWidth(), canvas.getHeight());
            drawBorder(graphics);
        });
因为清除画布后,笔划线宽将为4。这是一个问题,因为如果我选择铅笔工具作为所选工具(笔划线宽为3),它将是4,直到我选择另一个工具并切换回铅笔工具;此外,如果在按下清除按钮时选择了标记工具(笔划线宽7将为4,直到我选择另一个工具,然后重新选择标记工具),同样的概念也适用


我试图避免为每个工具设置一个检查,并让它每次都重置笔划的线宽——虽然这样做可行,但似乎很复杂。

编辑:我很快将Swing Canvas知识应用到JavaFX。如果您在JavaFX中使用了,您仍然需要按照下面所述的方式进行操作。 如果不是的话,我可能会使用Oracle在中描述的层方法


如果我对你的理解正确,那么在我看来你的方法是错误的。例如,我假设当用户绘制铅笔时,您正在直接绘制画布。这是不对的。 画布可以要求您随时重新绘制,您必须为此做好准备

也就是说,用户在屏幕外的GraphicsContext中绘制图形,并使用自己的设置,以便与用户选择的工具保持一致。 然后,在Canvas paint()方法中,将该上下文的内容复制到画布。此时,如果愿意,还可以添加自己的边框或其他注释


可能您已经在使用屏幕外绘制,并且希望将边框绘制到屏幕外缓冲区(例如,由于用户的“添加边框”操作)。然后看看GraphicsContext的save()和restore()方法。它们可以保存状态、更改设置、进行绘图,然后恢复旧状态。

考虑将画布放在窗格中,并使用CSS设置窗格样式。例如:

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class CanvasWithBorderExample extends Application {

    @Override
    public void start(Stage primaryStage) {

        final int SIZE = 400 ;
        Canvas canvas = new Canvas(SIZE, SIZE);

        GraphicsContext gc = canvas.getGraphicsContext2D() ;
        gc.setStroke(Color.RED);
        gc.moveTo(0, 0);
        gc.lineTo(SIZE, SIZE);
        gc.stroke();

        StackPane canvasContainer = new StackPane(canvas);
        canvasContainer.getStyleClass().add("canvas");

        VBox root = new VBox(10, canvasContainer, new Button("Click here"));
        root.setFillWidth(false);
        VBox.setVgrow(canvasContainer, Priority.NEVER);
        root.setAlignment(Pos.CENTER);

        Scene scene = new Scene(root);
        scene.getStylesheets().add("canvas-with-border.css");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
使用canvas-with-border.css:

.canvas {
    -fx-background-color: antiquewhite, white ;
    -fx-background-insets: 0, 20 ;
    -fx-padding: 20 ;
}

有什么地方可以看到这样的例子吗?JavaFX中没有
Canvas.paint()
方法。@James\u D啊,我错了。修改了答案。