创建特定类型的组

时间:2018-05-10 19:36:57

标签: javafx javafx-8

我使用SubScene创建了一个简单的3D查看器,并将3D对象添加到顶级根项目。

XDocument xml = XDocument.Parse(@"C:\Path\To\data.xml");
InvoiceModel invoice = xml.Descendants("invoice")
                       .Select(x => new InvoiceModel 
                       {
                         InvoiceId = x.Element("id").Value.ToString(),
                         InvoiceDate = x.Element("date").Value.ToString(),
                         InvoiceAmount = x.Element("amount").Value.ToString()
                       }).FirstOrDefault();

调用用户Viewer的代码然后可以获取root用户,创建3D对象并将其添加到根目录。这很好用。

但是,我意识到由于需求,我需要在逻辑上将根分成三个独立的区域。根转为:

public class Viewer extends AnchorPane {
   private final PerspectiveCamera camera = new PerspectiveCamera(true);
   private final Group root = new Group(camera)

   public Viewer() {
      SubScene scene = new SubScene(root, 300, 300, true, SceneAntialiasing.BALANCED);
   }

   public Group getRoot() {
      return root;
   }

调用代码可以通过上述组的getter添加多个摄像机,灯光,3D对象。

问题: 如果我向每个组提供带有getter的调用代码,那么调用代码也需要不断地将组中的节点强制转换为给定类型(例如cameraGroup中的Cameras)。调用代码也可以向Group添加非摄像头类型,因为JavaFX中的很多东西都继承了常见的Node基类型,而这正是Group使用的。

提供将组转换为每种类型的列表/可观察列表的单独的getter,setter,removers等会使接口复杂化。

有没有办法成立一个团体?即一组特定类型?或者我的设计有不同的方式吗?

1 个答案:

答案 0 :(得分:0)

Group不是通用的,所以没有直接的方法来做你想做的事。

但是,您可以保留单独的ObservableList并公开它们(而不是Group s),并向其注册监听器以保留组'子节点列表同步:

public class Viewer {

    private final PerspectiveCamera camera = new PerspectiveCamera();
    private final ObservableList<Camera> cameras = FXCollections.observableArrayList();
    private final Group cameraGroup = new Group();

    // etc

    public Viewer() {
        cameras.addListener((Change<? extends Camera> c) -> {
            while (c.next()) {
                if (c.wasAdded()) {
                    cameraGroup.getChildren().addAll(c.getAddedSubList());
                }
                if (c.wasRemoved()) {
                    cameraGroup.getChildren().removeAll(c.getRemoved());
                }
            }
        });

        cameras.add(camera);

        // etc

    }

    public ObservableList<Camera> getCameras() {
        return cameras ;
    }

}

替代解决方案(基本上是您描述的解决方案)是定义特定的addCamera()removeCamera()等方法,并且只公开不可修改的列表:

public class Viewer {

    public final PerspectiveCamera camera = new PerspectiveCamera();

    public final Group cameraGroup = new Group(camera);

    public final void addCamera(Camera camera) {
        cameraGroup.getChildren().add(camera);
    }

    public boolean removeCamera(Camera camera) {
        return cameraGroup.getChildren().remove(camera);
    }

    public List<Camera> getCameras() {
        List<Camera> cameras = new ArrayList<>();
        for (Node n : cameraGroup.getChildren()) {
            cameras.add((Camera)n);
        }
        return Collections.unmodifiableList(cameras);
    }

    // etc...
}