gpt4 book ai didi

javafx-2 - 如何可靠地获取 JavaFX 标签或工具栏的边界?

转载 作者:行者123 更新时间:2023-12-02 17:09:12 25 4
gpt4 key购买 nike

下面的示例代码。这对所有内容输出全零。对于工具栏,它还显示零。对于文本,它输出非零宽度和高度。这是 Label 上的错误还是故意的?我应该做些什么来让标签有其界限吗?我尝试过其他线程、移动、各种事情。

注意:所有节点都按预期显示。这只是边界的获取不起作用。

我看到一些关于可能在boundsInParent属性上使用监听器的内容。当我尝试这样做时,许多事件中的数字都会波动,因此似乎没有办法确定我何时会获得正确的值。

import javafx.application.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;


public class TestBounds extends Application {
public static void main(String[] args) {
launch(args);
}

public void start(Stage stage) {
Pane root = new Pane();
Group g = new Group();
root.getChildren().add(g);

Scene scene = new Scene(root, 500, 500);
stage.setScene(scene);
stage.show();

Platform.runLater(() -> {
// Text text = new Text("test label");
// ToolBar text = new ToolBar(new Button("test label"));
Label text = new Label("test label");
g.getChildren().add(text);
System.out.println(text.getBoundsInParent());
System.out.println(text.getBoundsInLocal());
System.out.println(text.getLayoutBounds());
});
}
}

@sarcan 的答案是一个好的开始,但它并不完整。这是一个例子:

package other;

import javafx.application.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.*;


public class Main extends Application {

@Override
public void start(Stage stage) {
Pane root = new Pane();
final Group g = new Group();
root.getChildren().add(g);

Scene scene = new Scene(root, 500, 500);
stage.setScene(scene);
stage.show();

Platform.runLater(() -> {
final Label text = new Label("test label");
g.getChildren().add(text);
new Thread(() -> {
Platform.runLater(() -> {
System.out.println("text.getWidth() = " + text.getWidth());
System.out.println(text.getBoundsInParent());
System.out.println(text.getBoundsInLocal());
System.out.println(text.getLayoutBounds());
});
}).start();
});
}

public static void main(String[] args) {
launch(args);
}
}

您可以删除 new Thread() 部分,它仍然会显示问题。我把它放在那里只是为了表明我真的想按照建议“推迟”它。上面的示例按照建议使用了 runLater,但仍然演示了该问题。边界全部输出为 0。

上面的例子很常见——当已经在 FX 线程中并且需要访问其边界时添加一个节点。但是,如何可靠地延迟以便在场景更新后获得这些边界呢? Platform.runLater 显然没有这样做。

最佳答案

这里的问题是您将文本添加到其父级,然后立即查询其坐标。 JavaFX 和大多数其他工具包的工作方式与您预期的有点不同:添加标签时,场景图不会立即更新。相反,它被标记为“脏”。当 JavaFX 应用程序线程存在于您的 block 中时,它将执行更新,包括布置您的组并相应地设置标签的边界。

这样做的原因很简单。如果JavaFX立即更新场景图,不仅会造成浪费,还会导致奇怪的结果。假设您要添加 20 个标签,这会触发 20 个立即更新。由于这些发生得非常快,用户界面会闪烁。相反,发生的情况是您添加 20 个标签,这会导致 ui 被标记为脏 20 次(这非常便宜),然后所有更改都将应用在一次更新中。将 runLater block 视为“向 JavaFX 描述您希望 ui 在下一次原子更新后的外观”。

现在,话虽这么说,如果您想获取文本的范围,只需首先给 JavaFX 一个更新的机会即可。例如,如果您将添加的文本移到 runLater block 前面,则会添加文本,更新场景图,然后您将查询坐标 - 这将产生正确的结果:

public void start(Stage stage) {
Pane root = new Pane();
final Group g = new Group();
final Label text = new Label("test label");
g.getChildren().add(text);
root.getChildren().add(g);

Scene scene = new Scene(root, 500, 500);
stage.setScene(scene);
stage.show();

Platform.runLater(new Runnable() {
public void run() {
System.out.println("text.getWidth() = " + text.getWidth());
System.out.println(text.getBoundsInParent());
System.out.println(text.getBoundsInLocal());
System.out.println(text.getLayoutBounds());
}
});
}

关于javafx-2 - 如何可靠地获取 JavaFX 标签或工具栏的边界?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17381686/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com