每次调用包含tabcontent的JavaFX start方法都会被调用

时间:2014-11-14 19:11:12

标签: tabs javafx-8 fxml subcontroller

每次调用标签时如何启动方法?我有一个Main.fxml tabpane和两个tabs,我为每个标签添加了一个单独的fxml(tab1.fxmltab2.fxml)。

Main.fxml

<?xml version="1.0" encoding="UTF-8"?>    
<?import javafx.scene.control.*?>    
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="434.0" prefWidth="428.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
   <children>
  <TabPane prefHeight="434.0" prefWidth="428.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
    <tabs>
      <Tab fx:id="tab1" text="Tab 1">
           <content>
              <fx:include source="tab1.fxml" />
           </content>
      </Tab>
      <Tab fx:id="tab2" onSelectionChanged="#addView" text="Tab 2">
           <content>
              <fx:include source="tab2.fxml" />
           </content>
      </Tab>
    </tabs>
  </TabPane>
 </children>
</AnchorPane>      

MainController.java

public class MainController implements Initializable{

    @FXML private Tab tab1;
    @FXML private Tab tab2;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {

    }


    @FXML public void addView(){

    }
}

每个FXML都有一个Label,它应该显示标签(内容)的调用频率。因此,如果我点击标签(“tab2”),每次再次调用此标签时,计数器标签应显示“1”并递增+1。这应该通过使用选项卡控制器中的方法来实现。

tab1.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="249.0" prefWidth="257.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.tab1Controller">
   <children>
     <Label fx:id="lbl_1" layoutX="92.0" layoutY="53.0" text="not clicked" />
   </children>
</AnchorPane>

tab1Controller.java

public class tab1Controller implements Initializable{


     @FXML public  Label lbl_1;

     private static int counter=0;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {


    }

    public void addViewCounter(){
        lbl_1.setText(""+counter);
        counter++;
    }
}

Tab2.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="249.0" prefWidth="257.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.tab2Controller">
   <children>
     <Label fx:id="lbl_2" layoutX="92.0" layoutY="53.0" text="not clicked" />
   </children>
</AnchorPane>

tab2Controller.java

public class tab1Controller implements Initializable{


     @FXML public  Label lbl_2;

     private static int counter=0;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {


    }

    public void addViewCounter(){
        lbl_2.setText(""+counter);
        counter++;
    }
}

我已经尝试通过使用静态方法和标签来解决这个问题,但我得到NullPointerExceptions,似乎这对java 8不起作用了。 另外,我试图使用FXMLloader来获取控制器...这样我也得到NullPointerExceptions

包含的fmxl或anchorpane不存在onCall方法吗?或者可能会让控制器再次初始化。

任何其他解决方案或想法?

1 个答案:

答案 0 :(得分:2)

首先,您的counter不应该是static。它们属于控制器实例,而不属于控制器类。

你需要三件事:

  1. 对主控制器中tabPa的引用
  2. 对主控制器中每个选项卡控制器的引用。
  3. tabPane选定选项卡上的监听器,以便您可以在所选选项卡更改时调用方法
  4. 首先,只需:

    <TabPane fx:id="tabPane" prefHeight="434.0" ... >
    

    在Main.fxml中,

    @FXML private TabPane tabPane ;
    
    MainController.java中的

    对于第二个,您可以使用"Nested Controller" technique

    您需要为每个fx:id添加fx:include属性,然后只需在MainController.java中添加控制器的引用。规则是,如果您的fx:include具有fx:id="x",则可以将相应FXML文件中的控制器注入名为xController的变量中。在这里,我已将控制器的类名更改为Tab1ControllerTab2Controller,以遵循标准约定(并避免混淆)。

    在Main.fxml中,更改fx:include以包含fx:id

    <fx:include fx:id="tab1Content" source="tab1.fxml" />
    
    <fx:include fx:id="tab2Content" source="tab2.fxml" />
    

    在MainController.java中:

    @FXML private Tab1Controller tab1ContentController ;
    @FXML private Tab2Controller tab2ContentController ;
    

    现在在MainController的{​​{1}}方法中设置了监听器:

    initialize()