Reaching Tab (TabPane) от другого контроллера классов Java (JavaFX) - PullRequest
0 голосов
/ 03 июля 2019

У меня есть класс ViewController и класс TabController.TabController расширяет ViewController.

В ViewController я динамически создаю вкладки и хочу в какой-то момент изменить имя вкладки.Я всегда получаю Null Pointer ...

Класс 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)

Проблема существует, если я хочу получить доступ к методу setTabText () из класса TabController.(При вызове setTabText () внутри ViewController ошибки не возникает).

Спасибо за помощь!

1 Ответ

1 голос
/ 03 июля 2019

Чтобы следить за происходящим, добавьте простое печатное сообщение в ViewController метод инициализации:

  public void initialize(URL location, ResourceBundle resources)
    {
        selectionModel = tabPane.getSelectionModel();
        System.out.println("ViewController initialized");
    }

Когда вы используете ViewController, он печатается, как и ожидалось.
Когда вы используете TabController, это не так. Это объясняет, почему selectionModel не инициализируется, и почему вы получаете NPE.

Одно из решений - TabController инициализировать его супер:

@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 при запросе. Это делает помощь легче и быстрее.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...