【发布时间】:2018-02-06 17:37:09
【问题描述】:
我有一个示例 3D 应用程序(通过参考 Javafx 示例 3DViewer 构建),它有一个通过布局框和窗格创建的表:
表格以 (0,0,0) 坐标为中心,相机最初位于 -z 位置。
它具有基于对象的相机 z 位置的放大/缩小。 放大/缩小对象的 boundsInParent 增加/减少,即面部区域增加/减少。所以我们的想法是当我们有更多的区域(总是限制在面部)时放置更多的文本,而当面部区域太少时放置更少的文本或没有文本。我可以使用此节点层次结构来做到这一点:
并在每次放大/缩小时根据 Box 调整窗格的大小(并管理 vBox 和其中的文本数量)。
现在的问题是,每当第一次将文本添加到 vBox 时,表 boundsInParent 就会给出不正确的结果(table image 在顶部显示 boundingBox)。进一步放大/缩小会给出正确的边界框并且不会消失。
下面是 UIpane3D 类:
public class UIPane3D extends Pane
{
VBox textPane;
ArrayList<String> infoTextKeys = new ArrayList<>();
ArrayList<Text> infoTextValues = new ArrayList<>();
Rectangle bgCanvasRect = null;
final double fontSize = 16.0;
public UIPane3D() {
setMouseTransparent(true);
textPane = new VBox(2.0)
}
public void updateContent() {
textPane.getChildren().clear();
getChildren().clear();
for (Text textNode : infoTextValues) {
textPane.getChildren().add(textNode);
textPane.autosize();
if (textPane.getHeight() > getHeight()) {
textPane.getChildren().remove(textNode);
textPane.autosize();
break;
}
}
textPane.setTranslateY(getHeight() / 2 - textPane.getHeight() / 2.0);
bgCanvasRect = new Rectangle(getWidth(), getHeight());
bgCanvasRect.setFill(Color.web(Color.BURLYWOOD.toString(), 0.10));
bgCanvasRect.setVisible(true);
getChildren().addAll(bgCanvasRect, textPane);
}
public void resetInfoTextMap()
{
if (infoTextKeys != null || infoTextValues != null)
{
try
{
infoTextKeys.clear();
infoTextValues.clear();
} catch (Exception e){e.printStackTrace();}
}
}
public void updateInfoTextMap(String pKey, String pValue)
{
int index = -1;
boolean objectFound = false;
for (String string : infoTextKeys)
{
index++;
if(string.equals(pKey))
{
objectFound = true;
break;
}
}
if(objectFound)
{
infoTextValues.get(index).setText(pValue.toUpperCase());
}
else
{
if (pValue != null)
{
Text textNode = new Text(pValue.toUpperCase());
textNode.setFont(Font.font("Consolas", FontWeight.BLACK, FontPosture.REGULAR, fontSize));
textNode.wrappingWidthProperty().bind(widthProperty());
textNode.setTextAlignment(TextAlignment.CENTER);
infoTextKeys.add(pKey);
infoTextValues.add(textNode);
}
}
}
}
所有操作后最后调用的代码:
public void refreshBoundingBox()
{
if(boundingBox != null)
{
root3D.getChildren().remove(boundingBox);
}
PhongMaterial blueMaterial = new PhongMaterial();
blueMaterial.setDiffuseColor(Color.web(Color.CRIMSON.toString(), 0.25));
Bounds tableBounds = table.getBoundsInParent();
boundingBox = new Box(tableBounds.getWidth(), tableBounds.getHeight(), tableBounds.getDepth());
boundingBox.setMaterial(blueMaterial);
boundingBox.setTranslateX(tableBounds.getMinX() + tableBounds.getWidth()/2.0);
boundingBox.setTranslateY(tableBounds.getMinY() + tableBounds.getHeight()/2.0);
boundingBox.setTranslateZ(tableBounds.getMinZ() + tableBounds.getDepth()/2.0);
boundingBox.setMouseTransparent(true);
root3D.getChildren().add(boundingBox);
}
两件事:
第一次添加文本时,table3D 的 boundsInParent 没有正确更新。
在 3D 节点上放置文本的正确方法是什么?我必须进行大量操作才能根据需要提供文本。
分享码here.
【问题讨论】:
-
您最好分享代码,至少我们可以用来重现您的问题?
-
@JoséPereda 共享代码链接,主类:JFXApp.java