2016-08-19 131 views
2

我在问这个问题之前在任何地方寻找解决方案,如果它已经存在请报告它。JavaFX,在标签之间传递参数控制器

在实践中我有这种情况:

CLICK TO VIEW THE IMAGE

TabLayout.fxml

<JFXTabPane fx:id="tabbedPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefWidth="500.0" tabClosingPolicy="UNAVAILABLE" tabMinWidth="100.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.TAB.TabController" stylesheets="@tab.css"> 
<tabs> 
    <Tab id="anagrafeTab" closable="false" text="Anagrafe"> 
    <content> 
     <fx:include fx:id="anagrafeL" source="/application/Anagrafe/AnagrafeLayout.fxml"/> 
    </content> 
    </Tab> 
    <Tab id="visiteTab" closable="false" text="Visite"> 
    <content> 
     <fx:include fx:id="visiteL" source="/application/Visite/VisiteLayout.fxml"/> 
    </content></Tab> 
    <Tab id="latteTab" closable="false" text="Produzione Latte"> 
    <content> 
     <fx:include fx:id="latteL" source="/application/Latte/LatteLayout.fxml"/> 
    </content> 
    </Tab> 
    <Tab id="partiTab" closable="false" text="Parti" > 
    <content> 
     <fx:include fx:id="partiL" source="/application/Parti/PartiLayout.fxml"/> 
    </content> 
    </Tab> 
</tabs> 
</JFXTabPane> 

用于每一个 “包括” 布局:

  • AnagrafeLayout.fxml
  • VisiteLayout.fxml
  • LatteLayout.fxml
  • PartiLayout.fxml

比我有一个模型,并为每一个布局的控制,但一个唯一调用。

public class Tab { 

public Tab() { 
    inizializza(); 
} 

private void inizializza() { 
    try { 
     Stage stage = new Stage(); 
     stage.setTitle("Dati"); 
     stage.getIcons().add(new Image(getClass().getResourceAsStream("insert.png"))); 

     FXMLLoader loader = new FXMLLoader(); 
     loader.setLocation(getClass().getResource("TabLayout.fxml")); 
     JFXTabPane root = (JFXTabPane) loader.load(); 

     Scene scene = new Scene(root,660,430); 
     stage.setScene(scene); 

     stage.show(); 
     //ScenicView.show(scene); 

    } catch(Exception e) { 
     e.printStackTrace(); 
    } 

    } 
} 

我需要将ObservableList<Visite> data = FXCollections.observableArrayList();传递给每个控制器。

我真的不知道该怎么做,我不会使用单个控制器,因为他们是相当长的类。

编辑:

TABController.java

public class TabController implements Initializable { 

@FXML 
private TabPane tabbedPane; 

@Override 
public void initialize(URL arg0, ResourceBundle arg1) { 
    assert tabbedPane != null : "fx:tabbedPane=\"in\" was not injected: check your FXML file 'TabLayout.fxml'."; 

    tabbedPane.getSelectionModel().selectedItemProperty().addListener((ov, oldTab, newTab) -> { 

     if(tabbedPane.getSelectionModel().getSelectedIndex() != 0) { 
      tabbedPane.getScene().getWindow().setWidth(1171); 
      tabbedPane.getScene().getWindow().setHeight(700); 
     } else { 
      tabbedPane.getScene().getWindow().sizeToScene(); 
     }   
    }); 
    } 
} 

EDIT2

的4个选项卡有,如上面提到的,每一个他自己的模型类。 所以我有4个不同的列表,它们最初是空的,因为它们是动态填充的,因为每个选项卡都有一个表。 当tabPane由不同的实习调用时,将创建列表。 我需要这些列表,因为它可能是以前的负载的可能性,我必须将这些信息传递给控制器​​。

在实践中,这种情况发生:

1)

呼叫创建从该选项卡中加载表格空列表功能插件。这些数据将在最后存储在数据库中。

2)

调用功能显示调用该函数插入件与创建列表和从数据库中获取数据并将其发送到随后可以修改表的特定标志。

我希望我是清楚的,我很抱歉,对于这个问题的不确定性先

现在我解决这样

public class TabController implements Initializable { 

@FXML 
private TabPane tabbedPane; 

@FXML 
private VisiteController visiteLController; 
private ObservableList<Visite> dataVisite = FXCollections.observableArrayList(); 
private ObservableList<Visite> dataDelVisite = FXCollections.observableArrayList(); 

@FXML 
private LatteController latteLController; 
private ObservableList<Latte> dataLatte = FXCollections.observableArrayList(); 
private ObservableList<Latte> dataDelLatte = FXCollections.observableArrayList(); 

@FXML 
private PartiController partiLController; 
private ObservableList<Parti> dataParti = FXCollections.observableArrayList(); 
private ObservableList<Parti> dataDelParti = FXCollections.observableArrayList(); 


@Override 
public void initialize(URL arg0, ResourceBundle arg1) { 
    assert tabbedPane != null : "fx:tabbedPane=\"in\" was not injected: check your FXML file 'TabLayout.fxml'."; 

    tabbedPane.getSelectionModel().selectedItemProperty().addListener((ov, oldTab, newTab) -> { 

     if(tabbedPane.getSelectionModel().getSelectedIndex() != 0) { 
      tabbedPane.getScene().getWindow().setWidth(1171); 
      tabbedPane.getScene().getWindow().setHeight(700); 
     } else { 
      tabbedPane.getScene().getWindow().sizeToScene(); 
     }   
    });  

    visiteLController.setData(dataVisite, dataDelVisite); 
    latteLController.setData(dataLatte, dataDelLatte); 
    partiLController.setData(dataParti, dataDelParti); 
} 
} 

和设置方法为每个控制器

明显变化
public void setData(ObservableList<Visite> data, ObservableList<Visite> dataDel) { 
    this.data = data; 
    this.dataDel = dataDel; 
    liveSearh(); 
} 
+1

你可以发布'TabController'的代码吗?这看起来像http://stackoverflow.com/questions/37068243/share-model-with-nested-controller –

+0

增加:) 现在我回头看看链接 –

+0

请澄清问题。每个控制器都需要什么,以及您在哪里创建每个需要的数据,或者有权访问这些数据? –

回答

0

也许这里最好的选择是使用controller factory,这样当你创建时,你可以将这个列表传递给控制器。

因此,首先,定义所有的控制器,使他们有一个构造采取观察的名单:

public class TabController implements Initializable { 

    private final ObservableList<Visite> data ; 

    public TabController(ObservableList<Visite> data) { 
     this.data = data ; 
    } 

    // existing code... 
} 

,例如,

public class AnagrafeController implements Initializable { 

    private final ObservableList<Visite> data ; 

    public AnagrafeController(ObservableList<Visite> data) { 
     this.data = data ; 
    } 

    // existing code... 
} 

现在你需要一个控制器工厂,基本上是一个函数,需要一个Class并返回该类的控制器。这只是需要一点反思:

FXMLLoader loader = new FXMLLoader(); 
loader.setLocation(getClass().getResource("TabLayout.fxml")); 

ObservableList<Visite> data = FXCollections.observableArrayList(); 

loader.setControllerFactory((Class<?> controllerType) -> { 
    try { 
     Constructor<?>[] constructors = controllerType.getConstructors(); 
     for (Constructor<?>[] constructor : constructors) { 
      if (constructor.getParameterCount() == 1 && 
       constructor.getParameterTypes()[0] == ObservableList.class) 

       return constructor.newInstance(data); 
      } 
     } 

     // no suitable constructor found, just use default: 
     return controllerType.newInstance(); 

    } catch (Exception exc) { 
     System.out.println("Could not create controller:"); 
     exc.printStackTrace(); 
     return null ; 
    } 
}); 

JFXTabPane root = loader.load(); 

// ... 

这将创建一个可观察的名单(data)和控制器工厂将确保如果控制器类有一个构造以可观察到的列表作为参数,data在为传递该参数。

当您使用<fx:include>时,使用相同的控制器工厂为包含的FXML文件创建控制器,因此假设您定义了合适的构造函数,同样的列表也会传递给这些控制器。

你也可以考虑一个依赖注入框架,这基本上可以自动将对象注入你的控制器。 Afterburner.fx是一个非常好的JavaFX依赖注入框架。

+0

好吧,Tab控制器不需要数据列表,但是,对于每个控制器,我必须给出不同的列表。 我应该为每个控制器类创建一个工厂控制器吗? 如果我发送两个列表而不是一个? 我等待您的回复,同时我将自己定位于您发送给我的链接中的解决方案;即在TabController类中,我声明了各种控制器类的控制器,并且我调用了存在于不同控制器类中的setter。 –

+1

好的,我认为问题是你需要在不同的控制器之间共享数据。如果你有权访问'TabController'中的列表,为什么不在每个其他控制器中定义一个'setData(...)'方法,并从'TabController'的'initialize()'方法? –

+0

是我最初的解决方案,仅仅是因为我的错误而无效:我没有正确声明控制器变量的名称。 我注意到你在开始时给我的链接:) –

相关问题