0

How can I start a method every time a tab is called? I have a Main.fxml with a tabpane and two tabs, I've included a separate fxml for each tab (tab1.fxml, tab2.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(){

    }
}

Each FXML has a Label which should show how often the tab(content) was called. So if I click on tab ("tab2") the counter label should show "1" and increment by +1 every time I call this tab again. This should happen by using a method within the tab controllers.

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++;
    }
}

I've already tried to solve this problem by using static methods and labels but i get NullPointerExceptions, seems like this doesn't work anymore with java 8. Also I've tried to get the controller by using a FXMLloader ... this way I also get a NullPointerExceptions.

Isn't there an onCall method for the included fmxl or the anchorpane? Or maybe something that makes the controller initialize again.

Any other solutions or ideas?

4

1 回答 1

2

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

你需要三样东西:

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

首先,只需执行以下操作:

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

在 Main.fxml 中,和

@FXML private TabPane tabPane ;

在 MainController.java 中。

其次,您可以使用“嵌套控制器”技术

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

在 Main.fxml 中,将fx:includes 更改为包括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'sinitialize()方法中设置监听器:

public void initialize() {
    tabPane.getSelectionModel().selectedItemProperty()
        .addListener((obs, oldTab, newTab) -> {
            if (newTab == tab1) {
                tab1ContentController.addViewCounter();
            } else if (newTab == tab2) {
                tab2ContentController.addViewCounter();
            }
        });
}
于 2014-11-14T20:45:42.083 回答