2016-01-05 1 views
0

У меня есть сцена, в которой есть TabPane tabPane, с одной «основной» вкладкой и другими вкладками (Connection - это пользовательский класс).JavaFX - доступ к динамически созданной вкладке контроллера

Я реализую эти вкладки динамически.

@Override 
public void connectionCreatedEvent(Connection connection) { 
    try { 
     Tab tab = new Tab(); 
     //... 
     tab.setContent(FXMLLoader.load(getClass().getResource("../fxml/connectionTab.fxml"))); 
     Platform.runLater(() -> { 
      tabPane.getTabs().add(tab); 
      tabPane.getSelectionModel().select(tab); 
     }); 
     connectionTabs.put(connection, tab); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

В настоящее время, в connectionTab.fxml Заявляю контроллер (ConnectionTabController).

Как я могу получить доступ к этому контроллеру табуляции из этого класса? Или мне нужно это по-другому?

Я застрял на:

@Override 
public void connectionLogEvent(Connection connection, String msg) { 
    System.out.println("-t-connection log : " + connection + " : " + msg); 
    for(Object o : connectionTabs.entrySet()) { 
     Map.Entry ct = (Map.Entry)o; 
     if(ct.getKey() == connection) 
      /* ???(Tab)ct.getKey().getController();??? */ 
    } 
} 

Это логично только мне, что это где-то в пределах Content (так как я устанавливаю его раньше), но я до сих пор не могу найти, как добраться это, или если это даже возможно.

Любая помощь более чем приветствуется!

ответ

1

Вы можете получить контроллер при загрузке FXML:

try { 
    Tab tab = new Tab(); 
    //... 
    FXMLLoader loader = new FXMLLoader(getClass().getResource("../fxml/connectionTab.fxml")); 
    tab.setContent(loader.load()); 

    ConnectionTabController controller = loader.getController(); 

    // ... 
} 

, а затем просто хранить его или передать его там, где это необходимо.

Другой вариант может заключаться в использовании this pattern. В этом случае вы могли бы сделать:

public class ConnectionTab extends Tab { 

    // @FXML-annotated controls... 


    public ConnectionTab() { 
     try { 
      FXMLLoader loader = new FXMLLoader(getClass().getResource("../fxml/connectionTab.fxml")); 
      loader.setRoot(this); 
      loader.setController(this); 
      loader.load(); 
     } catch (Exception exc) { 
      // ... 
     } 
    } 

    // controller methods, etc... 
} 

Обновить свой FXML в

<!-- imports etc ommitted --> 

<!-- note no fx:controller.... --> 
<fx:root type="javafx.scene.control.Tab" xmlns:fx="..."> 
    <content> 
     <!-- layout here --> 
    </content> 
</fx:root> 

и теперь в вашем другом коде вы

@Override 
public void connectionCreatedEvent(Connection connection) { 
    try { 
     ConnectionTab tab = new ConnectionTab(); 
     //... 

     Platform.runLater(() -> { 
      tabPane.getTabs().add(tab); 
      tabPane.getSelectionModel().select(tab); 
     }); 
     connectionTabs.put(connection, tab); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

Теперь connectionTabs карта дает прямой доступ к методы контроллера через объекты значения в нем.

Обратите внимание, что с этим решением, это очень легко передавать ссылки на ConnectionTab, если вам нужно что:

public class ConnectionTab { 

    private final Connection connection ; 

    // ... 

    public ConnectionTab(Connection connection) { 
     this.connection = connection ; 
     try { 

      // load FXML as before... 

     } catch (Exception e) { ... } 

    } 

    // ... 
} 
+0

Хорошо, так что это не будет спагетти, если бы я создал еще один класс 'ControllerTab', что просто (get + set) вкладку и ее контроллер и изменить «HashMap» на «HashMap »? Это то, что перешло мне в голову, но я подумал, что может быть более простой способ связаться с контроллером. – NemanjaT

+0

Возможно, рассмотрим класс 'ControllerTab extends Tab', который загружает сам FXML и использует [этот шаблон] (http://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml. HTML # custom_components). Таким образом вы просто помещаете их на свою карту, и вы можете напрямую обращаться к методам контроллера или добавлять/удалять их из панели вкладок (так как они являются вкладками и т. Д.). –

+0

Хорошо, спасибо вам большое! Много очков для вас, сэр. Думаю, я это сделаю, швы достаточно логичны. – NemanjaT

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

  • Нет связанных вопросов^_^