【问题标题】:JavaFX / FXML: Vertical button alongside the entire windowJavaFX / FXML:整个窗口旁边的垂直按钮
【发布时间】:2016-08-13 22:41:38
【问题描述】:

我使用 GridPane 作为舞台的主要场景,布局完全在 FXML 文件中定义。我想在窗口的整个侧面(即,跨越我的 GridPane 的所有行)都有一个按钮,如下所示:

但是我无法让它工作。更准确地说,按钮似乎不会跨越整个高度。我为按钮设置了GridPane.vgrow=ALWAYSmaxHeight="Infinity"GridPane.fillHeight=true,但按钮仍然与其中的文本一样长,并位于侧面的中心。

如何让按钮横跨整个 GridPane?如开头所述,我当然正确设置了GridPane.rowSpan。并不是按钮没有正确放置在 GridPane 中,只是它不会在整个可用的垂直空间中伸展。

请注意,我更喜欢通过 FXML 的解决方案,而不是 Java 代码,因为我不想在我的课程中使用这样的布局代码。

谢谢!

【问题讨论】:

    标签: javafx fxml


    【解决方案1】:

    最简单的方法是使用 css。请按照以下步骤操作:

    要旋转按钮中使用的标签,请使用:

    .button > .text {
        -fx-rotate: 90;
    }
    

    要扩展按钮以使用整个高度,请使用 Infinity 作为首选高度:

    .button {
        -fx-pref-height: Infinity;
        -fx-pref-width: 75;
    }
    

    MCVE

    这是一个例子,它展示了如何使用上面的代码:

    FXML

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.layout.ColumnConstraints?>
    <?import javafx.scene.layout.GridPane?>
    <?import javafx.scene.layout.RowConstraints?>
    <?import javafx.scene.layout.VBox?>
    
    <GridPane styleClass="root" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
       <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
          <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
       </columnConstraints>
       <rowConstraints>
          <RowConstraints minHeight="50.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="50.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="50.0" prefHeight="30.0" vgrow="SOMETIMES" />
       </rowConstraints>
       <children>
          <Button mnemonicParsing="false" text="Button" GridPane.rowSpan="3" />
          <VBox style="-fx-background-color: white;" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" GridPane.vgrow="ALWAYS" />
          <VBox style="-fx-background-color: white;" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" />
          <VBox style="-fx-background-color: white;" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="2" />
       </children>
    </GridPane>
    

    CSS

    root 是分配给 GridPane 的样式类。

    .root {
        -fx-background-color: grey;
        -fx-hgap: 5;
        -fx-vgap: 5;
        -fx-padding: 5;
    }
    
    .root > .button > .text {
        -fx-rotate: 90;
    }
    
    .button {
        -fx-pref-height: Infinity;
        -fx-pref-width: 75;
    }
    

    主要

    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    public class Main extends Application {
    
        @Override
        public void start(final Stage primaryStage) throws Exception {
    
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/grid.fxml"));
            final Parent root = fxmlLoader.load();
            final Scene scene = new Scene(root, 685, 411);
            scene.getStylesheets().add(getClass().getResource("/grid.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    输出

    【讨论】:

      【解决方案2】:

      这是一个很好的问题。很难弄清楚,但这里是场景构建器制作的结果和 FXML 文件:

      <?xml version="1.0" encoding="UTF-8"?>
      
      <?import javafx.scene.control.Button?>
      <?import javafx.scene.control.Label?>
      <?import javafx.scene.layout.AnchorPane?>
      <?import javafx.scene.layout.ColumnConstraints?>
      <?import javafx.scene.layout.GridPane?>
      <?import javafx.scene.layout.RowConstraints?>
      <?import javafx.scene.text.Font?>
      
      <GridPane hgap="20.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" vgap="5.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
        <columnConstraints>
          <ColumnConstraints halignment="CENTER" hgrow="NEVER" maxWidth="100.0" minWidth="50.0" prefWidth="100.0" />
          <ColumnConstraints hgrow="NEVER" maxWidth="1.7976931348623157E308" minWidth="500.0" prefWidth="500.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <Label text="Label" GridPane.columnIndex="1" />
            <Label text="Label" GridPane.columnIndex="1" GridPane.rowIndex="1" />
            <Label text="Label" GridPane.columnIndex="1" GridPane.rowIndex="2" />
            <AnchorPane GridPane.hgrow="ALWAYS" GridPane.rowSpan="3" GridPane.vgrow="ALWAYS">
               <children>
                  <Button contentDisplay="TOP" mnemonicParsing="false" textOverrun="CLIP" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                     <font>
                        <Font size="11.0" />
                     </font>
                     <graphic>
                        <Label minWidth="-Infinity" rotate="90.0" text="Some Text">
                           <font>
                              <Font size="15.0" />
                           </font>
                        </Label>
                     </graphic>
                  </Button>
               </children>
            </AnchorPane>
         </children>
      </GridPane>
      

      这是我所做的: 我将 Gridepane 作为其他控制器的父级,例如它包含 2 列和 3 行,然后我放置锚窗格和索引 (0,0) 并使列跨度保持不变,并将其他组件根据需要放在其他行中,然后我但是锚窗格中的按钮并将所有角的锚窗格的值设置为0(您可以在按钮的布局部分下找到锚窗格约束),然后我删除按钮的文本并将带有文本的标签放在按钮中,最后我旋转了将标签旋转 90 度(您可以在标签布局的转换下找到旋转属性),然后您就得到了您想要的。

      希望我能回答你的问题!

      【讨论】:

      • 嗨阿里,感谢您的努力。但这看起来很黑,而且代码对我来说并没有多大意义。必须有一个更简单、更清洁的解决方案。
      • 它看起来如何被黑了?我做的每一件事都是你想要的,它可以根据你的需要调整大小!!!!
      • 我想了解如何设置它,而不是使用生成的代码。你能解释一下为什么所有这些都是必需的,比如 mnemonicParsing=false 和 textOverrun=CLIP 吗?并且所有 minWidth 和 maxWidth 设置似乎也没有任何意义。在我看来,这不是最好的解决方案
      • 我解释了如何在 java 代码中手动完成,或者您可以使用场景生成器生成类似的 fxml 文件
      【解决方案3】:

      选择垂直按钮

      SceneViewer 中转到布局下拉菜单。

      1.设置minHeight,minWidth,prefWidth,prefHeight,MaxWidth

                  to 
         **USE_COMPUTED_SIZE**
      

      最大高度

                  to
            **MAX_VALUE**
      

      2.Button 必须跨越 GridPane 的所有行。

      3.Button 必须旋转 90 度

      这里还需要注意一些重要的事情。当您在 SceneViewer 中调整列或行的大小时,您设置的大小将是最大大小。

      这可能会增加问题,因为如果窗口增大,GridPane 将不会相应地移动。

      所以选择所有的列和行,并确保最大大小设置为

      USE_COMPUTED_SIZE,如果你想让他们成长。我添加这个只是作为建议。

      【讨论】:

      • 抱歉,我不是在寻找解释如何在 GUI 构建器中执行的操作。我想要一个技术解释手动编写什么代码(我讨厌自动生成的代码)
      • 你可以使用SceneBuilder,然后研究生成的fxml。这就是SceneBuilder的目的。我以前是手动写的,但是当你可以拥有兰博基尼时,你就不用400美元的车了。跨度>
      猜你喜欢
      • 2015-07-15
      • 2013-07-25
      • 1970-01-01
      • 2015-01-25
      • 2013-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多