我使用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等会使接口复杂化。
有没有办法成立一个团体?即一组特定类型?或者我的设计有不同的方式吗?
答案 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...
}