繁体   English   中英

如何在javafx中通过id动态查找FXML变量?

[英]How to find FXML variable by id dynamically in javafx?

我试图创建一个HTML编辑器(出于学习目的),并且试图使程序尽可能地动态。 我想通过其ID查找FXML变量(如TextField),并在按下按钮时检索文本字段中的文本。

我设置了2个Map变量

 public FXMLDocumentController() {
        this.HTMLtags = new HashMap<>();
        HTMLtags.put("pressMeButton", "h2.fx-h2");
        HTMLtags.put("setNewsMessageButton", "p.fx-message");

        this.elementsMap = new HashMap<>();
        elementsMap.put("pressMeButton", "newsTitle");
        elementsMap.put("setNewsMessageButton", "newsMessage");
    }

HTMLtags包含将要编辑的按钮ID和HTML标签。 elementsMap包含假定要从中获取文本的按钮ID和TextView ID。 有点像“将特定按钮绑定到特定文本字段”。

private void changeText(ActionEvent event) throws IOException {
Object source = event.getSource();
                Button clickedButton = (Button) source;
                System.out.println(HTMLtags.get(clickedButton.getId()));
                System.out.println(elementsMap.get(clickedButton.getId()));
                writeToHTML(HTMLtags.get(clickedButton.getId()), elementsMap.get(clickedButton.getId()));
}

上面的方法正确检索需要编辑的按钮ID和HTML标签。

这是在HTML中设置文本的代码

private void writeToHTML(String HTMLTag, String textField) {
        File input = new File(filePath);
        Document doc;
        try {
            doc = Jsoup.parse(input, "UTF-8");

            Element head = doc.select(HTMLTag).first();
            originalText = head.toString();

            TextField textFieldName = new TextField();
            textFieldName.setId(textField);
            head.text(textFieldName.getText());


            System.out.println("Original Text is: " + originalText);
            System.out.println("Modified Text is: " + head);

            Path path = Paths.get(filePath);
            Charset charset = StandardCharsets.UTF_8;

            String content = new String(Files.readAllBytes(path), charset);
            content = content.replaceAll(originalText, head.toString());
            Files.write(path, content.getBytes(charset));

        } catch (IOException ex) {
            Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

问题是我不知道如何在此部分代码中从文本字段中查找和检索文本

TextField textFieldName = new TextField();
                textFieldName.setId(textField);
                head.text(textFieldName.getText());

我想动态地做到这一点,而不必通过@FXML私有TextField声明每个FXML元素“ fx:id的名称”,并通过循环匹配每个元素。

我想这样做类似于通过ActionEvent获取按钮的ID /值。

编辑:这是完整的FXML btw

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

<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.66" xmlns:fx="http://javafx.com/fxml/1" fx:controller="newsletter.editor.FXMLDocumentController">
   <children>
      <ScrollPane fitToWidth="true" prefHeight="800.0" prefWidth="1280.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <content>
            <VBox alignment="CENTER" prefHeight="450.0">
               <children>
                  <HBox alignment="CENTER">
                     <children>
                        <Label alignment="CENTER" minHeight="25.0" minWidth="192.0" prefHeight="50.0" prefWidth="192.0" text="Newsletter Title" wrapText="true">
                           <font>
                              <Font size="18.0" />
                           </font>
                        </Label>
                        <TextField id="newsTitle" fx:id="newsTitle" prefHeight="28.0" prefWidth="180.0" promptText="Write here" HBox.hgrow="ALWAYS" />
                     </children>
                  </HBox>
                  <HBox prefHeight="100.0" prefWidth="200.0">
                     <children>
                        <TextArea fx:id="newsMessage" prefHeight="100.0" prefWidth="766.0" />
                     </children>
                  </HBox>
                  <HBox prefHeight="100.0" prefWidth="200.0" />
                  <HBox prefHeight="100.0" prefWidth="200.0" />
                  <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
                     <children>
                        <Button fx:id="setNewsMessageButton" mnemonicParsing="false" onAction="#changeText" text="MAGIC" />
                        <Button fx:id="pressMeButton" mnemonicParsing="false" onAction="#changeText" text="Press Me for Magic">
                           <HBox.margin>
                              <Insets right="10.0" />
                           </HBox.margin>
                        </Button>
                        <Button fx:id="filePathButton" mnemonicParsing="false" onAction="#filePathSave" text="Select Path">
                           <HBox.margin>
                              <Insets right="10.0" />
                           </HBox.margin>
                        </Button>
                        <Button fx:id="popoverButton" mnemonicParsing="false" onAction="#popOverTrigger" text="PopOver Test">
                           <HBox.margin>
                              <Insets right="10.0" />
                           </HBox.margin>
                        </Button>
                     </children>
                  </HBox>
               </children>
               <padding>
                  <Insets left="20.0" right="20.0" />
               </padding>
            </VBox>
         </content>
      </ScrollPane>
   </children>
</AnchorPane>

您可以执行id查找来找到TextField

Parent parent = getTextFieldParent(); // the Parent (or Scene) that contains the TextFields
TextField textField = (TextField) parent.lookup("#myTextField");
if (textField != null)
    String text = textField.getText();

是的,您需要的方法lookup() 不仅Parent类具有此方法,而且在Panel类中也具有FlowPane,AnchorPane和许多其他类。 这也是Scene类中的此方法。

但! 此方法仅在场景显示后查找。 我现在不知道为什么会这样,但是在Scene show()之前, lookup()仅找到顶层面板。 show()它通过id查找元素,例如scene.lookup("#myId"); 必须输入符号#

lookup()方法也可以按类型查找不带id的元素。

示例: scene.lookup("FlowPane"); (不带#)将在您的.fxml文件中找到第一个FlowPane。 还有scene.lookupAll("ImageView"); 将返回包含场景中所有ImageView元素的大量对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM