如何创建背景网格
How to create a background grid
我想创建一个网格作为我的 JavaFX 应用程序的背景。我目前的解决方案是在 canvas 上绘制一个矩形,从中创建一个图像图案并将其设置为填充。
问题:有没有更好的方法来解决这个问题,最好通过 CSS?
当前版本:
public class BackgroundGrid extends Application {
double gridSize = 20;
@Override
public void start(Stage primaryStage) {
Scene scene = new Scene(new Group(), 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
scene.setFill(createGridPattern());
}
public ImagePattern createGridPattern() {
double w = gridSize;
double h = gridSize;
Canvas canvas = new Canvas(w, h);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setStroke(Color.BLACK);
gc.setFill(Color.LIGHTGRAY.deriveColor(1, 1, 1, 0.2));
gc.fillRect(0, 0, w, h);
gc.strokeRect(0, 0, w, h);
Image image = canvas.snapshot(new SnapshotParameters(), null);
ImagePattern pattern = new ImagePattern(image, 0, 0, w, h, false);
return pattern;
}
public static void main(String[] args) {
launch(args);
}
}
非常感谢!
编辑:为了获得清晰的网格线,只需使用
gc.strokeRect(0.5, 0.5, w, h);
我认为这在 CSS 中是行不通的,不是吗?
获得真正清晰的网格线的建议并不适用于所有系统。在 Retina 显示屏上,您必须使用 0.5 的线宽,然后从整数线坐标偏移 0.25。所以在实践中你必须确定你的应用程序是在什么系统上 运行 然后使用不同的线宽和偏移量。
这是从旧 Oracle forum post 转载的答案。
基于 GridPane 的方法
几种方法(基于GridPane布局):
- 单个单元格的样式边框(并确保它们填充
他们的整个网格位置)或
- style 整体背景
网格在填充整个网格的单元格之间留下间隙
位置如下所示或
- 用线添加新的网格节点然后
为添加的行设置样式。
我为下面的代码选择了方法 2(样式化网格背景)。该示例使用内联 CSS 样式(因为我很懒),但它可以(并且更好)使用外部 CSS 样式表来设置网格样式。
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class GridPaneStyle extends Application {
@Override
public void start(final Stage stage) {
// create a grid with some sample data.
GridPane grid = new GridPane();
grid.addRow(0, new Label("1"), new Label("2"), new Label("3"));
grid.addRow(1, new Label("A"), new Label("B"), new Label("C"));
// make all of the Controls and Panes inside the grid fill their grid cell,
// align them in the center and give them a filled background.
// you could also place each of them in their own centered StackPane with
// a styled background to achieve the same effect.
for (Node n : grid.getChildren()) {
if (n instanceof Control) {
Control control = (Control) n;
control.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
control.setStyle("-fx-background-color: cornsilk; -fx-alignment: center;");
}
if (n instanceof Pane) {
Pane pane = (Pane) n;
pane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
pane.setStyle("-fx-background-color: cornsilk; -fx-alignment: center;");
}
}
// style the grid so that it has a background and gaps around the grid and between the
// grid cells so that the background will show through as grid lines.
grid.setStyle("-fx-background-color: palegreen; -fx-padding: 2; -fx-hgap: 2; -fx-vgap: 2;");
// turn layout pixel snapping off on the grid so that grid lines will be an even width.
grid.setSnapToPixel(false);
// set some constraints so that the grid will fill the available area.
ColumnConstraints oneThird = new ColumnConstraints();
oneThird.setPercentWidth(100 / 3.0);
oneThird.setHalignment(HPos.CENTER);
grid.getColumnConstraints().addAll(oneThird, oneThird, oneThird);
RowConstraints oneHalf = new RowConstraints();
oneHalf.setPercentHeight(100 / 2.0);
oneHalf.setValignment(VPos.CENTER);
grid.getRowConstraints().addAll(oneHalf, oneHalf);
// layout the scene in a stackpane with some padding so that the grid is centered
// and it is easy to see the outer grid lines.
StackPane layout = new StackPane();
layout.setStyle("-fx-background-color: whitesmoke; -fx-padding: 10;");
layout.getChildren().addAll(grid);
stage.setScene(new Scene(layout, 600, 400));
stage.show();
// can be uncommented to show the grid lines for debugging purposes, but not particularly useful for styling purposes.
//grid.setGridLinesVisible(true);
}
public static void main(String[] args) {
launch();
}
}
备用 Canvas 基于方法
另请参阅 FXExperience 博客 post Resizable Grid using Canvas。
您也可以使用 CSS 来完成。这就是您所需要的:
.root {
-fx-background-color: #D3D3D333,
linear-gradient(from 0.5px 0.0px to 10.5px 0.0px, repeat, black 5%, transparent 5%),
linear-gradient(from 0.0px 0.5px to 0.0px 10.5px, repeat, black 5%, transparent 5%);
}
0.5px 的偏移量解决了从 0px 设置为 10px 时的一些错误行为,并且一些线条用两个像素而不是一个像素渲染:
我想创建一个网格作为我的 JavaFX 应用程序的背景。我目前的解决方案是在 canvas 上绘制一个矩形,从中创建一个图像图案并将其设置为填充。
问题:有没有更好的方法来解决这个问题,最好通过 CSS?
当前版本:
public class BackgroundGrid extends Application {
double gridSize = 20;
@Override
public void start(Stage primaryStage) {
Scene scene = new Scene(new Group(), 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
scene.setFill(createGridPattern());
}
public ImagePattern createGridPattern() {
double w = gridSize;
double h = gridSize;
Canvas canvas = new Canvas(w, h);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setStroke(Color.BLACK);
gc.setFill(Color.LIGHTGRAY.deriveColor(1, 1, 1, 0.2));
gc.fillRect(0, 0, w, h);
gc.strokeRect(0, 0, w, h);
Image image = canvas.snapshot(new SnapshotParameters(), null);
ImagePattern pattern = new ImagePattern(image, 0, 0, w, h, false);
return pattern;
}
public static void main(String[] args) {
launch(args);
}
}
非常感谢!
编辑:为了获得清晰的网格线,只需使用
gc.strokeRect(0.5, 0.5, w, h);
我认为这在 CSS 中是行不通的,不是吗?
获得真正清晰的网格线的建议并不适用于所有系统。在 Retina 显示屏上,您必须使用 0.5 的线宽,然后从整数线坐标偏移 0.25。所以在实践中你必须确定你的应用程序是在什么系统上 运行 然后使用不同的线宽和偏移量。
这是从旧 Oracle forum post 转载的答案。
基于 GridPane 的方法
几种方法(基于GridPane布局):
- 单个单元格的样式边框(并确保它们填充 他们的整个网格位置)或
- style 整体背景 网格在填充整个网格的单元格之间留下间隙 位置如下所示或
- 用线添加新的网格节点然后 为添加的行设置样式。
我为下面的代码选择了方法 2(样式化网格背景)。该示例使用内联 CSS 样式(因为我很懒),但它可以(并且更好)使用外部 CSS 样式表来设置网格样式。
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class GridPaneStyle extends Application {
@Override
public void start(final Stage stage) {
// create a grid with some sample data.
GridPane grid = new GridPane();
grid.addRow(0, new Label("1"), new Label("2"), new Label("3"));
grid.addRow(1, new Label("A"), new Label("B"), new Label("C"));
// make all of the Controls and Panes inside the grid fill their grid cell,
// align them in the center and give them a filled background.
// you could also place each of them in their own centered StackPane with
// a styled background to achieve the same effect.
for (Node n : grid.getChildren()) {
if (n instanceof Control) {
Control control = (Control) n;
control.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
control.setStyle("-fx-background-color: cornsilk; -fx-alignment: center;");
}
if (n instanceof Pane) {
Pane pane = (Pane) n;
pane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
pane.setStyle("-fx-background-color: cornsilk; -fx-alignment: center;");
}
}
// style the grid so that it has a background and gaps around the grid and between the
// grid cells so that the background will show through as grid lines.
grid.setStyle("-fx-background-color: palegreen; -fx-padding: 2; -fx-hgap: 2; -fx-vgap: 2;");
// turn layout pixel snapping off on the grid so that grid lines will be an even width.
grid.setSnapToPixel(false);
// set some constraints so that the grid will fill the available area.
ColumnConstraints oneThird = new ColumnConstraints();
oneThird.setPercentWidth(100 / 3.0);
oneThird.setHalignment(HPos.CENTER);
grid.getColumnConstraints().addAll(oneThird, oneThird, oneThird);
RowConstraints oneHalf = new RowConstraints();
oneHalf.setPercentHeight(100 / 2.0);
oneHalf.setValignment(VPos.CENTER);
grid.getRowConstraints().addAll(oneHalf, oneHalf);
// layout the scene in a stackpane with some padding so that the grid is centered
// and it is easy to see the outer grid lines.
StackPane layout = new StackPane();
layout.setStyle("-fx-background-color: whitesmoke; -fx-padding: 10;");
layout.getChildren().addAll(grid);
stage.setScene(new Scene(layout, 600, 400));
stage.show();
// can be uncommented to show the grid lines for debugging purposes, but not particularly useful for styling purposes.
//grid.setGridLinesVisible(true);
}
public static void main(String[] args) {
launch();
}
}
备用 Canvas 基于方法
另请参阅 FXExperience 博客 post Resizable Grid using Canvas。
您也可以使用 CSS 来完成。这就是您所需要的:
.root {
-fx-background-color: #D3D3D333,
linear-gradient(from 0.5px 0.0px to 10.5px 0.0px, repeat, black 5%, transparent 5%),
linear-gradient(from 0.0px 0.5px to 0.0px 10.5px, repeat, black 5%, transparent 5%);
}
0.5px 的偏移量解决了从 0px 设置为 10px 时的一些错误行为,并且一些线条用两个像素而不是一个像素渲染: