我的JavaFx应用程序中有两个控件 1. TextField 2. ListView
我想使用TextField的坐标将ListView放在TextField的正下方。 因为TextField的位置发生了变化。
详细信息:
我正在为我的项目创建自动建议文本字段,当用户在文本字段中输入内容时,需要弹出列表。该文本字段可能存在于场景中的任何位置,也可以在另一个列表视图中。所以我需要的是如何在屏幕上获取文本字段的坐标,以便我可以在文本字段的正下方放置列表视图。
答案 0 :(得分:0)
我在这里看到多个选项:
我认为你可能更善于使用ContextMenu
。当您显示ContextMenu
时,您可以定义一个视图,它应该相对于视图显示以及显示它的一侧。
如果ContextMenu
无法满足您的要求,我最简单的想法就是您将TextField
替换为VBox
并输入TextField
和ListView
中的VBox
。这将使他们在一起,您可以像定位VBox
一样定位TextField
。
最后,如果您想自己布局,TextField包含layoutX
和layoutY
以及height
和width
等属性。使用这些可以计算ListView的位置(例如ListView的Y位置为textField.layoutY + textField.height
)。为了使这个位置保持最新,我看到两个选项:
TextField
您可能已覆盖某些layoutChildrens
的{{1}}方法,因此您可以将此代码放在那里。Parent
,以便在他们更改并重新定位ListView时收到通知。答案 1 :(得分:0)
要获取屏幕坐标中文本字段的位置,可以执行
Bounds boundsInScreen = textField.localToScreen(textField.getBoundsInLocal());
这将返回一个Bounds
对象,您可以从中获取各种坐标,例如
Popup popup = ... ;
popup.setWidth(boundsInScreen.getWidth());
popup.show(textField, boundsInScreen.getMinX(), boundsInScreen.getMaxY());
答案 2 :(得分:0)
我创建了这个帮助类来做到这一点。
public class PositionUtils {
public static void position(Region movable, Region reference, Anchor movableAnchor, Anchor referenceAnchor, float xOffset, float yOffset) {
double x = reference.localToScene(reference.getBoundsInLocal()).getMaxX();
double y = reference.localToScene(reference.getBoundsInLocal()).getMaxY();
Point referencePoint = referenceAnchor.referencePoint;
Point movablePoint = movableAnchor.movablePoint;
x -= (0.5 * movable.getWidth()) * movablePoint.x;
y += (0.5 * movable.getHeight()) * movablePoint.y;
x += (0.5 * reference.getWidth()) * referencePoint.x;
y -= (0.5 * reference.getHeight()) * referencePoint.y;
movable.setLayoutX(x + xOffset);
movable.setLayoutY(y + yOffset);
}
public static void position(Pane movable, Pane reference, Anchor movableAnchor, Anchor referenceAnchor) {
position(movable, reference, movableAnchor, referenceAnchor, 0, 0);
}
public static void position(Pane movable, Pane reference, Side side) {
position(movable, reference, side, 0, 0);
}
public static void position(Pane movable, Pane reference, Side side, float xOffset, float yOffset) {
Anchor movableAnchor = null;
Anchor referenceAnchor = null;
switch (side) {
case TOP:
movableAnchor = Anchor.BOTTOM_CENTER;
referenceAnchor = Anchor.TOP_CENTER;
break;
case BOTTOM:
movableAnchor = Anchor.TOP_CENTER;
referenceAnchor = Anchor.BOTTOM_CENTER;
break;
case RIGHT:
movableAnchor = Anchor.CENTER_LEFT;
referenceAnchor = Anchor.CENTER_RIGHT;
break;
case LEFT:
movableAnchor = Anchor.CENTER_RIGHT;
referenceAnchor = Anchor.CENTER_LEFT;
break;
}
position(movable, reference, movableAnchor, referenceAnchor, xOffset, yOffset);
}
public enum Anchor {
TOP_LEFT(new Point(0, 0), new Point(-2, 2)),
TOP_CENTER(new Point(1, 0), new Point(-1, 2)),
TOP_RIGHT(new Point(2, 0), new Point(0, 2)),
CENTER_LEFT(new Point(0, -1), new Point(-2, 1)),
CENTER(new Point(1, -1), new Point(-1, 1)),
CENTER_RIGHT(new Point(1, -2), new Point(0, 1)),
BOTTOM_LEFT(new Point(0, -2), new Point(-2, 0)),
BOTTOM_CENTER(new Point(1, -2), new Point(-1, 0)),
BOTTOM_RIGHT(new Point(2, -2), new Point(0, 0));
public Point referencePoint;
public Point movablePoint;
Anchor(Point movablePoint, Point referencePoint) {
this.referencePoint = referencePoint;
this.movablePoint = movablePoint;
}
}
public enum Side {
TOP,
BOTTOM,
RIGHT,
LEFT
}
}