我试图通过从模态窗口单击按钮来填充方法调用中的TableView。我希望这是可能的,但我没有运气。 TableView已在FXML文件中创建。每当我调用该方法时,我都会收到一个空指针异常。有什么想法或建议吗?对不起,如果我的问题格式不好,我不会问很多问题。
MainController.java
@FXML TableView<Part> partsTableView;
@FXML ObservableList<Part> parts;
@FXML public TableColumn<Part, Integer> partIDColumn;
@FXML public TableColumn<Part, String> partNameColumn;
@FXML public TableColumn<Part, Integer> partILColumn;
@FXML public TableColumn<Part, Double> partPriceColumn;
@FXML
public void getPartData(){
partIDColumn.setCellValueFactory(new PropertyValueFactory<>("id")); (Line 112)
partNameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
partILColumn.setCellValueFactory(new PropertyValueFactory<>("instock"));
partPriceColumn.setCellValueFactory(new PropertyValueFactory<>("price"));
partsTableView.setItems(generateData());
}
private ObservableList<Part> generateData(){
parts = FXCollections.observableArrayList();
parts.add(new Part(0, "Part" , 1 , 25.00));
return parts;
}
main.fxml
<TableView fx:id="partsTableView" layoutX="13.0" layoutY="68.0" prefHeight="344.0" prefWidth="556.0">
<columns>
<TableColumn fx:id="partIDColumn" editable="false" prefWidth="138.0" resizable="false" text="Part ID" />
<TableColumn fx:id="partNameColumn" editable="false" prefWidth="139.0" resizable="false" text="Part Name" />
<TableColumn fx:id="partILColumn" editable="false" prefWidth="119.0" resizable="false" text="Inventory Level" />
<TableColumn fx:id="partPriceColumn" editable="false" prefWidth="159.0" resizable="false" text="Price / Cost Per Unit" />
</columns>
</TableView>
错误:引起:java.lang.NullPointerException 在ims.MainController.getPartData(MainController.java:112)
我正在使用IntelliJ,我在Scene Builder中构建我的舞台/场景。我很抱歉,如果这很简单,而且我忽略了一些事情,但是,我只是在困难时期搞清楚这一点。
提前感谢您的时间和帮助!
答案 0 :(得分:1)
我准备了一个样本。你可以遵循它的逻辑。重点是管理主对话框和模态稀释控制器。您可以在AppMainController.java中查看DialogController dialogController = fxmlLoader.<DialogController>getController();
行。在此示例中,主控制器(AppMainController
)获取对话框控制器(DialogController
)并将其可观察列表设置为对话框控制器。示例类和fxmls如下:
AppMain.java:
package populatetable;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class AppMain extends Application{
@Override
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("AppMain.fxml"));
Scene scene = new Scene(root, 500,500);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
AppMain.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane minHeight="500.0" minWidth="500.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111" fx:controller="populatetable.AppMainController">
<children>
<TableView fx:id="tvData" layoutX="91.0" layoutY="159.0" prefHeight="300.0" prefWidth="300.0">
<columns>
<TableColumn fx:id="colId" prefWidth="75.0" text="ID" />
<TableColumn fx:id="colName" prefWidth="75.0" text="Name" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
<Button layoutX="211.0" layoutY="85.0" mnemonicParsing="false" onAction="#onOpenDialog" text="Open Dialog" />
</children>
</AnchorPane>
AppMainController.java
package populatetable;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
public class AppMainController implements Initializable {
@FXML
private TableView<Data> tvData;
@FXML
private TableColumn colId;
@FXML
private TableColumn colName;
private ObservableList<Data> tvObservableList = FXCollections.observableArrayList();
// Open dialog button click event
@FXML
void onOpenDialog(ActionEvent event) throws IOException {
System.out.println("onOpenDialog clicked");
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Dialog.fxml"));
Parent parent = fxmlLoader.load();
DialogController dialogController = fxmlLoader.<DialogController>getController();
dialogController.setAppMainObservableList(tvObservableList);
Scene scene = new Scene(parent, 300, 200);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
}
@Override
public void initialize(URL location, ResourceBundle resources) {
colId.setCellValueFactory(new PropertyValueFactory<>("id"));
colName.setCellValueFactory(new PropertyValueFactory<>("name"));
tvData.setItems(tvObservableList);
}
public ObservableList<Data> getTvObservableList() {
return tvObservableList;
}
}
DialogController.java
package populatetable;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
public class DialogController {
private ObservableList<Data> appMainObservableList;
//fill table button click event
@FXML
void fillTable(ActionEvent event) {
Data data = new Data(1, "Name1");
appMainObservableList.add(data);
}
public void setAppMainObservableList(ObservableList<Data> tvObservableList) {
this.appMainObservableList = tvObservableList;
}
}
Dialog.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane minHeight="200.0" minWidth="300.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111" fx:controller="populatetable.DialogController">
<children>
<Button layoutX="115.0" layoutY="89.0" mnemonicParsing="false" onAction="#fillTable" text="Fill Table" />
</children>
</AnchorPane>
Data.java
package populatetable;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
public class Data {
private final SimpleIntegerProperty id;
private final SimpleStringProperty name;
public Data(int id, String name) {
this.id = new SimpleIntegerProperty(id);
this.name = new SimpleStringProperty(name);
}
public int getId() {
return id.get();
}
public void setId(int ID) {
id.set(ID);
}
public String getName() {
return name.get();
}
public void setName(String nme) {
name.set(nme);
}
@Override
public String toString() {
return "id: " + id.get() + " - " + "name: " + name.get();
}
}
希望它有用。