Включить / отключить групповые кнопки одновременно в JavaFX - PullRequest
1 голос
/ 22 октября 2019

Я хочу отключить несколько кнопок одного «типа» в JavaFX. Например, у меня есть несколько кнопок отмены для разных операций, но я бы хотел включить / отключить их все одновременно, но, похоже, я не могу получить к ним доступ внутри LinkedList.

В приведенном нижеПример «минимальный и воспроизводимый», при нажатии кнопки «Пуск» он должен активировать (отключить по умолчанию в fxml) кнопки отмены, но это не так.

DemoController.java

public class DemoController {
    @FXML
    Button startBtn;
    @FXML
    Button cancelBtn1; // disabled by default
    @FXML
    Button cancelBtn2; // disabled by default
    @FXML
    Tab tab1;

    public SDK sdk;

    List<Node> cancelBtnGroup = new LinkedList<Node>();

    public void initialize() {
        cancelBtnGroup.add(cancelBtn1);
        cancelBtnGroup.add(cancelBtn2);

        startBtn.setOnAction(event -> {
            tab1.setDisable(true);
            startBtn.setDisable(true);
            System.out.println("Disabling cancel buttons");
            HashMap<String, String> test = new HashMap<String, String>();
            test.put("disableCancel", "false");
            sdk.onEvent(test);
        });

        initializeSDK();
    }

    public void initializeSDK() {
        sdk = new SDK() {
            @Override
            public void onEvent(HashMap<String, String> e) {
                if(e.containsKey("disableCancel")) {
                    for(Node btn : cancelBtnGroup) {
                        btn.setDisable(Boolean.parseBoolean(e.get("disableCancel")));
                    }
                }
            }
        };
    }
}

Кажется, я как-то перезаписываю кнопки, но не вижу как. Я чувствую, что не понимаю сферу действия некоторых функций. Я пытался сделать код максимально простым и читабельным, поэтому, если я упускаю что-то чрезвычайно очевидное, может быть, поэтому. Объект SDK не содержит объектов с одинаковыми именами, чтобы быть уверенным, что проблема не в том, что я изменил имена.

Ответы [ 2 ]

3 голосов
/ 23 октября 2019

Из кода, который вы опубликовали, я не могу определить, почему он не работает. Тем не менее, вот минимальный пример использования подхода «отключить общий предок» и FXML:

App.java

package com.example;

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class App extends Application {

  @Override
  public void start(Stage primaryStage) throws IOException {
    var root = FXMLLoader.<Parent>load(getClass().getResource("/App.fxml"));
    var scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.show();
  }
}

App.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ToggleButton?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns="http://javafx.com/javafx/13" xmlns:fx="http://javafx.com/fxml/1"
      fx:controller="com.example.Controller" spacing="10" prefWidth="500" prefHeight="300"
      alignment="CENTER">

    <padding>
        <Insets topRightBottomLeft="10"/>
    </padding>

    <ToggleButton fx:id="toggleBtn"/>

    <HBox fx:id="container" alignment="CENTER" spacing="10">
        <Button text="Button #1"/>
        <Button text="Button #2"/>
        <Button text="Button #3"/>
        <Button text="Button #4"/>
    </HBox>

</VBox>

Controller.java

package com.example;

import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.HBox;

public class Controller {

  @FXML private ToggleButton toggleBtn;
  @FXML private HBox container;

  @FXML
  private void initialize() {
    toggleBtn.textProperty().bind(
        Bindings.when(toggleBtn.selectedProperty())
          .then("Disable Buttons")
          .otherwise("Enable Buttons")
    );
    container.disableProperty().bind(toggleBtn.selectedProperty().not());
  }
}

Примечание: Вместо привязки свойства контейнера disable вкод, описанный выше, также может быть выполнен с использованием:

<!-- Everything else omitted for brevity -->
<HBox disable="${!toggleBtn.selected}">

Конечно, если вы используете что-то отличное от ToggleButton, то реализация связывания в FXML может оказаться невозможной.

1 голос
/ 23 октября 2019

Проблема была в том, что я отключаю вкладку, которая отключает все кнопки в ней. Я этого не заметил, потому что у меня только 2 кнопки, одна из которых отключается в любом случае, а другая - нет. Мне показалось, что кнопка просто не отвечает.

Решение

Удалить tab1.setDisable(true)

Я былотключив все мои вкладки, чтобы в середине работы пользователь не мог переключать вкладки, но я забыл, что если вы отключите текущую вкладку, она также отключит кнопки.

Я хочу поблагодарить @Slaw за помощь и мириться смое отношение. (У меня был слишком много раздражающих опытов с SO раньше, поэтому у меня есть предрасположенность к ответам, которые публикуют одну и ту же раздражающую ссылку 1000 раз. Я знаю, что мне нужен минимальный воспроизводимый пример, но это не всегда легкоособенно если вы работаете с внешним SDK и уже обширным кодом. Я пытался сделать его минимальным и воспроизводимым.

...