Свойство генератора пользовательских действий для пользовательского компонента JavaFX - Как? - PullRequest
0 голосов
/ 16 января 2020

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

В моем приложении есть несколько пользовательских компонентов, поэтому я могу построить более сложную сцену. Эта проблема включает в себя 3 компонента управления; компонент PrimaryControl (SplitPane), который содержит MenuComponent и ActivityComponent (оба настраиваемые), который изменяется в зависимости от выбора переключателей, установленных в MenuComponent.

Как я могу заставить класс MenuControl «излучать» выполнил действие, когда радиокнопка в ToggleGroup (из этого компонента) была изменена, что затем будет обработано функцией в родительском компоненте PrimaryControl, чтобы он мог изменить, какой ActivityComponent является видимым / активным? Потерпи меня.

primary_control.f xml

<fx:root type="javafx.scene.layout.VBox" xmlns:fx="http://javafx.com/fxml">
    <MenuControl onToggleGroupButtonSelectionChanged="#onChange"/>
    <ActivityOneControl fx:id="one" isVisible="true"/>
    <ActivityTwoControl fx:id="two" isVisible="false"/>
    ...
</fx:root>

menu_control.f xml

<fx:root type="javafx.scene.layout.VBox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/10.0.2-internal">

    <GridPane alignment="CENTER" hgap="10" vgap="10">
        <padding><Insets bottom="25" left="25" right="25" top="15" /></padding>
        <Label text="Select A Task" GridPane.columnIndex="0" GridPane.rowIndex="0">
            <font><Font name="System Bold" size="13.0" /></font>
        </Label>

        <fx:define>
            <ToggleGroup fx:id="menuSelection"/>
        </fx:define>

        <RadioButton fx:id="one" text="one" GridPane.columnIndex="0" GridPane.rowIndex="1" toggleGroup="$menuSelection">
        </RadioButton>
        <RadioButton fx:id="two" text="two" GridPane.columnIndex="0" GridPane.rowIndex="2" toggleGroup="$menuSelection">
        </RadioButton>
        <RadioButton fx:id="three" text="three" GridPane.columnIndex="0" GridPane.rowIndex="3" toggleGroup="$menuSelection">

        </RadioButton>
    </GridPane>

</fx:root>

Как создать слушателя в моем MenuControl java класс, который сможет обнаружить изменение выбора ToggleGroup, а затем передать это изменение на onToggleGroupButtonSelectionChanged="#onChange", чтобы я мог обработать выбор кнопки из класса PrimaryControl java? Я помню, как делал подобные вещи в Angular, и это было довольно легко, но по какой-то причине я не могу найти никакой информации о том, как это сделать, - Java. Это то, что известно как внедрение зависимостей?

Я нашел эту ссылку и попытался реализовать ее для своей проблемы, но безуспешно, так как ничего не было объяснено и прослушивалось другое событие для JavaFX 2.0 - создать обработчик действий для пользовательских компонент в F XML.

PrimaryController. java (аналогично MenuControl. java)

public class PrimaryControl extends VBox {

    public DashboardControl() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("primary_control.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    @FXML
    protected void onChange() {
        System.out.println("change activity");
    }
}

Заранее благодарим всех, кто мне помогает с этим.

1 Ответ

1 голос
/ 17 января 2020
  • Сначала создайте перечисление, которое представляет возможные варианты выбора:
public enum SelectionMode {
    ONE, TWO, THREE
}
  • Теперь добавьте свойство в элемент управления Menu, которое дает другим элементам управления возможность узнать, что выбирается, не открывая логи c позади нее или не изменяя их из других элементов управления (используя ReadOnlyObjectProperty):
private ReadOnlyObjectWrapper<SelectionMode> selectionMode
    = new ReadOnlyObjectWrapper<>(this, "selectionMode");

public final ReadOnlyObjectProperty<SelectionMode> selectionModeProperty() {
    return selectionMode.getReadOnlyProperty();
}

private final SelectionMode getSelectionMode() {
    return selectionMode.get();
}
  • Свяжите это свойство с выбранным переключателем в Метод класса контроллера initialize. Обратите внимание, что я использую методы setUserData и getUserData, в противном случае вам необходимо иметь условие if для каждой имеющейся у вас кнопки-переключателя:
@Override
public void initialize(URL location, ResourceBundle resources) {
    one.setUserData(SelectionMode.ONE);
    two.setUserData(SelectionMode.TWO);
    three.setUserData(SelectionMode.THREE);

    selectionMode.bind(Bindings.createObjectBinding(() -> {
        Toggle selectedToggle = menuSelection.getSelectedToggle();
        return (SelectionMode) selectedToggle.getUserData();
    }, menuSelection.selectedToggleProperty()));
}
  • Ваш основной контроллер Класс может получить доступ к своему контроллеру Меню, установив идентификатор в <MenuControl fx:id="menu"/>. Затем вы можете просто назначить ChangeListener и получать уведомления при каждом изменении выбора:
menu.selectionModeProperty().addListener((observable, oldValue, newValue) -> {
    // write your code here
});

Примечание : вы можете инициализировать пользовательские данные в вашем f xml вот так (вместо того, чтобы делать это в методе initialize):

<RadioButton fx:id="one" text="one" toggleGroup="$menuSelection">
    <userData>
        <SelectionMode fx:constant="ONE"/>
    </userData>
</RadioButton>
<RadioButton fx:id="two" text="two" toggleGroup="$menuSelection">
    <userData>
        <SelectionMode fx:constant="TWO"/>
    </userData>
</RadioButton>
<RadioButton fx:id="three" text="three" toggleGroup="$menuSelection">
    <userData>
        <SelectionMode fx:constant="THREE"/>
    </userData>
</RadioButton>
...