2012-07-16 267 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

相关问题