我有一个JavaFX应用程序,它具有调出FileChooser
的功能。我只想获取所选文件的路径,并在应用程序中将文本字段设置为该路径。我需要重复使用这个功能4次。每次,我都会将TextField
ID传递给它所说的null
函数,然后获取NullPointerException
。我已经尝试了几种不同的解决方案,据说为它创建initialize()
,但这也不起作用。
多个来源说要初始化文本字段对象,例如:
TextField global_dataset_1 = new TextField();
然后有些消息来源说不要那样做,只是引用.fxml ID;这就是我原本想做的事情......我尝试了上面的第一个,在开头声明它并将其包装成@Override initialize()
。都没有奏效。我在.fxml文件中设置了ID。
我还看过: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>
非常感谢任何帮助!
答案 0 :(得分:2)
您在构建FXML文件方面存在错误。在您的代码中,您需要使用fx:id
设置节点的ID,但只需id
。
您的TextField
应更改为:
<TextField fx:id="global_dataset_1" ...
一些附注:
您可能希望使用field.setText()
代替appendText()
,除非您打算允许他们选择多个文件并将它们全部列在同一文本字段中。
此外,在您的控制器类中,您应该将节点声明为private
:
@FXML
private TextField global_dataset_1;
最后,不需要(或推荐)将您的primaryStage
作为公共字段进行分享。打开FileChooser
居中的另一种方法是从控制器中声明的任何节点获取当前Window
:
File selectedFile = fileChooser.showOpenDialog(
global_dataset_1.getScene().getWindow());