【问题标题】:JavaFX widthProperty not refreshingJavaFX widthProperty 不刷新
【发布时间】:2015-09-12 05:04:19
【问题描述】:

我正在开发一个 javaFX 项目,在该项目中我需要精确控制 Node 的大小。 我的代码当前在需要时正确更新了 prefWidthProperty,并且最小和最大尺寸设置为使用 pref 尺寸,但 widthProperty 没有更新。

我已经通过将打印语句添加为属性的侦听器来验证这一点。 PrefWidthProperty 更新,widthProperty 不更新(直到我单击节点,可能获得焦点?)

我尝试在其自身及其父级上请求布局,与焦点相同,但没有成功。

我目前真的不知道如何修复这个非常烦人的错误。似乎目前一切都落后于 1 个布局传递。

用于设置大小和检查更改的代码:

//Set the size
this.setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
this.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
this.prefWidthProperty().bind(getTotalWidthProperty());

public ObservableValue<? extends Number> getTotalWidthProperty() {       
    return rightArgument.layoutXProperty().add(rightArgument.translateXProperty()).add(rightArgument.widthProperty()).add(H_GAP);
}

//Check for change:
this.prefWidthProperty().addListener(p -> System.out.println("FB_Pref_"+System.currentTimeMillis() + "  " + this.getPrefWidth()));
this.widthProperty().addListener(p -> System.out.println("FB______"+System.currentTimeMillis() + "  " + this.getWidth()));

如前所述,FB_Pref 会按时正确打印,而 FB_____ 打印得太晚了。

【问题讨论】:

  • 能否提供更多代码?
  • 您还想看哪些部分?我添加了一些关于如何设置 prefWidthProperty 的内容。

标签: java user-interface layout properties javafx


【解决方案1】:

如果您将 min/max 设置为 pref,这将创建一个固定大小的节点。在第一个布局阶段将包括最小/最大/首选尺寸。宽度“属性”反映了节点上当前设置的宽度。因此,如果您不更改宽度,您的侦听器将永远不会收到事件。您可以使用 getWidth sysout 宽度,这总是返回当前宽度。

JavaFX 中有两种类型的侦听器,一种是变更侦听器,一种是失效侦听器。您添加了一个带有 lambda 的失效侦听器。这个仅在需要时触发,而不是在每次更改时仅在重新布局时触发。在这里查看更多信息:http://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm#sthref12

试试这个:

this.prefWidthProperty().addListener(
        (ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
          System.out.println("FB_Pref_" + System.currentTimeMillis() + "  " + this.getPrefWidth());
        });

this.widthProperty().addListener(
        (ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
          System.out.println("FB______" + System.currentTimeMillis() + "  " + this.getWidth())
        });

【讨论】:

  • 遗憾的是,这对我没有任何改变:(如果可能的话,我想设置 widthProperty,但这是只读的,所以不可能。我有想法在 prefWidthProperty 更改时调用 setWidth() 方法,但这也没有效果。
  • 您想如何更改 prefWidth?它与另一个节点有关吗? setWidth 方法在 widthProperty 上完成了它的工作,因此您可以设置它。
  • 好的,所以在 prefWidthProperty 更改上设置宽度确实会触发 widthProperty 侦听器,并且还会更新 Node 的 getWidth()。但是,它不会在视觉上更新节点。事实上,它会导致 RunTimeExceptions,设置一个绑定值(我没有直接接触)。我有一种感觉,这正在接近真正的问题......
  • 我有一个节点,其中包含宽度所基于的元素,这些元素可以改变很多,所以我(想要)使用绑定来控制大小。该节点依次包含在 StackPane 中,包含在自定义控制器中。 StackPane 也不会更新其宽度。
  • 啊,你想让你的舞台内的组件在你的窗口被调整大小时调整大小?
【解决方案2】:

这是一个很长的延迟回答这个问题。当我对 prefWidthPropertyprefHeightProperty 执行类似的绑定任务时,我发现了一个解决方案。节点的宽度/高度似乎是首选尺寸之后的一个布局步骤。执行以下操作将解决它(假设 this 扩展了 Node):

prefWidthProperty.addListener((observable, oldValue, newValue) -> {
    Platform.runLater(() -> getParent().requestLayout());
};

由于某种原因,稍后在 Application 线程上执行 Runnable 可以正常工作。每次设置首选维度时,无论如何都会在Region 类的MinPrefMaxPropertyinvalidated() 方法中调用requestLayout()。这只是再次强制更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-18
    • 2012-06-08
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    相关资源
    最近更新 更多