【问题标题】:How to align a line between the gap of a gridpane?如何在网格窗格的间隙之间对齐一条线?
【发布时间】:2019-08-30 13:44:13
【问题描述】:

我想知道如何在网格窗格的 VGap/HGap 的间隙之间对齐一条线。

Public class Main extends Application {

    private StackPane root = new StackPane();
    private Scene scene = new Scene(root, 1366, 768);

    @Override
    public void start(Stage primaryStage) {
        GridPane gridPane = new GridPane();
        gridPane.addRow(1, new Button("0 1"), new Button("0 2"), new Button("0 3"));
        gridPane.addRow(2, new Button("1 1"), new Button("1 2"), new Button("1 3"));
        gridPane.addRow(3, new Button("2 1"), new Button("2 2"), new Button("2 3"));
        gridPane.setHgap(20);
        gridPane.setVgap(20);
        gridPane.setAlignment(Pos.CENTER);
        root.getChildren().add(gridPane);

        Separator separator = new Separator(Orientation.HORIZONTAL);
        gridPane.add(separator, 0, 1, 1, GridPane.REMAINING);

        primaryStage.setTitle("Test");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

现在我有一个网格窗格,其中的线条与前缀 X 和 Y 值一起悬空,这在调整窗口大小时显然是无用的。 有没有办法可以将一条线绑定到 H 和 V 间隙之间的中心?

谢谢。

【问题讨论】:

  • 您需要发布您的代码并展示您所拥有的以及您正在努力实现的目标。如果我不得不猜测的话,您可能只需要在节点之间的 GrindPane 单元格中添加那条线。

标签: java javafx


【解决方案1】:

我建议你学习使用 FXML 和 SceneBuilder。在代码中,你需要使用 ColumnConstraints 和 RowConstraints 来实现你所需要的。

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Control;
import javafx.scene.control.Separator;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 *
 * @author blj0011
 */
public class JavaFXTestingGround extends Application
{

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

    private StackPane root = new StackPane();
    private Scene scene = new Scene(root, 400, 400);

    @Override
    public void start(Stage primaryStage)
    {
        GridPane gridPane = new GridPane();
        gridPane.add(new Button("0 0"), 0, 0);
        gridPane.add(new Button("2 0"), 2, 0);
        gridPane.add(new Button("4 0"), 4, 0);

        gridPane.add(new Button("0 2"), 0, 2);
        gridPane.add(new Button("2 2"), 2, 2);
        gridPane.add(new Button("4 2"), 4, 2);

        gridPane.add(new Button("0 4"), 0, 4);
        gridPane.add(new Button("2 4"), 2, 4);
        gridPane.add(new Button("4 4"), 4, 4);

        Separator hSeparatorOne = new Separator(Orientation.HORIZONTAL);
        gridPane.add(hSeparatorOne, 0, 1, 5, 1);
        hSeparatorOne.setPrefHeight(10);
        hSeparatorOne.setMaxWidth(Double.MAX_VALUE);
        //hSeparatorOne.setStyle("-fx-background-color: red;");

        Separator hSeparatorTwo = new Separator(Orientation.HORIZONTAL);
        gridPane.add(hSeparatorTwo, 0, 3, 5, 1);
        hSeparatorTwo.setPrefHeight(10);
        hSeparatorTwo.setMaxWidth(Double.MAX_VALUE);
        //hSeparatorTwo.setStyle("-fx-background-color: red;");

        Separator vSeparatorOne = new Separator(Orientation.VERTICAL);
        gridPane.add(vSeparatorOne, 1, 0, 1, 5);
        vSeparatorOne.setPrefWidth(10);
        vSeparatorOne.setMaxHeight(Double.MAX_VALUE);
        //vSeparatorOne.setStyle("-fx-background-color: red;");

        Separator vSeparatorTwo = new Separator(Orientation.VERTICAL);
        gridPane.add(vSeparatorTwo, 3, 0, 1, 5);
        vSeparatorTwo.setPrefWidth(10);
        vSeparatorTwo.setMaxHeight(Double.MAX_VALUE);
        //vSeparatorTwo.setStyle("-fx-background-color: red;");

        ColumnConstraints columnConstraintsColumnZero = new ColumnConstraints(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE, Control.USE_PREF_SIZE, Priority.SOMETIMES, HPos.CENTER, true);
        ColumnConstraints columnConstraintsSeperatorOne = new ColumnConstraints(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE, Control.USE_PREF_SIZE, Priority.SOMETIMES, HPos.CENTER, true);
        ColumnConstraints columnConstraintsColumnTwo = new ColumnConstraints(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE, Control.USE_PREF_SIZE, Priority.SOMETIMES, HPos.CENTER, true);
        ColumnConstraints columnConstraintsSeperatorThree = new ColumnConstraints(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE, Control.USE_PREF_SIZE, Priority.SOMETIMES, HPos.CENTER, true);
        ColumnConstraints columnConstraintsColumnFour = new ColumnConstraints(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE, Control.USE_PREF_SIZE, Priority.SOMETIMES, HPos.CENTER, true);
        gridPane.getColumnConstraints().addAll(columnConstraintsColumnZero, columnConstraintsSeperatorOne, columnConstraintsColumnTwo, columnConstraintsSeperatorThree, columnConstraintsColumnFour);

        RowConstraints rowConstraintsRowZero = new RowConstraints(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE, Control.USE_PREF_SIZE, Priority.SOMETIMES, VPos.CENTER, true);
        RowConstraints rowConstraintsSeperatorOne = new RowConstraints(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE, Control.USE_PREF_SIZE, Priority.SOMETIMES, VPos.CENTER, true);
        RowConstraints rowConstraintsRowTwo = new RowConstraints(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE, Control.USE_PREF_SIZE, Priority.SOMETIMES, VPos.CENTER, true);
        RowConstraints rowConstraintsSeperatorThree = new RowConstraints(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE, Control.USE_PREF_SIZE, Priority.SOMETIMES, VPos.CENTER, true);
        RowConstraints rowConstraintsRowFour = new RowConstraints(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE, Control.USE_PREF_SIZE, Priority.SOMETIMES, VPos.CENTER, true);
        gridPane.getRowConstraints().addAll(rowConstraintsRowZero, rowConstraintsSeperatorOne, rowConstraintsRowTwo, rowConstraintsSeperatorThree, rowConstraintsRowFour);

        gridPane.setMaxSize(Control.USE_PREF_SIZE, Control.USE_PREF_SIZE);
        root.getChildren().add(gridPane);

        primaryStage.setTitle("Test");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

【讨论】:

  • 正是我需要的。你知道如何设置这些线条的笔画长度吗?我尝试设置样式hSeparatorOne.setStyle("-fx-stroke-width: 30;"); 并更改它的首选项高度会更改行之间的间距。我怎样才能做到这一点?谢谢。
  • 我尝试了这个解决方案,但它只改变了一部分行和列的颜色。这是它的样子 imgur.com/TIV2dq8 我只想让它占据线条之间的所有区域并为该部分着色。
  • 我在度假。我稍后再看。
  • 你好@user3845934。如果此答案解决了您最初的问题,请接受并提出新问题。
【解决方案2】:

除了 gridPane.setGridLinesVisible(true) 之外,您还必须为“真实”项目之间的行或列中的行添加节点。

例如对于水平线,您可能会这样做:

Separator separator = new Separator(Orientation.HORIZONTAL);
gridPane.add(separator, col, row, 1, GridPane.REMAINING);

这是一个可调整大小边框的完整解决方案:

package example.grid;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.DoubleProperty;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;


public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    private Region makeVerticalLine() {
        VBox vb = new VBox();
        vb.setBackground(new Background(new BackgroundFill(Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY)));
        vb.setPrefHeight(1);
        vb.setPrefWidth(1);
        vb.setMaxHeight(Double.MAX_VALUE);
        return vb;
    }

    private Region makeHorizontalLine() {
        HBox hb = new HBox();
        hb.setBackground(new Background(new BackgroundFill(Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY)));
        hb.setPrefHeight(1);
        hb.setPrefWidth(1);
        hb.setMaxWidth(Double.MAX_VALUE);
        return hb;
    }

    private void bindWidths(DoubleProperty width, Region ... regions) {
        for (Region r : regions) {
            r.prefWidthProperty().bind(width);
        }
    }

    private void bindHeights(DoubleProperty height, Region ... regions) {
        for (Region r : regions) {
            r.prefHeightProperty().bind(height);
        }
    }

    @Override
    public void start(Stage stage) throws Exception {
        BorderPane parent = new BorderPane();
        Slider slider = new Slider(1, 100, 3);
        GridPane grid = new GridPane();
        Region h11 = makeHorizontalLine();
        Region h21 = makeHorizontalLine();
        Region h31 = makeHorizontalLine();
        Region h13 = makeHorizontalLine();
        Region h23 = makeHorizontalLine();
        Region h33 = makeHorizontalLine();
        Region h15 = makeHorizontalLine();
        Region h25 = makeHorizontalLine();
        Region h35 = makeHorizontalLine();
        Region v1 = makeVerticalLine();
        Region v2 = makeVerticalLine();

        ColumnConstraints numCol = new ColumnConstraints();
        numCol.setHalignment(HPos.CENTER);
        numCol.setHgrow(Priority.ALWAYS);
        ColumnConstraints sepCol = new ColumnConstraints();
        sepCol.setHgrow(Priority.NEVER);

        RowConstraints numRow = new RowConstraints();
        numRow.setValignment(VPos.CENTER);
        numRow.setVgrow(Priority.ALWAYS);
        RowConstraints sepRow = new RowConstraints();
        sepRow.setVgrow(Priority.NEVER);

        GridPane.setRowSpan(v1, GridPane.REMAINING);
        GridPane.setRowSpan(v2, GridPane.REMAINING);

        grid.addRow(0, new Label("7"), v1, new Label("8"), v2, new Label("9"));
        grid.add(h11,0,1);
        grid.add(h21,2,1);
        grid.add(h31,4,1);
        grid.add(new Label("4"), 0, 2);
        grid.add(new Label("5"), 2, 2);
        grid.add(new Label("6"), 4, 2);
        grid.add(h13,0,3);
        grid.add(h23,2,3);
        grid.add(h33,4,3);
        grid.add(new Label("1"), 0, 4);
        grid.add(new Label("2"), 2, 4);
        grid.add(new Label("3"), 4, 4);
        grid.add(h15,0,5);
        grid.add(h25,2,5);
        grid.add(h35,4,5);
        grid.add(new Label("0"), 2, 6);
        grid.getColumnConstraints().addAll(numCol,sepCol,numCol,sepCol,numCol);
        grid.getRowConstraints().addAll(numRow,sepRow,numRow,sepRow,numRow,sepRow,numRow);

        bindHeights(slider.valueProperty(), h11,h13,h15,h21,h23,h25,h31,h33,h35);
        bindWidths(slider.valueProperty(), v1, v2);

        VBox controls = new VBox(slider);
        parent.setTop(controls);
        parent.setCenter(grid);

        Scene scene = new Scene(parent);
        stage.setScene(scene);
        stage.show();
        Platform.setImplicitExit(true);
    }
}

【讨论】: