自定义组件 JavaFX 的自定义操作发射器属性 - 如何?



在开发JavaFX应用程序项目的过程中,这是我第一次真正的绊脚石,我甚至不知道如何正确地说出我想要做什么,因为我不知道我试图使用的技术的名称。

在我的应用程序中,我有多个自定义组件,因此我可以构建更复杂的场景。此问题涉及 3 个控制组件;一个 PrimaryControl 组件 (SplitPane(,其中包含一个 MenuComponent 和一个 ActivityComponent(都是自定义的(,它根据在 MenuComponent 中设置的单选按钮的选择而变化。

当 ToggleGroup 中的单选按钮(来自该组件(发生更改时,如何让 MenuControl 类"发出"执行的操作,然后由父组件 PrimaryControl 中的函数处理,以便它可以更改哪个 ActivityComponent 可见/活动?请耐心等待。

primary_control.fxml

<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.fxml

<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 侦听不同的事件 - 为 FXML 中的自定义组件创建操作处理程序。

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");
}
}

提前感谢任何帮助我的人。

  • 首先,创建一个表示可能选择的枚举:
public enum SelectionMode {
ONE, TWO, THREE
}
  • 现在,向 Menu 控件添加一个属性,使其他控件能够知道所选内容,而无需公开其背后的逻辑或使其可从其他控件更改(使用ReadOnlyObjectProperty(:
private ReadOnlyObjectWrapper<SelectionMode> selectionMode
= new ReadOnlyObjectWrapper<>(this, "selectionMode");
public final ReadOnlyObjectProperty<SelectionMode> selectionModeProperty() {
return selectionMode.getReadOnlyProperty();
}
private final SelectionMode getSelectionMode() {
return selectionMode.get();
}
  • 将此属性绑定到 Menu 控制器类的initialize方法中的选定单选按钮。请注意,我使用的是setUserDatagetUserData方法,否则,您需要为每个单选按钮提供一个 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"/>中设置 id 来访问其菜单控制器。 然后,您只需分配一个ChangeListener,并在每次更改选择时收到通知:
menu.selectionModeProperty().addListener((observable, oldValue, newValue) -> {
// write your code here
});

注意:您可以像这样在 fxml 中初始化用户数据(而不是在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>

最新更新