我有一个ViewController类和一个TabController类。 TabController扩展了ViewController。
在ViewController中,我动态创建选项卡,并且我想在某个时候更改选项卡的名称。我总是得到空指针...
ViewController类
public class ViewController implements Initializable {
@FXML
private TabPane tabPane;
@FXML
private Button addNewTabButton;
private Integer count = 1;
private SingleSelectionModel<Tab> selectionModel;
@Override
public void initialize(URL location, ResourceBundle resources)
{
selectionModel = tabPane.getSelectionModel();
}
@FXML
public void createNewTab(){
Tab newTab = new Tab();
try {
String id = count.toString();
newTab.setText("New Tab");
newTab.setClosable(true);
newTab.setId(id);
newTab.setContent(FXMLLoader.load(getClass().getResource("Tab.fxml")));
count++;
} catch (IOException e){
System.out.println("Error");
}
tabPane.getTabs().add(newTab);
selectionModel.selectLast();
}
public void setTabText(String text){
selectionModel.getSelectedItem().setText(text);
}
}
TabController类
public class TabController extends ViewController implements Initializable {
@FXML
private Button setTextButton;
@FXML
private void fooBar(){
setTabText("fooBar");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
}
}
我总是在线上获得NullPointer:setTabText(“ fooBar”); (TabControllerClass)
如果我想从TabController类访问setTabText()方法,则存在问题。 (当我在ViewController中调用setTabText()时没有错误。)
谢谢您的帮助!
答案 0 :(得分:1)
要进行后续操作,请向ViewController
初始化方法中添加一条简单的打印消息:
public void initialize(URL location, ResourceBundle resources)
{
selectionModel = tabPane.getSelectionModel();
System.out.println("ViewController initialized");
}
使用ViewController
时,它会按预期打印。
使用TabController
时不会。这说明了为什么selectionModel
未初始化,以及为什么得到NPE的原因。
一种解决方案是让TabController
初始化其super:
@Override
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb);
}
这里有一个简单的mcve来演示它*
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class Test1 extends Application
{
@Override
public void start(Stage primaryStage) {
try {
Pane page = (Pane) FXMLLoader.load(this.getClass().getResource("test1.fxml"));
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.show();
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
test1.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/10.0.1"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="TabController">
<center>
<TabPane fx:id="tabPane" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" BorderPane.alignment="CENTER" />
</center>
<bottom>
<Button fx:id="addNewTabButton" mnemonicParsing="false" onAction="#createNewTab" text="Button" BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>
简化的控制器:
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.text.Text;
public class ViewController implements Initializable {
@FXML
private TabPane tabPane;
@FXML
private Button addNewTabButton;
private int count = 1;
private SingleSelectionModel<Tab> selectionModel;
@Override
public void initialize(URL location, ResourceBundle resources)
{
selectionModel = tabPane.getSelectionModel();
System.out.println("ViewController initialized");
}
@FXML
public void createNewTab(){
Tab newTab = new Tab();
String id = String.valueOf(count++);
newTab.setText(id);
newTab.setContent(new Text("Tab number "+id));
tabPane.getTabs().add(newTab);
selectionModel.selectLast();
}
public void setTabText(String text){
selectionModel.getSelectedItem().setText(text);
}
}
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
public class TabController extends ViewController implements Initializable {
@Override
public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb); //comment out this line to cause NPE
}
}