JavaFX的。从另一个控制器

时间:2016-11-16 08:26:18

标签: javafx javafx-2 javafx-8

需要你的帮助! 这可能更多的是设计视角,但我在我的应用程序中使用这种模式,所以想得到一个想法。

附加了示例屏幕截图。 http://imgur.com/a/fuD5D

我的问题: 我有一个BorderPane,在我的情况下是一种根容器(RootBorderPane.fmxl,RootBorderPaneController.java)。视图是使用场景构建器设计的。我将使用左侧作为导航面板,并根据左侧的选择,我将在RootBorderPane的中心区域加载一个新视图。 我有其他类似的视图(View1.fxml,View2.fxml,View3.fxml等)(使用场景构建器设计)和各自的控制器(View1Controller.java,View2Controller.java,View3Controller.java等)。 View1,View2,View3自己包含TableViews。 现在我在RootBorderPane的左边有几个按钮(Button1,Button2,Button3等),如果我点击Button1然后我应该加载我的View1(View1.fxml)并在RootBorderPane中心区域设置它。

我单击“Button1”,在按钮上单击我加载了View1并将其设置在RootBorderPane的中心。该逻辑位于RootBorderPaneController.java中 View1包含一个TableView,并且在View1的控制器(View1Controller.java)的initializable()方法上加载和设置表视图的数据 我能够完成上述所有说法。

问题: 我在导航面板上有添加和删除按钮,这些按钮应根据在View1的tableview上选择的记录启用/禁用。 (如果在桌面视图上选择了记录,则应启用删除按钮,否则如果在桌面视图中未选择任何记录,则应启用“添加”按钮。)

直接或间接地我的问题搁置到从另一个控制器访问一个控制器。有没有优雅的设计方法来做到这一点,而不是在另一个控制器中保留1个控制器的参考。

先谢谢

2 个答案:

答案 0 :(得分:0)

允许您访问subPanes(View_1 ... View_n)控制器的一种方法是在为根窗格执行操作时加载它们。

String(contentsOf:encoding:)

现在你只需要在你的bpc控制器中使用setSubPaneList(..)方法,你就可以访问你的subPanes的公共方法(例如getter / setter)

答案 1 :(得分:0)

您似乎使用FXML Loader动态加载View,因此以下是使用它的规则:

  1. 不要使用FXMLLoader的静态方法,使FXMLLoader拥有更多选项(即控制器和节点实例)
  2. 从主控制器获取FXMLLoader给出的子控制器的实例。
  3. 选择在父子控制器之间操作的常用方法:我提出了一个selectedProperty()方法。
  4. 从界面获取此属性,以便所有子控制器都可以访问
  5. 我使用Property在控制器之间操作,在你的情况下,TableView的selectedProperty应该是理想的解决方案:你可以拥有所选的实例,并且你有选择/取消选择的事件,可以通过两种方式使用:just绑定它,或添加在tableView中完成的更改的监听器 对于这种情况,绑定就足够了。

    该解决方案涉及许多文件,因此主要技巧如下:从主控制器获取当前子节点的selectedProperty实例,并将其绑定到按钮的visibleProperty,以显示它。 / p>

    buttonOpen.disableProperty().bind(controller.selectedProperty().isNull());
    

    您需要在打开按钮的代码中再次使用selectedProperty

    public void open(){
     //TODO open in a view
     System.out.println("open the object"+selectedProperty().get()
    }
    

    完整资料来源:

    Java文件

    /**
     * App launch
     */
    public class SOFx extends Application{
    
      public static void main(String[] args) {
        launch(args);
      }
    
      @Override
      public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle ("SO test");
        //static loading for index, don't need the controller.
        Parent root =  FXMLLoader.load(getClass().getResource("Index.fxml"),null);
        Scene scene = new Scene(root);
        primaryStage.setMaximized(true);
        primaryStage.setScene(scene);
        primaryStage.show ();
      }
    }
    
    /**
     * Main Controller
     */
    public class IndexController {
    
    
      @FXML
      private BorderPane root;
    
      @FXML
      private Button buttonOpen;
    
      private ObjectProperty<Object> selectedProperty;
    
      public FXMLLoader loadFXML(URL url, ResourceBundle resources){
        FXMLLoader fxmlLoader = new FXMLLoader ();
        fxmlLoader.setLocation (url);
        fxmlLoader.setResources(resources);
        try {
          fxmlLoader.load ();
          return fxmlLoader;
        } catch (IOException e) {
          e.printStackTrace(System.err);
          throw new IllegalStateException(e);
        }
      }
    
      public void button1(){
        FXMLLoader loadFXML = loadFXML(getClass().getResource("View1.fxml"),null);
        root.setCenter(loadFXML.getRoot());
        ICenterController controller = (ICenterController) loadFXML.getController();
        selectedProperty = controller.selectedProperty();
        buttonOpen.disableProperty().bind(selectedProperty.isNull());
      }
    
      public void open(){
        //TODO open in a view
        System.out.println("open the object"+selectedProperty.get());
       }
    
    }
    
    /**
     * Interface of Center controllers
     */
    public interface ICenterController {
     ObjectProperty<Object>  selectedProperty();
    }
    
    
    
    /**
     * Child controller
     */
    public class View1Controller implements ICenterController {
    
      private static final ObjectProperty<Object> selectedProperty = new SimpleObjectProperty();
    
      @Override
      public ObjectProperty<Object> selectedProperty() {
        return selectedProperty;
      }
    
      /**
       * simulate TableView selection/deselection
       */
      public void select(){
        selectedProperty.set(new Object());
      }
    
      public void deselect(){
        selectedProperty.set(null);
      }
    
    }
    

    Fxml文件,我没有做完全的TableView,我用按钮模拟它

    Index.fxml

        <BorderPane xmlns="http://javafx.com/javafx/8.0.51" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="pdem.stackoverflow.IndexController" fx:id="root">
    
            <left>
                <VBox>
                    <Button onAction="#button1" text="view1"/>
                    <Button fx:id="buttonOpen" text="open"/>
                </VBox>
    
            </left>
    
    
        </BorderPane>
    

    View1.fxml

    <VBox xmlns="http://javafx.com/javafx/8.0.51" xmlns:fx="http://javafx.com/fxml/1"
        fx:controller="pdem.stackoverflow.View1Controller" >
                <Button onAction="#select" text="select"/>
                <Button onAction="#deselect" text="deselect"/>
    </VBox>