初始化或不初始化JavaFX TextField [英] To initialize or to not initialize JavaFX TextField
问题描述
我有一个JavaFX应用程序,它具有调出 FileChooser
的功能。我只想获取所选文件的路径,并在应用程序中将文本字段设置为该路径。我需要重复使用这个功能4次。每次,我将 TextField
ID传递给它所说的 null
的函数,然后得到的NullPointerException
。我已经尝试了几种不同的解决方案,据说为它创建一个 initialize()
,但这也不起作用。
I have a JavaFX app that has the function to bring up a FileChooser
. I just want to get the path of the file selected and set a Text Field to that path in the app. I need to re-use this function 4 times. Every time, I pass the TextField
ID to the function it says it's null
and then get the NullPointerException
. I've tried several different solutions that said to create an initialize()
for it, but that does not work either.
多个来源说要初始化文本字段对象,例如:
Multiple sources said to initialize the text field objects such as:
TextField global_dataset_1 = new TextField();
然后有些消息来源表示不这样做而只是引用.fxml ID;这是我原本想做的......我在开头尝试了第一个并将其包装成 @Override initialize()
。都没有奏效。我在.fxml文件中设置了ID。
Then some sources said don't do that and to just refer to the .fxml IDs; which is what I thought originally to do... I tried the first one above by declaring it in the beginning and wrapping it into an @Override initialize()
. Neither worked. I have the IDs set in the .fxml file.
我还看过: http://tutorials.jenkov.com/javafx/filechooser.html 和 https://examples.javacodegeeks.com/desktop-java/javafx/fxml/javafx-fxml-controller-example/ 和 https:// github .com / mwilchek / Restaurant-Gift-Card-Lookup-App / blob / master / src / controller / NewAccountController.java
以下是我所拥有的:
Main.java
package views;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
public static Stage primaryStage = new Stage();
@Override
public void start(Stage primaryStage) throws IOException{
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
primaryStage.setTitle("Configuration Manager");
primaryStage.setScene(new Scene(root, 1100, 700));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
FxmlController.java
package controller;
import javafx.beans.property.SimpleObjectProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Accordion;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.stage.FileChooser;
import java.io.File;
import static views.Main.primaryStage;
public class FxmlController {
@FXML
Accordion mainList;
@FXML
AnchorPane AnchorPane1;
//TextFields are all set to NULL ERROR
@FXML
TextField global_dataset_1;
@FXML
TextField global_dataset_2;
@FXML
TextField global_dataset_3;
@FXML
TextField global_dataset_4;
public void fileChooser1() {
fileChooser(global_dataset_1);
}
public void fileChooser2() {
fileChooser(global_dataset_2);
}
public void fileChooser3() {
fileChooser(global_dataset_3);
}
public void fileChooser4() {
fileChooser(global_dataset_4);
}
public FxmlController(){
}
// Error: For some reason won't pass TextField Object here...
public void fileChooser(TextField field) {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Select Global Dataset");
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("CSV Files", "*.csv"),
new FileChooser.ExtensionFilter("All Files", "*.*"));
File selectedFile = fileChooser.showOpenDialog(primaryStage);
field.appendText(selectedFile.getPath());
}
Main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.String?>
<?import javafx.collections.FXCollections?>
<?import javafx.scene.control.Accordion?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<VBox prefHeight="700.0" prefWidth="1100.0" style="-fx-background-color: white;" stylesheets="@bootstrap3.css" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.FxmlController">
<children>
<MenuBar style="-fx-background-color: #2176ff;" styleClass="context-menu" stylesheets="@bootstrap3.css" >
<menus>
<Menu mnemonicParsing="false" styleClass="menu-item" text="File">
<items>
<MenuItem mnemonicParsing="false" text="New" />
<MenuItem mnemonicParsing="false" text="Open…" />
<Menu mnemonicParsing="false" text="Open Recent" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Close" />
<MenuItem mnemonicParsing="false" text="Save" />
<MenuItem mnemonicParsing="false" text="Save As…" />
<MenuItem mnemonicParsing="false" text="Revert" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Preferences…" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Quit" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
<SplitPane dividerPositions="0.5, 0.5, 0.5" prefHeight="659.0" prefWidth="1100.0" >
<items>
<Accordion id="mainList" prefWidth="384.0">
<panes>
<TitledPane animated="false" styleClass="primary" stylesheets="@bootstrap3.css" text="Global Configurations">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="52.0" prefWidth="393.0" >
<children>
<Label layoutX="14.0" layoutY="15.0" prefHeight="41.0" prefWidth="93.0" text="Year:">
<font>
<Font size="18.0" />
</font>
</Label>
<ChoiceBox id="year" layoutX="405.0" layoutY="21.0" prefWidth="116.0" style="-fx-background-color: #2176ff;" styleClass="primary" stylesheets="@bootstrap3.css" value="2018">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="2018" />
<String fx:value="2019" />
<String fx:value="2020" />
<String fx:value="2021" />
<String fx:value="2022" />
</FXCollections>
</items>
</ChoiceBox>
<Label layoutX="14.0" layoutY="70.0" text="Run Name:">
<font>
<Font size="18.0" />
</font>
</Label>
<Separator layoutX="-3.0" layoutY="54.0" prefHeight="13.0" prefWidth="537.0" />
<TextField id="run_name" layoutX="298.0" layoutY="68.0" prefHeight="32.0" prefWidth="225.0" promptText="Run Name" style="-fx-background-color: #2176ff; -fx-text-fill: white;" styleClass="primary" stylesheets="@bootstrap3.css">
<font>
<Font size="14.0" />
</font>
</TextField>
<Separator layoutX="-2.0" layoutY="109.0" prefHeight="13.0" prefWidth="537.0" />
<Label layoutX="14.0" layoutY="122.0" prefHeight="35.0" prefWidth="140.0" text="Global Datasets" underline="true">
<font>
<Font name="Century" size="18.0" />
</font>
</Label>
<Label layoutX="14.0" layoutY="160.0" text="Dataset 1: ">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="14.0" layoutY="192.0" text="Dataset 2: ">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="14.0" layoutY="227.0" text="Dataset 3: ">
<font>
<Font size="18.0" />
</font>
</Label>
<Label layoutX="14.0" layoutY="263.0" text="Dataset 4: ">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField id="global_dataset_1" cache="true" layoutX="111.0" layoutY="158.0" prefWidth="379.0" promptText="Path to File" styleClass="primary" stylesheets="@bootstrap3.css" />
<Button layoutX="497.0" layoutY="157.0" mnemonicParsing="false" onMouseClicked="#fileChooser1" styleClass="primary" stylesheets="@bootstrap3.css" text="..." />
<TextField id="global_dataset_2" cache="true" layoutX="111.0" layoutY="191.0" prefWidth="379.0" promptText="Path to File" styleClass="primary" stylesheets="@bootstrap3.css" />
<TextField id="global_dataset_3" cache="true" layoutX="111.0" layoutY="227.0" prefWidth="379.0" promptText="Path to File" styleClass="primary" stylesheets="@bootstrap3.css" />
<TextField id="global_dataset_4" cache="true" layoutX="110.0" layoutY="263.0" prefWidth="379.0" promptText="Path to File" styleClass="primary" stylesheets="@bootstrap3.css" />
<Button layoutX="497.0" layoutY="192.0" mnemonicParsing="false" styleClass="primary" stylesheets="@bootstrap3.css" text="..." />
<Button layoutX="497.0" layoutY="226.0" mnemonicParsing="false" styleClass="primary" stylesheets="@bootstrap3.css" text="..." />
<Button layoutX="497.0" layoutY="262.0" mnemonicParsing="false" styleClass="primary" stylesheets="@bootstrap3.css" text="..." />
</children></AnchorPane>
</content>
</TitledPane>
<TitledPane animated="false" styleClass="primary" stylesheets="@bootstrap3.css" text="Annual 1">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</TitledPane>
<TitledPane animated="false" styleClass="primary" stylesheets="@bootstrap3.css" text="Annual 2">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</TitledPane>
</panes>
</Accordion>
<AnchorPane id="AnchorPane1" prefHeight="200.0" prefWidth="200.0" visible="true" />
<AnchorPane id="AnchorPane2" prefHeight="200.0" prefWidth="200.0" visible="false" />
<AnchorPane id="AnchorPane3" prefHeight="200.0" prefWidth="200.0" visible="false" />
</items>
</SplitPane>
</children>
</VBox>
任何帮助都将不胜感激!
Any help would be greatly appreciated!
推荐答案
您在构建FXML文件方面存在错误。在您的代码中,您需要使用 fx:id
设置节点的ID,但您只需 id
。
You have errors with how you've built your FXML file. Within your tags, you need to set the node's ID using fx:id
but you only do id
.
您的 TextField
应更改为:
<TextField fx:id="global_dataset_1" ...
一些附注:
你可能想要使用 field.setText()
代替 appendText()
,除非您打算允许他们选择多个文件并将它们全部列在同一文本字段中。
You may want to use field.setText()
instead of appendText()
unless your intention is to allow them to select multiple files and list them all in the same text field.
此外,在您的控制器类中,您应将节点声明为 private
:
Also, in your controller class, you should declare your nodes as private
:
@FXML
private TextField global_dataset_1;
最后,以公共方式分享您的 primaryStage
字段不是必需的(或推荐)。打开 FileChooser
的另一种方法是从控制器中声明的任何节点获取当前的 Window
:
Lastly, sharing your primaryStage
as a public field is not necessary (or recommended). Another way to open the FileChooser
centered would be to get the current Window
from any node declared in your controller:
File selectedFile = fileChooser.showOpenDialog(
global_dataset_1.getScene().getWindow());
这篇关于初始化或不初始化JavaFX TextField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!