gpt4 book ai didi

java - 如何增加 ToggleGroup 中可能选择的数量(例如 RadioButtons)?

转载 作者:行者123 更新时间:2023-12-02 12:15:40 26 4
gpt4 key购买 nike

我对编程和 OOP(现在是第二个 Java 项目)有点陌生,并且希望得到任何提示或帮助。

我目前正在为我自己的纸笔游戏开发角色创建程序。我正在使用JavaFX (没有 FXML,因此没有 SceneBuilder)GUI 部分。我正在 JDK1.8.0_131 上使用 Eclipse Neon。

这是我的问题:
tl;dr:如何增加 ToggleGroup 中可能选择的数量?
我将创建一个选项列表供用户选择。该列表包含大约 30 种不同的优势,他或她可以选择来改善他们的性格。允许的最大选项取决于字符,大约为 5。我已经实现了 pairs 的数组。 (我了解 HashMap),其中每个条目都是一对,由优势名称和表示其成本的整数组成(它们的值不同,因此成本也不同)。
列表本身现在应该通过

来实现
ScrollPane scrollAdv = new ScrollPane();
VBox vBoxAdv = new VBox();
scrollAdv.setContent(vBoxAdv);
Pair<String, Integer>[] listAdv = info.getAdvantages();
for (int i = 0; i < listAdv.length; i++) {
String name = listAdv[i].getKey(); // delivers the 1st entry of a pair
int costs = listAdv[i].getValue(); // delivers the 2nd entry of a pair
ToggleButton toggleButton = new ToggleButton();
toggleButton.setUserData(name);
toggleButton.setText(name + " (" + costs + ")");
vBoxAdv.getChildren().add(toggleButton);
}

请注意,我不太关心 ToggleButtons,它们可以轻松地用 RadioButtons 替换。如果我正确理解了文档,两者的工作方式是相同的。他们都使用 ToggleGroup 来确保只选择一个选项。
因此,虽然您现在可能已经猜到了,但我想做的是让用户能够同时选择多个选项。我不想这样做,因此用户必须选择一个又一个选项,同时重置之间的列表。

感谢您的阅读,并提前感谢您提供的任何帮助或提示。

编辑:我总是可以添加一个计数器,每当选择或取消选择一个选项时就会刷新,并阻止任何选择(如果它<1),但我认为应该有更好的解决方案,例如增加 ToggleGroup 似乎正在使用的内置限制 1。

最佳答案

一种方法是在达到限制时禁用剩余的切换。这是一个执行此操作的 ToggleSet 类:

import java.util.ArrayList;
import java.util.List;

import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.IntegerBinding;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.scene.Node ;
import javafx.scene.control.Toggle;

public class ToggleSet<T extends Node & Toggle> {

private final ObservableList<T> toggles = FXCollections.observableArrayList(t -> new Observable[] {t.selectedProperty()});
private final FilteredList<T> selectedToggles = toggles.filtered(t -> ((Toggle)t).isSelected());
private final IntegerProperty maximumSelectable = new SimpleIntegerProperty(0);

private final IntegerBinding numSelected = Bindings.size(selectedToggles);

public ToggleSet(int maximumSelectable) {

this.maximumSelectable.addListener((obs, oldMax, newMax) -> {
if (newMax.intValue() < numSelected.get()) {
List<Toggle> togglesToClear = new ArrayList<>(selectedToggles.subList(0, numSelected.get() - newMax.intValue()));
togglesToClear.forEach(t -> t.setSelected(false));
}
});

setMaximumSelectable(maximumSelectable);
}

public ToggleSet() {
this(0);
}

public ObservableList<T> getSelectedToggles() {
return FXCollections.unmodifiableObservableList(selectedToggles) ;
}

public IntegerProperty maximumSelectableProperty() {
return maximumSelectable ;
}

public final int getMaximumSelectable() {
return maximumSelectableProperty().get();
}

public final void setMaximumSelectable(int maximumSelectable) {
maximumSelectableProperty().set(maximumSelectable);
}

public void addToggle(T toggle) {
if (numSelected.get() >= getMaximumSelectable()) {
toggle.setSelected(false);
}
toggles.add(toggle);
toggle.disableProperty().bind(toggle.selectedProperty().not().and(numSelected.greaterThanOrEqualTo(maximumSelectable)));
}

public void removeToggle(T toggle) {
toggles.remove(toggle);
toggle.disableProperty().unbind();
}

}

这是一个测试它的示例:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Spinner;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class ToggleSetTest extends Application {

@Override
public void start(Stage primaryStage) {
ToggleSet<ToggleButton> toggleSet = new ToggleSet<>(5);
GridPane grid = new GridPane() ;

Spinner<Integer> maxSelectedSpinner = new Spinner<>(0, 20, 5);
maxSelectedSpinner.getValueFactory().valueProperty().bindBidirectional(toggleSet.maximumSelectableProperty().asObject());

grid.add(new HBox(2, new Label("Maximum selected"), maxSelectedSpinner), 0, 0, 2, 1);

grid.addRow(1, new Label("Selection"), new Label("Include in set"));

for (int i = 1; i <= 20 ; i++) {
RadioButton button = new RadioButton("Button "+i);
CheckBox checkBox = new CheckBox();
checkBox.selectedProperty().addListener((obs, wasChecked, isNowChecked) -> {
if (isNowChecked) {
toggleSet.addToggle(button);
} else {
toggleSet.removeToggle(button);
}
});
checkBox.setSelected(true);
grid.addRow(i + 1, button, checkBox);
}
grid.setPadding(new Insets(10));
grid.setHgap(5);
grid.setVgap(2);
Scene scene = new Scene(grid);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {
launch(args);
}
}

如果您想要与 ToggleGroup 相同的行为,即先前的选择变为取消选择,则有点棘手,但以下应该可以工作:

import java.util.ArrayList;
import java.util.List;

import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node ;
import javafx.scene.control.Toggle;

public class ToggleSet<T extends Node & Toggle> {

private final ObservableList<T> toggles = FXCollections.observableArrayList(t -> new Observable[] {t.selectedProperty()});
private final ObservableList<T> selectedToggles = FXCollections.observableArrayList();
private final IntegerProperty maximumSelectable = new SimpleIntegerProperty(0);

private final ChangeListener<Boolean> toggleListener = (obs, wasSelected, isNowSelected) -> {
@SuppressWarnings("unchecked")
T toggle = (T) ((Property<?>)obs).getBean();
if (isNowSelected) {
selectedToggles.add(toggle);
ensureWithinMax();
} else {
selectedToggles.remove(toggle);
}
};

public ToggleSet(int maximumSelectable) {

this.maximumSelectable.addListener((obs, oldMax, newMax) -> ensureWithinMax());
setMaximumSelectable(maximumSelectable);
}

private void ensureWithinMax() {
if (this.maximumSelectable.get() < selectedToggles.size()) {
List<Toggle> togglesToClear = new ArrayList<>(selectedToggles.subList(0, selectedToggles.size() - this.maximumSelectable.get()));
togglesToClear.forEach(t -> t.setSelected(false));
}
}

public ToggleSet() {
this(0);
}

public ObservableList<T> getSelectedToggles() {
return FXCollections.unmodifiableObservableList(selectedToggles) ;
}

public IntegerProperty maximumSelectableProperty() {
return maximumSelectable ;
}

public final int getMaximumSelectable() {
return maximumSelectableProperty().get();
}

public final void setMaximumSelectable(int maximumSelectable) {
maximumSelectableProperty().set(maximumSelectable);
}

public void addToggle(T toggle) {
if (toggle.isSelected()) {
selectedToggles.add(toggle);
ensureWithinMax();
}
toggle.selectedProperty().addListener(toggleListener);
toggles.add(toggle);
}

public void removeToggle(T toggle) {
toggle.selectedProperty().removeListener(toggleListener);
toggles.remove(toggle);
}

}

(使用相同的测试代码。)

关于java - 如何增加 ToggleGroup 中可能选择的数量(例如 RadioButtons)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46196923/

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