【问题标题】:Cannot align text field inside a stack pane无法对齐堆栈窗格内的文本字段
【发布时间】:2019-10-25 18:25:04
【问题描述】:

我有一个StackPane,我需要在其中添加四个文本字段和一个图表。这些文本字段将用于设置图表轴的范围。我选择了StackPane,因为它在稍后包含的停靠窗格中很好地重新缩放(与图表一起)。我没有在VBoxHBox 中嵌入文本字段,因为它们给我后来添加到窗格的缩放矩形(可缩放)带来了麻烦。

除了我无法设置TextFields 和StackPane 边界附近的距离之外,一切正常。我所能控制的只是像pane.setAlignment(upperY, Pos.TOP_LEFT) 这样的一般定位。但这意味着我的两个TextFields 在左下角重叠。任何人都知道如何通过 CSS 或直接在 Java 代码中解决此问题?

我尝试在 CSS 中设置 -fx-alignment。我尝试更改窗格的类型。我尝试在 CSS 等中设置边框插图。

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application
{
    static LineChart<Number, Number> chart; 

    @Override
    public void start(Stage stage) throws Exception 
        {

            TextField upperY = new TextField("upperY");  upperY.getStylesheets().add("css/chart.css"); 
            TextField lowerY = new TextField("lowerY");  lowerY.getStylesheets().add("css/chart.css"); 
            TextField rightX = new TextField("rightX");  rightX.getStylesheets().add("css/chart.css"); 
            TextField leftX = new TextField("leftX");  leftX.getStylesheets().add("css/chart.css"); 


            StackPane pane = new StackPane();
            HBox.setHgrow(pane, Priority.ALWAYS);
            VBox.setVgrow(pane, Priority.ALWAYS);

            pane.setAlignment(upperY, Pos.TOP_LEFT);
            pane.setAlignment(lowerY, Pos.BOTTOM_LEFT);
            pane.setAlignment(rightX, Pos.BOTTOM_RIGHT);
            pane.setAlignment(leftX, Pos.BOTTOM_LEFT);

            chart = new LineChart<>(new NumberAxis(), new NumberAxis());

            pane.getChildren().addAll(chart, upperY, lowerY, leftX, rightX);

            Pane root = new Pane();
            root.getChildren().add(pane);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();
        } // end start

    public static void main(String[] args)
    {
        launch(args);
    }
}
.text-field{
    -fx-font-size: 10pt;
    -fx-min-width: 35;
    -fx-pref-width: 35;
    -fx-max-width: 35;    
    -fx-min-height: 18;
    -fx-pref-height: 18; 
    -fx-max-height: 18;
    -fx-font-family: "Arial Narrow";
    -fx-text-fill: black;
    -fx-alignment: BASELINE_CENTER;
    -fx-padding: -2 2 0 2;  /*   // T R B L*/  
    -fx-background-color: white; 
    -fx-control-inner-background: white;
    -fx-border-color: lightgray;
    -fx-border-insets: 0 0 0 0; 
    -fx-background-insets: 0 0 0 0;
}

我需要将leftX 文本字段向右推,将lowerY 文本字段向上推一点。

【问题讨论】:

  • 如果您知道节点的大小,您可以使用the margin propertyAnchorPane。我想不出为什么这比将多个节点包装在HBox/VBox 中更可取的原因。不知道你的问题是什么......
  • 感谢费边。我现在附上一张照片。在 StackPane 上施加插图/边距的问题在于它减少了图表的可用空间。这不会阻止我的两个文本字段在左下角重叠。我需要一些东西来独立替换每个文本字段
  • 我解决了它,因为你建议将此方法应用为 StackPane.setMargin(textfield, new Insets(1,0,0,20)); // T R B L
  • 阅读 api 文档并了解所有可用布局的行为(在选择最不合适的布局之前)似乎是个好主意;不相关:不要对字段使用静态范围

标签: java javafx alignment


【解决方案1】:

布局类似于GridPane。唯一的问题是,对图表使用列/行跨度会导致图表无法用于计算GridPane 的首选大小。

但是,您可以使用HBoxVBox 分别保存底部和左侧的文本字段,并将VBox 和图表放在第一行,将HBox 放在图表下方的单元格中。

为简单起见,以下示例使用Region 而不是图表,但调整代码以使用不同的节点类型很简单:

private static TextField createTextField(String prompt) {
    TextField tf = new TextField(prompt);
    return tf;
}

@Override
public void start(Stage primaryStage) throws Exception {
    // Using simple region instead of a chart for simplicity here
    Region chart = new Region();
    chart.setStyle("-fx-background-color: red;");
    chart.setPrefSize(300, 300);

    // create textfield container to the left
    Region placeholder = new Region();
    VBox.setVgrow(placeholder, Priority.ALWAYS);
    VBox left = new VBox(
            createTextField("upperY"),
            placeholder,
            createTextField("lowerY"));

    // create textfield container to the bottom
    placeholder = new Region();
    HBox.setHgrow(placeholder, Priority.ALWAYS);
    HBox bottom = new HBox(
            createTextField("leftX"),
            placeholder,
            createTextField("rightX"));

    GridPane container = new GridPane();
    container.add(left, 0, 0);
    container.add(bottom, 1, 1);
    container.add(chart, 1, 0);

    // make sure the row/column containing the chart is the one that grows
    ColumnConstraints cConstraints = new ColumnConstraints();
    cConstraints.setHgrow(Priority.ALWAYS);
    container.getColumnConstraints().addAll(new ColumnConstraints(), cConstraints);

    RowConstraints rConstraints = new RowConstraints();
    rConstraints.setVgrow(Priority.ALWAYS);
    container.getRowConstraints().addAll(rConstraints, new RowConstraints());

    Scene scene = new Scene(container);

    primaryStage.setScene(scene);
    primaryStage.show();
}

【讨论】:

  • @kleopatra 没有理由不这样做。在这种情况下,我确实使用了修饰符,因为这样编译器/IDE 会在我不小心访问非静态成员的情况下报错...
  • 反之亦然:应该有一个令人信服的理由来使用静态 - 我们在 OO 领域,一切都应该是一个实例......
  • OO 领域也需要辅助方法,如果它们与实例无关,我将它们设为静态。你可能会以不同的方式思考这个问题,但我不会。
  • 你知道我对给出坏例子的看法 - 不要不要不要,这是所有新手都会记住的;)这里没有使用辅助方法的理由,所以不要使用......并且即使它是(或似乎是需要的),也很有可能是设计出了问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
  • 2019-09-30
  • 1970-01-01
  • 2011-06-25
  • 2020-07-19
  • 1970-01-01
相关资源
最近更新 更多