gpt4 book ai didi

java - a.disableProperty().bind(b.visibleProperty()) 导致 Java FX 10 中的元素呈现无效

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:32:39 26 4
gpt4 key购买 nike

这是 Java 10 中的回归,请参阅错误报告以获取进一步更新:JDK-8204949


考虑以下 Java FX 代码,其中 b 开始不可见:a.disableProperty().bind(b.visibleProperty())

如果使用此类代码的应用程序在 Java 10 VM 上运行,那么从 b 第一次可见时,a 将始终呈现为已禁用。

当然,在 a 并未真正禁用期间(尽管呈现为灰色覆盖层),您仍然可以与该元素进行交互。例如。您可以在输入控件中编辑文本,单击按钮/链接等,事件得到正确传播等。

如果应用程序在 Java 8 VM 上运行,它会按预期工作。

我目前没有 EOS Java 9,所以我只测试了:

  • Windows 10 x64 专业版 1709 和 1803
  • Java 8u172 x64(在 JDK 和 JRE 上都明确针对可执行文件)
  • Java 10u1 x64(在 JDK 和 JRE 上都明确针对可执行文件)

Java 10 的外观示例: Invalid render example in Java 10

b 有机会变得可见之前,它在第一次启动时的样子: enter image description here


一个 SSCCE(对于一个有点晦涩的问题是强制性的;a 将是 propertyProviderb 将是 invalidRenderFieldinvalidRenderButton):

package application;

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Accordion;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.VBox;

public class Main extends Application {
@Override
public void start(Stage primaryStage) {
System.out.println("Executing start(Stage) in " + Thread.currentThread().getName());
try {
TextField invalidRenderField = new TextField();
Button invalidRenderButton = new Button("Click to reproduce");
Label propertyProvider = new Label();
propertyProvider.setVisible(false);
VBox invalidRenderParent = new VBox(invalidRenderField, invalidRenderButton, propertyProvider);
TitledPane invalidRenderPane = new TitledPane("Incorrectly rendered elements", invalidRenderParent);
Accordion root = new Accordion(invalidRenderPane);
root.setExpandedPane(invalidRenderPane);

invalidRenderField.disableProperty().bind(propertyProvider.visibleProperty());
invalidRenderButton.disableProperty().bind(propertyProvider.visibleProperty());
invalidRenderButton.setOnAction(e -> {
System.out.println("Executing 1st onAction(ActionEvent) in " + Thread.currentThread().getName());

propertyProvider.setVisible(true);
propertyProvider.setText("At this point of time you cannot modify the field or click the button");

Task<Void> task = new Task<>() {
@Override
protected Void call() throws Exception {
System.out.println("Executing non-JFX code in " + Thread.currentThread().getName());
Thread.sleep(3_000L);
return null;
}
};
task.setOnSucceeded(e2 -> {
System.out.println("Executing onSuccess(WorkerStateEvent) in " + Thread.currentThread().getName());

propertyProvider.setVisible(false);

Label infoLabel = new Label("Either click the button below or just select the previous pane within the accordion");
Button closePlaceholderButton = new Button("View failure");
VBox placeholder = new VBox(infoLabel, closePlaceholderButton);
TitledPane placeholderPane = new TitledPane("Placeholder", placeholder);

closePlaceholderButton.setOnAction(e3 -> {
System.out.println("Executing 2nd onAction(ActionEvent) in " + Thread.currentThread().getName());
root.getPanes().remove(placeholderPane);
root.setExpandedPane(invalidRenderPane);
});

root.getPanes().add(1, placeholderPane);
root.setExpandedPane(placeholderPane);
});
new Thread(task, "WhateverThread").start();
});

Scene scene = new Scene(root, 800, 450);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
System.out.println("Executing main(String[]) in " + Thread.currentThread().getName());
launch(args);
}
}

单击“单击以重现”一次后的 SSCCE 输出:

Executing main(String[]) in main
Executing start(Stage) in JavaFX Application Thread
Executing 1st onAction(ActionEvent) in JavaFX Application Thread
Executing non-JFX code in WhateverThread
Executing onSuccess(WorkerStateEvent) in JavaFX Application Thread

正如预期的那样,JavaFX 代码在指定的线程上执行。


问题是,我是不是做错了什么和/或遗漏了什么明显的东西?我似乎找不到此代码的任何“错误”,它看起来很合理,但它出现故障。这是一个错误吗(我需要 lrn2search)?

总而言之,欢迎提出解决方法的任何建议。我需要此代码(或通过变通方法实现的等效代码)才能在 Java 10 上运行,没有任何借口。

最佳答案

首先,我想确认我观察到的行为与您相同。

  • Windows 10 x64 家庭版
  • Java 1.8.0_172 x64 -- 按预期工作
  • Java 10.0.1 x64 -- 失败(显示为禁用但实际上并未禁用)

这似乎是一个错误,您应该这样报告它。


可能的解决方法

我发现如果您将以下代码添加到所有受影响的节点,则有问题的节点将正确呈现:

node.disableProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue) { // if no longer disabled
node.applyCss();
}
});

如果您有很多节点可以禁用并且受问题中描述的相同事件序列的影响,这可能会变得乏味。创建某种类型的实用方法来处理这个问题可能是明智的。

编辑

我发现使 propertyProvider 不可见的顺序会影响我提供的解决方法。如果您在显示新的 TitledPane 之后 使 propertyProvider 不可见,那么当您返回到另一个 TitledPane 时, TextFieldButton 在未禁用时仍呈现为禁用状态。还没有找到解决方法。

关于java - a.disableProperty().bind(b.visibleProperty()) 导致 Java FX 10 中的元素呈现无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50800612/

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