【问题标题】:JavaFX constraint issues with dynamic pane动态窗格的 JavaFX 约束问题
【发布时间】:2019-01-15 16:37:41
【问题描述】:

下面是主 UI,我在其中动态添加包含名称、作者、描述和按钮的窗格。

在这里,它很好地扩展到可用宽度。

这是我上面 UI 的 FXML 代码

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>


<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: white;" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ResultsUI">
   <children>
      <AnchorPane prefWidth="600.0" style="-fx-background-color: white;" VBox.vgrow="NEVER">
         <children>
            <TextField id="queryOldTF" fx:id="queryOldTF" layoutX="14.0" layoutY="14.0" prefHeight="40.0" prefWidth="518.0" style="-fx-min-height: 40; -fx-border-radius: 50%; -fx-border-color: #007BFF; -fx-background-color: white;" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="68.0" AnchorPane.topAnchor="14.0" />
            <Button id="serachAgainBtn" fx:id="serachAgainBtn" layoutX="532.0" layoutY="14.0" mnemonicParsing="false" onAction="#searchAgain" style="-fx-background-color: #007BFF; -fx-min-height: 40; -fx-min-width: 40; -fx-text-fill: white; -fx-border-radius: 50%; -fx-background-radius: 50%;" text="GO" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0" />
         </children>
         <VBox.margin>
            <Insets />
         </VBox.margin>
      </AnchorPane>
      <AnchorPane prefHeight="700.0" prefWidth="600.0" style="-fx-background-color: white;" VBox.vgrow="ALWAYS">
         <children>
            <ScrollPane id="scrollPane" fx:id="scrollPane" fitToWidth="true" layoutX="1.0" prefHeight="339.0" prefWidth="574.0" style="-fx-background-color: white;" vbarPolicy="ALWAYS" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="1.0" AnchorPane.rightAnchor="1.0" AnchorPane.topAnchor="0.0">
              <content>
                  <AnchorPane prefHeight="206.0" style="-fx-background-color: white;">
                     <children>
                        <TextArea id="descTl" fx:id="descTl" editable="false" layoutY="46.0" prefHeight="111.0" prefRowCount="4" style="-fx-background-color: white;" wrapText="true" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
                           <font>
                              <Font name="Calibri Light" size="12.0" />
                           </font>
                        </TextArea>
                        <Label id="nameTl" fx:id="nameTl" prefHeight="27.0" style="-fx-font-size: 18;" text="Name" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="1.0" AnchorPane.topAnchor="1.0" />
                        <Label id="authorTl" fx:id="authorTl" layoutX="4.0" layoutY="27.0" prefHeight="17.0" style="-fx-font-style: italic;" text="Authors" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" />
                        <Button id="openBtn" fx:id="openBtn" layoutY="164.0" mnemonicParsing="false" style="-fx-background-color: white; -fx-border-color: #007BFF; -fx-border-radius: 25%;" text="Open" AnchorPane.bottomAnchor="14.800000000000011" AnchorPane.leftAnchor="0.0" />
                     </children>
                  </AnchorPane>
              </content>
               <padding>
                  <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
               </padding>
            </ScrollPane>
         </children>
      </AnchorPane>
   </children>
</VBox>

这是我在运行时动态扩展和添加的 FXML 的子部分

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<fx:root xmlns:fx="http://javafx.com/fxml" type="javafx.scene.layout.Pane">
    <Pane id="resPane" fx:id="resPane" prefHeight="200.0" prefWidth="200.0">
        <children>
            <Label id="descTl" fx:id="descTl" layoutX="14.0" layoutY="75.0" text="Description" />
            <Label id="nameTl" fx:id="nameTl" layoutX="14.0" layoutY="14.0" style="-fx-font-size: 18;" text="Name" />
            <Label id="authorTl" fx:id="authorTl" layoutX="14.0" layoutY="49.0" text="Authors" />
            <Button id="openBtn" fx:id="openBtn" layoutX="12.0" layoutY="161.0" mnemonicParsing="false" text="Open" />
        </children>
    </Pane>
</fx:root>

但在动态添加窗格后,我的 UI 如下所示:

这就是我想要实现的目标:

1) 使动态膨胀的窗格动态填充宽度

2) 从 textarea 中移除滚动条(即使在设置首选行属性后实际上也不会移除)并在文本溢出时附加椭圆

3) 从 UI 中移除灰色背景(尽管将所有视图的属性设置为白色背景,但我似乎无法找到 UI 的哪个部分导致 UI 出现灰点)

下面是我的主控制器

public class ResultsUI { @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    @FXML
    private TextField queryOldTF;

    @FXML
    private Button serachAgainBtn;

    @FXML
    private VBox resContainer;

    @FXML
    private ScrollPane scrollPane;

    @FXML
    void searchAgain(ActionEvent event) {
        String query = queryOldTF.getText().toString();
        queryOldTF.setText(query);
        getFromOwn = true;
        initialize();
    }

    private boolean getFromOwn = false;

    @FXML
    void initialize() {
        assert queryOldTF != null : "fx:id=\"queryOldTF\" was not injected: check your FXML file 'Second.fxml'.";
        assert serachAgainBtn != null : "fx:id=\"serachAgainBtn\" was not injected: check your FXML file 'Second.fxml'.";
        assert resContainer != null : "fx:id=\"resContainer\" was not injected: check your FXML file 'Second.fxml'.";
        assert scrollPane != null : "fx:id=\"scrollPane\" was not injected: check your FXML file 'Second.fxml'.";

        System.out.println(MainUI.query);
        if (!getFromOwn)
            queryOldTF.setText(MainUI.query);

        HashMap<Integer, Double> documents = ExtendedBooleanModel.returnRankedDocuments(queryOldTF.getText().toString().trim());
        Map<Integer, Paper> papers = ObjectHandler.getPapersCollection();

        List<MyPane> panes = new ArrayList<>();
        for (int index:
             documents.keySet()) {

            MyPane docPane = new MyPane(papers.get(index).getContent(), papers.get(index).getTitle(), papers.get(index).getAuthor(), papers.get(index).getName());
            panes.add(docPane);
        }

        VBox pane = new VBox();
        pane.getChildren().addAll(panes);

        scrollPane.setContent(pane);
    }
}

下面是动态膨胀窗格的控制器:

public class MyPane extends Pane {

    @FXML
    public TextArea descTl;

    @FXML
    public Label nameTl;

    @FXML
    public Label authorTl;

    public MyPane(String desc, String name, String author, String doc) {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("subFXML.fxml"));
        loader.setRoot(this);
        loader.setController(this);
        try {
            loader.load();

            descTl.setText(desc);
            nameTl.setText(name);
            authorTl.setText(author);
            openBtn.setOnAction(event -> {
                File myFile = new File("pdfs/" + doc.replace(".txt", ".pdf"));
                try {
                    Desktop.getDesktop().open(myFile);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });

        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    @FXML
    private Button openBtn;

    public void setOnAction(EventHandler<ActionEvent> handler) {
        System.out.println("test");
        openBtn.setOnAction(handler);
    }

    public EventHandler<ActionEvent> getOnAction() {
        return openBtn.getOnAction();
    }
}

任何帮助将不胜感激...

【问题讨论】:

  • 你应该使用ListView
  • @Sedrick 我可以在 ListView 中嵌入 TextFields、TextAreas 和自定义的 onclick 按钮侦听器吗?
  • 我打算创建一个答案,但由于 slaw 发布了一个非常好的答案,所以我不会。 Here是你的起点。

标签: java javafx


【解决方案1】:

正如我在您之前的问题中提到的in a comment,我强烈建议您不要使用AnchorPane。您将有更好的时间使用实际上布局他们的孩子(“自动”)的布局。例如,您的主 FXML 文件可以简化为:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" 
      fx:controller="ResultsUI" prefWidth="600" prefHeight="500">

    <HBox spacing="10">
        <padding>
            <Insets topRightBottomLeft="10"/>
        </padding>
        <TextField fx:id="queryOldTF" HBox.hgrow="ALWAYS"/>
        <Button fx:id="searchAgainBtn" text="GO" onAction="#searchAgain"/>
    </HBox>

    <ListView fx:id="resultsListView" VBox.vgrow="ALWAYS"/>

</VBox>

使用此设置,您不必担心绝对定位(例如layoutXArchivePane.rightAnchor 等...)。这也使用ListView 作为suggested by Sedrick;因为ListView 是一个虚拟控件,即使您有很多结果要显示,它也会保持性能。

在控制器中,您可以自定义 ListViewcellFactory 以正确显示您的项目(请参阅 this question)。您还可以将“子部分”FXML 文件(您可能用作单元格图形的文件)简化为:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.VBox?>

<fx:root xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
         type="javafx.scene.layout.VBox">

    <Label fx:id="titleLabel" text="Title"/>
    <Label fx:id="authorsLabel" text="Authors"/>
    <!-- The parent VBox will grow the TextArea horizontally -->
    <TextArea fx:id="descArea" editable="false" wrapText="true" prefRowCount="6"/>
    <Button text="Open" onAction="#openFile"/>

</fx:root>

在上面的两个 FXML 文件中,为简洁起见,我省略了 styles,但将样式分成一个或多个 CSS 文件可能更容易/更清晰/更易于维护。


至于删除TextArea 中的滚动条见this question


您看到的灰色框可能是ScrollPane 的背景,尽管它可能是其他祖先节点,甚至是Scene。由于您的节点没有按照您的需要增长以填充空间,因此祖先节点的背景正在“窥视”。其中一些可以通过修复布局来修复,以便覆盖节点。但是,您可能需要设置某些节点的背景颜色。这将是使用 CSS 最简单的;见JavaFX CSS Reference Guide

在这里使用 Scene Builder 的 CSS Analyzer 可能是一个有用的工具。要显示它,请转到 View &gt; Show CSS Analyzer 或按 Ctrl+6 (Windows)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 2013-07-23
    • 2011-07-06
    • 2015-04-06
    相关资源
    最近更新 更多