从另一个类控制器Java(JavaFX)到达Tab(TabPane)

时间:2019-07-03 01:52:32

标签: java javafx tabs

我有一个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()时没有错误。)

谢谢您的帮助!

1 个答案:

答案 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
    }
}


*在询问时考虑发布mcve。它使帮助变得更加轻松快捷。