6

我想在 JavaFX 应用程序中禁用特定时间的按钮。有什么选择吗?如果没有,是否有任何解决方法?

以下是我在应用程序中的代码。我试过Thread.sleep了,但我知道这不是阻止用户点击下一步按钮的好方法。

nextButton.setDisable(true);
final Timeline animation = new Timeline(
        new KeyFrame(Duration.seconds(delayTime),
        new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                nextButton.setDisable(false);
            }
        }));
animation.setCycleCount(1);
animation.play();
4

4 回答 4

6

您可以使用提供相关 GUI 调用的线程的简单方法(runLater()当然通过):

new Thread() {
    public void run() {
        Platform.runLater(new Runnable() {
            public void run() {
                myButton.setDisable(true);
            }
        }
        try {
            Thread.sleep(5000); //5 seconds, obviously replace with your chosen time
        }
        catch(InterruptedException ex) {
        }
        Platform.runLater(new Runnable() {
            public void run() {
                myButton.setDisable(false);
            }
        }
    }
}.start();

这可能不是实现它的最简洁的方法,但可以安全地工作。

于 2013-06-04T14:16:02.620 回答
5

您也可以使用Timeline

  final Button myButton = new Button("Wait for " + delayTime + " seconds.");
  myButton.setDisable(true);

  final Timeline animation = new Timeline(
            new KeyFrame(Duration.seconds(delayTime),
            new EventHandler<ActionEvent>() {
                @Override public void handle(ActionEvent actionEvent) {
                    myButton.setDisable(false);
                }
            }));
  animation.setCycleCount(1);
  animation.play();
于 2013-06-04T14:49:28.143 回答
2

禁用 JavaFX 控件的方法是:

myButton.setDisable(true);

您可以按您希望的任何方式以编程方式实现时间逻辑,方法是轮询计时器或调用此方法以响应某个事件。

如果您在 SceneBuilder 中通过 FXML 创建了此按钮实例,则应为该按钮分配一个 fx:id,以便在加载场景图期间将其引用自动注入您的控制器对象。这将使您更容易在控制器代码中使用。

如果您以编程方式创建了此按钮,那么您的代码中就已经有了它的引用。

于 2013-06-04T13:58:00.040 回答
0

或者您可以使用服务并将运行属性绑定到您要禁用的按钮的 disableProperty。

public void start(Stage stage) throws Exception {
    VBox vbox = new VBox(10.0);
    vbox.setAlignment(Pos.CENTER);      

    final Button button = new Button("Your Button Name");
    button.setOnAction(new EventHandler<ActionEvent>() {            
        @Override
        public void handle(ActionEvent event) {
            Service<Void> service = new Service<Void>() {                   
                @Override
                protected Task<Void> createTask() {
                    return new Task<Void>() {
                        @Override
                        protected Void call() throws Exception {
                            Thread.sleep(5000);//Waiting time
                            return null;
                        }
                    };
                }
            };
            button.disableProperty().bind(service.runningProperty());               
            service.start();
        }
    });     

    vbox.getChildren().addAll(button);
    Scene scene = new Scene(vbox, 300, 300);
    stage.setScene(scene);
    stage.show();
}

但是 Uluk Biy 给出的 Timeline 解决方案,看起来更加优雅。

于 2013-06-04T15:03:11.593 回答