2016-08-26 1 views
4

Надеюсь получить некоторые ответы относительно наличия операторов fx: include для каждой вкладки в tabpane. Мне удалось с легкостью отобразить контент, но методы ссылок связанного класса контроллера просто дают мне исключение nullpointerreference, независимо от того, как я его структурирую. Контроллеры включенных макетов FXML не имеют ни метода конструктора, ни метода initialize(), нужны ли они? Я пробовал разные вещи, но всегда получал такое же исключение.JavaFX 8 - Таблицы и вкладки с отдельными FXML и контроллерами для каждой вкладки

Что я просто делал, это добавить слушателя изменений в tabpane и когда была нажата вкладка, я хотел заполнить некоторые текстовые поля некоторыми значениями, полученными от глобального доступного массива. Обратите внимание: проблема с arraylist не является проблемой, поэтому выполнение этой операции с использованием основного контроллера работает нормально.

Я собираюсь добавить пример кода в ближайшее время, но не могу прямо сейчас. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация, иначе я отправлю код позже сегодня.

* Редактировать, вот мой пример кода, взятый из другого потока здесь, в StackOverflow. JavaFX TabPane - One controller for each tab

TestApp.java:

public class TestApp extends Application { 
    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Scene scene = new Scene(new StackPane()); 

     FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/MainTestWindow.fxml")); 
     scene.setRoot(loader.load()); 
     MainTestController controller = loader.getController(); 
     controller.init(); 

     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

Главный контроллер, где я хочу, чтобы ссылаться на контроллеры суб.

public class MainTestController { 

    @FXML private TabPane tabPane; 
    // Inject tab content. 
    @FXML private Tab fooTabPage; 
    // Inject controller 
    @FXML private FooTabController fooTabPageController; 

    // Inject tab content. 
    @FXML private Tab barTabPage; 
    // Inject controller 
    @FXML private BarTabController barTabPageController; 

    public void init() { 
     tabPane.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends Tab> observable, 
                     Tab oldValue, Tab newValue) -> { 
      if (newValue == barTabPage) { 
       System.out.println("Bar Tab page"); 
       barTabPageController.handleButton(); 
      } else if (newValue == fooTabPage) { 
       System.out.println("Foo Tab page"); 
       fooTabPageController.handleButton(); 
      } 
     }); 
    } 
} 
.fxml

Главный вид в

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.control.TabPane?> 
<?import javafx.scene.control.Tab?> 

<TabPane fx:id="tabPane" fx:controller="controller.MainTestController" xmlns="http://javafx.com/javafx/8.0.40" 
     xmlns:fx="http://www.w3.org/2001/XInclude"> 
    <tabs> 
     <Tab fx:id="fooTabPage" text="FooTab"> 
      <fx:include source="fooTabPage.fxml"/> 
     </Tab> 
     <Tab fx:id="barTabPage" text="BarTab"> 
      <fx:include source="barTabPage.fxml"/> 
     </Tab> 
    </tabs> 
</TabPane> 

FooTab:

public class FooTabController { 
    @FXML private Label lblText; 

    public void handleButton() { 
     lblText.setText("Byebye!"); 
    } 
} 

.fxml FooTab в:

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.layout.VBox?> 
<?import javafx.scene.control.Label?> 

<?import javafx.scene.control.Button?> 
<VBox xmlns:fx="http://www.w3.org/2001/XInclude" fx:controller="controller.FooTabController"> 
    <Label fx:id="lblText" text="Helllo"/> 
    <Button fx:id="btnFooTab" onAction="#handleButton" text="Change text"/> 
</VBox> 

BarTab:

public class BarTabController { 
    @FXML private Label lblText; 

    public void handleButton() { 
     lblText.setText("Byebye!"); 
    } 
} 

.fxml BarTab в

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.layout.VBox?> 
<?import javafx.scene.control.Label?> 

<?import javafx.scene.control.Button?> 
<VBox xmlns:fx="http://www.w3.org/2001/XInclude" fx:controller="controller.BarTabController"> 
    <Label fx:id="lblText" text="Helllo" /> 
    <Button fx:id="btnBarTab" onAction="#handleButton" text="Change text"/> 
</VBox> 

выше OnAction как для FooTab и BarTab работы с соответствующими кнопками. Когда этот метод (handleButton) является ссылкой с главного контроллера, это когда я получаю исключение.

+0

«ссылки на методы соответствующего класса контроллера просто не дает мне исключение nullpointerreference независимо от того, как я структурировать». Можете ли вы изменить свой вопрос, чтобы показать, что вы пробовали? –

+0

Теперь я обновил тестовый код, который у меня есть, пожалуйста, сообщите –

ответ

4

Чтобы ввести контроллер для прилагаемого FMXL-файла, вам понадобится атрибут fx:id на элементе <fx:include>. Контроллер будет введен в поле с "Controller", добавленным к значению fx:id.

Если вы хотите ввести фактический Tab, вам понадобится отдельный fx:id.

Итак:

<tabs> 
    <Tab fx:id="fooTab" text="FooTab"> 
     <fx:include fx:id="fooTabPage" source="fooTabPage.fxml"/> 
    </Tab> 
    <Tab fx:id="barTab" text="BarTab"> 
     <fx:include fx:id="barTabPage" source="barTabPage.fxml"/> 
    </Tab> 
</tabs> 

и

@FXML private TabPane tabPane; 
// Inject tab content. 
@FXML private Tab fooTab; 
// Inject controller 
@FXML private FooTabController fooTabPageController; 

// Inject tab content. 
@FXML private Tab barTab; 
// Inject controller 
@FXML private BarTabController barTabPageController; 
+0

Спасибо, что так много, он работал как шарм сразу! –

0

Вывод: Пример шаблона "впрыснуть SubControllers"
- приведенный выше пример очень помог мне понять механизм INJECT в прошлом. Спасибо.
- я переработан код, чтобы сделать его еще более прозрачным и понятным
- следующий код завершения и работы

Tab1fooController.java

public class TabPaneRootController { 

    @FXML private TabPane tabPane; 

    //###################################Inject part############################################# 
    // Inject tab content 
    @FXML private Tab tab1_foo; //from TabPaneRootView.fxml: <Tab fx:id="tab1_foo" ...> 
    @FXML private Tab tab2_bar; //from TabPaneRootView.fxml: <Tab fx:id="tab2_bar" ...> 

    // Inject tab controller 
    @FXML private Tab1fooController xxx_tab1foo_xxxController;//TabPaneRootView.fxml_include_fx:id="xxx_tab1foo_xxx" + "Controller" 
    @FXML private Tab2barController xxx_tab2bar_xxxController;//TabPaneRootView.fxml_include_fx:id="xxx_tab2bar_xxx" + "Controller" 
    //########################################################################################### 

     public void init() { 
       tabPane.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends Tab> observable, 
                    Tab oldValue, Tab newValue) -> {                          
      if (newValue == tab2_bar) { 
       System.out.println("- 2.Tab bar -"); 
       System.out.println("xxx_tab2bar_xxxController=" + xxx_tab2bar_xxxController); //if =null => inject problem 
       xxx_tab2bar_xxxController.handleTab2ButtonBar(); 
      } else if (newValue == tab1_foo) { 
       System.out.println("- 1.Tab foo -"); 
       System.out.println("xxx_tab1foo_xxxController=" + xxx_tab1foo_xxxController); //if =null => inject problem 
       xxx_tab1foo_xxxController.handleTab1ButtonFoo(); 
      } else { 
       System.out.println("- another Tab -"); 
      } 
     }); 
    } 
} 

tabPaneRootView.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.control.Tab? 
<?import javafx.scene.control.TabPane?> 

<TabPane fx:id="tabPane" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.TabPaneRootController"> 
<tabs> 
    <Tab fx:id="tab1_foo" text="myTab1foo"> 
     <fx:include fx:id="xxx_tab1foo_xxx" source="tab1fooView.fxml" /> 
    </Tab> 
    <Tab fx:id="tab2_bar" text="myTab2bar"> 
     <fx:include fx:id="xxx_tab2bar_xxx" source="tab2barView.fxml" /> 
    </Tab> 
</tabs> 

Tab1fooController.java

public class Tab1fooController { 
    @FXML private Label tab1_label_showText; 

    public void handleTab1ButtonFoo() { 
     if(tab1_label_showText.getText().equals("tab1 aaa")) { 
      tab1_label_showText.setText("tab1 iii"); 
     } else { 
      tab1_label_showText.setText("tab1 aaa"); 
     } 
    } 
} 

tab1fooView.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.control.Button?> 
<?import javafx.scene.control.Label?> 
<?import javafx.scene.layout.VBox?> 

<VBox xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.Tab1fooController"> 
    <Label fx:id="tab1_label_showText" text="Tab1_start" /> 
    <Button fx:id="tab1_button_foo" onAction="#handleTab1ButtonFoo" text="tab1_button_foo" /> 
</VBox> 

Tab2barController.java

public class Tab2barController { 
    @FXML private Label tab2_label_showText; 

    public void handleTab2ButtonBar() {    
     if(tab2_label_showText.getText().equals("tab2 bbb")) { 
      tab2_label_showText.setText("tab2 jjj"); 
     } else { 
      tab2_label_showText.setText("tab2 bbb"); 
     } 
    } 
} 

tab2barView.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.control.Button?> 
<?import javafx.scene.control.Label?> 
<?import javafx.scene.layout.VBox?> 

<VBox xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111" fx:controller="controller.Tab2barController"> 
    <Label fx:id="tab2_label_showText" text="Tab2_start" /> 
    <Button fx:id="tab2_button_bar" onAction="#handleTab2ButtonBar" text="tab2_button_bar" /> 
</VBox> 

TestApp.java

public class TestApp extends Application { 
    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Scene scene = new Scene(new StackPane()); 

     FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/tabPaneRootView.fxml")); 
     scene.setRoot(loader.load()); 
     TabPaneRootController controller = loader.getController(); 
     controller.init(); 

     primaryStage.setScene(scene); 
     primaryStage.setTitle("Inject TabController"); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

- Directory structure
- Example started

Смежные вопросы