Я в процессе кодирования приложения, которое (по существу) имитирует MS Paint; вы можете выбрать инструмент "Карандаш" и нарисовать линию с шагом 3; вы можете выбрать инструмент Marker и нарисовать линию с шагом 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);
});
потому что после очистки Canvas ширина линии хода будет равна 4. Это проблема, потому что, если бы у меня был инструмент карандаша в качестве выбранного инструмента (ширина линии штриха 3), он будет равен 4, пока я не выберу другой инструмент и не вернусь назад к инструменту для карандашей; кроме того, та же концепция применяется, если у меня был инструмент маркера, выбранный во время нажатия кнопки очистки (ширина линии хода 7 будет равна 4, пока я не выберу другой инструмент, а затем снова заберу инструмент маркера).
Я пытаюсь избежать необходимости устанавливать проверку для каждого инструмента и перезагружать ширину линии штриха каждый раз - в то время как это будет работать, это кажется запутанным.
Подумайте о том, чтобы поместить холст в панель и использовать 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 ;
}
EDIT: Я должен был быстро применить знания Swing Canvas к JavaFX. Если вы используете изменяемый размер Canvas в JavaFX, вам все равно нужно сделать это, как описано ниже. Если нет, я бы, вероятно, использовал слойный подход, как описано в учебнике Java от Oracle.
Если я правильно вас понимаю, то, похоже, у вас неправильный подход. Я предполагаю, что вы рисуете в Canvas непосредственно, когда пользователь рисует свой карандаш, например. Это неверно. Canvas может попросить вас перерисовать его в любое время, и вы должны быть к этому готовы.
То есть, сделайте чертежи пользователя в экранном GraphicsContext с собственными настройками, которые вы можете поддерживать в соответствии с инструментами, которые пользователь выбирает. Затем в методе Canvas paint() скопируйте содержимое этого контекста в Canvas. В это время вы также можете добавить свою собственную границу или другие аннотации, если хотите.
Возможно, вы уже используете экранный чертеж и хотите нарисовать свою границу в буфер вне экрана (например, из-за действия "добавить границу" от пользователя). Затем просмотрите методы save() и restore() GraphicsContext. Они позволяют сохранять состояние, изменять настройки, делать чертеж, а затем восстанавливать старое состояние.
Canvas.paint()
.