本帖最后由 wow7jiao 于 2023-7-5 12:45 编辑
附件已经打包了,很简单的数据插入,但是我不会,实在弄不好了,求有缘人解答package application;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
public class Main<T> extends Application {
@FXML
private TableView<Person> table;
@FXML
private TableColumn<Person, Integer> ageCol;
@FXML
private TableColumn<Person, String> nameCol;
//(1)创建并初始化数据
private final ObservableList<Person> cellData = FXCollections.observableArrayList();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
cellData.add(new Person(20,"Jack"));
cellData.add(new Person(18,"Jerry"));
cellData.add(new Person(21,"Mike"));
//(2)配置 TableColumn 列
ageCol.setCellValueFactory(cellData -> cellData.getValue().getAge().asObject());
nameCol.setCellValueFactory(cellData -> cellData.getValue().getName());
//(3)为 TableView 添加数据
table.setItems(cellData);
try {
// BorderPane root = new BorderPane();
Pane root = (Pane) FXMLLoader.load(getClass().getResource("Sample.fxml"));
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public class Person {
private IntegerProperty age;
private StringProperty name;
public Person(Integer age, String name) {
super();
this.age = new SimpleIntegerProperty(age);
this.name = new SimpleStringProperty(name);
}
public IntegerProperty getAge() {
return age;
}
public void setAge(Integer age) {
this.age = new SimpleIntegerProperty(age);
}
public StringProperty getName() {
return name;
}
public void setName(String name) {
this.name = new SimpleStringProperty(name);
}
}
}
你的代码中问题出现在 start() 方法中。你在加载 Sample.fxml 之前就为 TableView 添加了数据。但是此时,FXML还没有被加载,因此 TableView 及其列还是 null 。当你尝试调用 setItems() 或者 setCellValueFactory() 时,它们会触发空指针异常。
解决这个问题的一个方法是在FXML文件中设置 initialize() 方法,并在此方法中进行列的初始化和数据的添加。请注意,这需要在你的FXML文件的控制器中进行。
修改后的代码可能是这样的:
package application;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.beans.property.*;
import java.net.URL;
import java.util.ResourceBundle;
public class MainController implements Initializable {
@FXML
private TableView<Person> table;
@FXML
private TableColumn<Person, Integer> ageCol;
@FXML
private TableColumn<Person, String> nameCol;
// 创建并初始化数据
private final ObservableList<Person> cellData = FXCollections.observableArrayList();
@Override
public void initialize(URL url, ResourceBundle rb) {
cellData.add(new Person(20,"Jack"));
cellData.add(new Person(18,"Jerry"));
cellData.add(new Person(21,"Mike"));
// 配置 TableColumn 列
ageCol.setCellValueFactory(cellData -> cellData.getValue().getAge().asObject());
nameCol.setCellValueFactory(cellData -> cellData.getValue().getName());
// 为 TableView 添加数据
table.setItems(cellData);
}
public class Person {
private IntegerProperty age;
private StringProperty name;
public Person(Integer age, String name) {
super();
this.age = new SimpleIntegerProperty(age);
this.name = new SimpleStringProperty(name);
}
public IntegerProperty getAge() {
return age;
}
public void setAge(Integer age) {
this.age = new SimpleIntegerProperty(age);
}
public StringProperty getName() {
return name;
}
public void setName(String name) {
this.name = new SimpleStringProperty(name);
}
}
}
然后在 Main 类中只加载FXML文件:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
Pane root = (Pane) FXMLLoader.load(getClass().getResource("Sample.fxml"));
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
在这个修改后的代码中, MainController 类负责处理所有与TableView相关的操作。并且你需要在 Sample.fxml 文件中将 MainController 设置为控制器:
<AnchorPane fx:controller="application.MainController">
<!-- Rest of your FXML file -->
</AnchorPane>
如果你的 Sample.fxml 文件没有在 MainController 中指定,需要修改为上述的形式。其中 fx:controller 的值应该是 MainController 类的完整名称。这样,当FXML文件被加载时,JavaFX将会自动创建一个 MainController 实例,并将所有带 @FXML 注解的字段与FXML文件中对应的元素绑定起来。
|