Javafx 创建特定类型的组
我使用子场景创建了一个简单的3D查看器,并将3D对象添加到顶级根项目中Javafx 创建特定类型的组,javafx,javafx-8,Javafx,Javafx 8,我使用子场景创建了一个简单的3D查看器,并将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 Sub
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;
}
调用代码,用户可以通过查看器获取根,创建3D对象并将其添加到根。这很有效
然而,我意识到,由于需求,我需要从逻辑上将根划分为三个独立的区域。根变成:
private final Group cameraGroup = new Group(camera);
private final Group lightGroup = new Group();
private final Group objectsGroup = new Group();
private final Group root = new Group(cameraGroup, lightGroup, objectsGroup);
调用代码可以通过上述组的getter添加多个摄影机、灯光、3D对象
问题:
如果我为每个组提供带有getter的调用代码,那么调用代码还需要不断地将组中的节点强制转换为给定类型(例如cameraGroup中的摄影机)。调用代码还可以将非摄影机类型添加到组中,因为JavaFX中的许多内容都继承自公共节点基类型,而这正是组所使用的
提供单独的getter、setter、remover等,将组转换为每种类型的列表/可观察列表,这会使接口复杂化
有没有办法组建一个团队?i、 e.特定类型的一组?或者我的设计有不同的方法吗?
Group
不是通用的,所以没有直接的方法来做你想做的事情
但是,您可以保留单独的可观察列表
s并公开它们(而不是组
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 ;
}
}
你的答案正是我想要的:@koolbanana与第二个选项大致相同。注意:1。对于每个
组
,不需要一个包装器,您只需将查看器
用作所有组的单个包装器即可。该选项无法解决客户端代码的向下转换问题。
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...
}