【发布时间】:2018-11-24 13:50:01
【问题描述】:
我有一个 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>
任何帮助将不胜感激!
【问题讨论】:
-
拥有一个文本字段数组比拥有 4 个单独的文本字段更好/更灵活,所有这些文本字段都有自己的 fileChooser 方法。只需将您想要设置的所需文本字段对象的索引传递给方法,以便您可以执行类似
fileChooser(int index){fileChooser(textFieldArray[index])}的操作 -
我可以将其实现为 fileChooser 的解决方法,但是,这些字段仍设置为 null。我不明白为什么当我在控制器中引用它们并将它们 ID 到 .fxml 文件中时......:-/