2012-07-16 168 views
3

當我學習JavaFX2的新世界時,我偶然發現了另一個煩人的問題。我正在開發一個有多個場景的程序(~10個場景)。爲此,我創建了一個這樣的小類:將對象從一個場景傳遞到另一個場景

public class SceneSelector { 
    ... 
    public void setScene(Stage stage, String fxmlfilename, ObservableList ol) throws Exception{ 
     String s = "../" + fxmlfilename; 
     Parent root = FXMLLoader.load(getClass().getResource(s)); 
     root.setUserData(ol); 

     Scene scene = new Scene(root); 
     stage.setScene(scene); 

     //show the stage 
     stage.show(); 
    } 
} 

該類適用於切換場景。 現在的問題是我有時需要將數據從Scene1傳遞到Scene2。我試圖通過設置setUserData()來實現這一點,這個新場景基本上可以免除一件事情。如何在新場景初始化時獲取用戶數據? (因爲節點仍然空當時)在SCENE1

代碼:在SCENE2

//Code connected to a button that opens the new Scene 
private void openLabID(ActionEvent event) throws Exception {  
    final Stage primaryStage = (Stage) btnNewScene.getScene().getWindow(); 

    ObservableList<Koe> olAfTeWerkenKoeien = DA_Koe.getAfTeWerkenKoeien(); 
    ss.setScene(primaryStage, "GUI/scenes/koe/Koe.fxml", olAfTeWerkenKoeien); 
} 

代碼:

當然
public void initialize(URL url, ResourceBundle rb) { 
    Scene s = lbl.getScene(); 
    ObservableList<Koe> olAfTeWerkenKoeien = (ObservableList<Koe>) s.getRoot().getUserData(); 
    System.out.println(olAfTeWerkenKoeien.size()); 
} 

場景s的這一點上給出了一個空值(因爲lbl在這一點上是空的),所以我想知道,是否有一種方法在初始化後立即被解僱?

當我將此代碼附加到Scene2上的按鈕時,它的作用就像一個魅力,但它應該自動加載。

編輯: 數據與setMyData()方法中的設置是沒有問題的,但是檢索,它是:

public ObservableList<Koe> getMyData() { 
    return this.myData; 
} 

我怎樣才能獲得CustomScene對象時,控制器初始化?因爲這樣做下面這將導致一個NullPointerException(因爲btnSluiten沒有初始化,只是還沒有):

@Override 
public void initialize(URL url, ResourceBundle rb) { 
    ... 
    Stage stage = (Stage) btnSluiten.getScene().getWindow(); 
    CustomScene cs = (CustomScene) stage.getScene(); 

    ObservableList<Koe> olKoe = cs.getMyData(); 

    System.out.println(olKoe.size()); 
} 

回答

2

我相信你錯過了場景物體內的點。從Scene類文檔中我們可以看到:

JavaFX Scene類是場景圖中所有內容的容器。

這意味着Scene對象只是一個容器,因此它不應該保存任何數據。記住

就這樣,你可以用這樣一個領域的又一靜態對象

private static Label lbl; 

... 

public static Label getLbl() 
{ 
    return MyStaticObject.Lbl; 
} 

... 

,並用它來存儲您的LBL(或任何對象適合你的信息),然後靜態地檢索。

我正在做,從我的應用程序設置我的其他舞臺對象的所有者。我希望它有幫助。乾杯

+0

嗨布魯諾,感謝您指出,但什麼是最好的解決方案,然後創建一個有很多不同的應用程序(使用這裏的Java等價物)'JInternalFrames'?我知道Stage對象可以使用,但是這給了我們額外的窗口,這不是我想要的視圖。最好的解決方案是有一個場景,並與多個面板一起工作,只顯示/隱藏它們? – Perneel 2012-07-17 10:38:38

+0

看起來像最好的方法,你將只有一個場景,因爲我們正在談論JavaFX 2,你可以添加一些eyecandy像一個面板之間的另一個漂亮的過渡 – 2012-07-17 11:34:27

+0

作爲一個警告靜態數據是一個邊界黑客。如果你使用單例方法,它可以工作,但如果你進入共享空間,你就會遇到麻煩。你可能會考慮一個注射方案或其他東西來保存它。 (再次,單身人士會好起來的)。我玩的是類似的問題,但我的方法(迄今爲止)是從資源調用初始化方法。例如scene.initalize(somePojo); – 2012-07-17 15:38:02

2

如果你真的想你的場景是有意義的(又名存儲特定的用戶數據),你可以擴展它:

public class FooScene extends Scene { 
    private ObservableList myData; 

    public setMyData(ObservableList data) { 
     this.myData = data; 
     //handle data 
    } 
} 

,以確保安裝程序代碼最簡單的方法一幕初始化它來調用它被稱爲自己:

public class SceneSelector { 
    ... 
    public void setScene(Stage stage, String fxmlfilename, ObservableList ol) throws Exception{ 
     String s = "../" + fxmlfilename; 
     Parent root = FXMLLoader.load(getClass().getResource(s)); 

     // first: add root to scene 
     FooScene scene = new FooScene(root); 
     // second: apply data to scene (or root) 
     scene.setMyData(ol); 
     stage.setScene(scene); 

     //show the stage 
     stage.show(); 
    } 
} 
+0

嗨謝爾蓋,這確實是一個好主意。然而,這仍然導致同樣的問題,我無法從控制器的initialize()方法獲取Scene對象?或者我在這裏錯過了什麼? – Perneel 2012-07-17 11:08:57

+0

我明白了。我錯過了你正在通過fxml加載場景的問題。等一下,我會更新答案。 – 2012-07-17 11:41:04

+0

好的,在此先感謝:) – Perneel 2012-07-17 17:01:41

1

您可以使用控制器的場景,並通過控制器傳遞數據:

String filePath1 = "../" + fxmlfilename; 
URL location1 = YourController1.class.getResource(filePath1); 
FXMLLoader fxmlLoader = new FXMLLoader(); 
fxmlLoader.setLocation(location1); 
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory()); 
Parent root = (Node) fxmlLoader.load(location1.openStream()); 

YourController1 ctrl1 = (YourController1) fxmlLoader.getController(); 

然後你就可以將數據分配到控制器:

ctrl1.setUserData(); 

最後,只是展會現場,只要你想:

Scene scene = new Scene(root); 
stage.setScene(scene); 

//show the stage 
stage.show(); 

在控制器初始化()方法,就得到控制器數據像往常一樣數據對象。

+0

謝謝...您拯救了我的生命:P – 2015-06-10 19:52:00

+0

任何想法爲什麼userData在「初始化」方法其他控制器? – FelipeKunzler 2016-10-23 00:23:37

+0

您必須在控制器初始化後設置對象,在初始化過程中,userData對象應該爲空。 – Thinhbk 2016-10-24 02:18:59

相關問題