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

时间:2015-11-29 00:01:30

标签: java html javafx fxml

我正在尝试创建一个HTML编辑器(学习目的),我正在尝试使程序尽可能动态。我希望通过它的id找到FXML变量,如TextField,并在按下按钮时检索文本字段中的文本。

我设置了2个地图变量

 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()));
}

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

以下是在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元素 @FXML私有TextField“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>

2 个答案:

答案 0 :(得分:1)

您可以执行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();

答案 1 :(得分:0)

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

但是!此方法仅在场景显示后查找。我现在不知道为什么发生这种情况,但是在场景show()之前,lookup()仅找到顶层面板。在show()之后,它按ID查找元素,例如scene.lookup("#myId"); 符号#是必需的。

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

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