2014-10-03 18 views
0

如何將同一個FXML層次結構加載到2個不同的根中? 我試過這個:從同一個FXML與Java構建單獨的選項卡

protected void openPrivateSession(String remoteNick, int port, boolean isHost) { 
    FXMLLoader loader = 
     new FXMLLoader(getClass().getResource("PrivateTab.fxml")); 
    try { 
     PrivateChat pcc = new PrivateChatController(remoteNick, port, isHost); 
     loader.setController(pcc); 
    if (isHost) { 
     connectRemoteUser(remoteNick, pcc.getPort()); 
    } 
    Tab privateChat = new Tab(remoteNick); 
    loader.setRoot(privateChat); 
    loader.load(); 
    clientController.addPrivateChatTab(privateChat); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

在客戶端程序中。這是客戶端控制器:

public class ClientController implements Initializable { 
    private Client associatedClient; 
    private String hostname; 
    private int port; 

    private Stage primaryStage; 
    private String title; 

    @FXML 
    private VBox nickList; 

    @FXML 
    private TextArea chatArea; 

    @FXML 
    private TextField msgBar; 

    @FXML 
    private Button sendButton; 

    @FXML 
    private MenuItem connectDisconnect; 

    @FXML 
    private TabPane privateChatPane; 

    @FXML 
    private MenuItem settingsButton; 

    @FXML 
    private Stage settings; 

    . 
    . 
    . 

}

但加載相同privateChat標籤到相同的客戶端(而不是一個本地,一個是遠程的 - 這意味着privateChatPane,可能所有其他FXML對象有相同的參考文獻)。

所以我想我最後的問題是...你怎麼能注入同樣的FXML到2個不同的對象,並保持其獨特性?

好MCVE:

class classA extends Application{ 

public static void main(String[] args){ launch(args); } 

private ClassAController cac; 

public void start(Stage s){ 
    FXMLLoader loader = new FXMLLoader(getClass().getResource("ClassA.fxml"); 
    loader.setController(cac = new ClassAController()); 
    s.setScene(new Scene(loader.load())); 
    s.show(); 
} 

public void onSomeEvent(String s){ 
    FXMLLoader loader = new FXMLLoader(getClass().getResource("PrivateChat.fxml"); 
    loader.setController(new PrivateChatController()); 
    Tab tab = new Tab(s); 
    loader.setRoot(tab); 
    cac.addPrivateChatTab(tab); 
} 
} 

class ClassAController implements Initializeable{ 
@FXML TabPane privateChatPane; 

public void initialize(URL url, ResourceBundle resource){} 

//Using this method causes the add of the same Tab twice to the same app instead once for each app 
public void addPrivateChatTab(Tab privateChat){ 
privateChatPane.getTabs().add(privateChat); 
} 

我跑ClassA的應用程序的兩個實例。當我使用addPrivateChatTab()時,我在相同的應用程序實例中獲得了兩次相同的選項卡。

+0

您的代碼不多大的意義對象我。例如。 pcc沒有定義。 FXMLLoader不使用clientController。你在談論2個「根」和一個「遠程」選項卡,但是我在代碼中沒有看到這些。很難說出你究竟想要達到什麼目的。 – Puce 2014-10-03 11:03:34

+0

根據這些部分代碼,我猜只有一個clientController實例,clientController.addPrivateChatTab(privateChat)會將所有privateChat選項卡添加到此clientController。代碼中沒有remoteController。不是嗎? – 2014-10-03 11:30:30

+0

不,你是對的。當然,這是部分代碼,我不會發布整個事情太大。 每個客戶端都有一個clientController(2個實例),但是它們注入了相同的FXML,這對我造成了問題。 如何從同一個FXML實現clientController的多個實例?這甚至有可能嗎? – 2014-10-03 11:50:33

回答

0

好吧,所以我解決了這個問題,this後有幫助。 我的代碼改變只是一點點:

protected void addPrivateChatTab(String remoteNick, int port, boolean isHost) { 
FXMLLoader loader = 
    new FXMLLoader(getClass().getResource("PrivateTab.fxml")); 
try { 
    loader.setController(new PrivateChat(remoteNick, port, isHost)); 
    if (isHost) { 
    associatedClient.connectRemoteUser(remoteNick, PrivateChat.getPort()); 
    } 
    Tab privateChat = new Tab(remoteNick); 
    SplitPane sp = loader.load(); 
    privateChat.setContent(sp); 
    addPrivateChatTab(privateChat); 
    } catch (IOException e) { 
    e.printStackTrace(); 
} 

爲了讓Google更具體:

  1. 創建包裝對象(Tab privateChat = new Tab(remoteNick))。
  2. 加載您即將添加的動態對象的內容(SplitPane sp = loader.load())。
  3. 將包裝物的內容您加載(privateChat.setContent(sp)
  4. 最後完成的對象添加到舞臺/父節點(addPrivateChatTab(privateChat)
相關問題