gpt4 book ai didi

javaFX: ListView 选择模型内的单选按钮

转载 作者:行者123 更新时间:2023-12-02 11:53:03 24 4
gpt4 key购买 nike

我需要 ListView 内的 RadioButtons 所以我找到了这个答案:

javaFX:listview with Radio Button

但问题是 ListView 中选定的单元格和选定的 RadioButton 未绑定(bind)。如果单击列表中的单元格,我想自动选择相应的 RadioButton

所以我的问题是如何绑定(bind)这两个?

更新:因此,我设法做到这一点的唯一方法类似于@Sedrick Jefferson 的答案,但没有在 RadioButton 前面添加 StackPane 。我将 RadioButtons 名称RadioButtons 列表添加到 ToggleGroup 并将监听器添加到 selectedToggleProperty:当选择新的 RadioButton 时,我选择相应的ListView 中的行

    import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class RadioButtonListView extends Application
{

public static final ObservableList<RadioButton> namesRadioButtons
= FXCollections.observableArrayList();
private ToggleGroup group = new ToggleGroup();

@Override
public void start(Stage primaryStage)
{
primaryStage.setTitle("List View Sample");

final ListView<RadioButton> listView = new ListView();
listView.setPrefSize(200, 250);
listView.setEditable(true);

String[] names =
{
"Adam", "Alex", "Alfred", "Albert",
"Brenda", "Connie", "Derek", "Donny",
"Lynne", "Myrtle", "Rose", "Rudolph",
"Tony", "Trudy", "Williams", "Zach"
};

for (String name : names)
{
namesRadioButtons.add(new RadioButton(name));
}
group.getToggles().addAll(namesRadioButtons);
listView.setItems(namesRadioButtons);
group.selectedToggleProperty().addListener((obs, oldSel, newSel) -> {
listView.getSelectionModel().select((RadioButton) newSel);
listView.getFocusModel().focus(listView.getSelectionModel().getSelectedIndex());
});
listView.setCellFactory(param -> new RadioListCell());
listView.getSelectionModel().selectedItemProperty().addListener((obs, oldSel, newSel) ->
{
if (newSel != null)
{
RadioButton tempRadioButton = (RadioButton) newSel;
tempRadioButton.setSelected(true);
}
if (oldSel != null)
{
RadioButton tempRadioButton = (RadioButton) oldSel;
tempRadioButton.setSelected(false);
}
});

StackPane root = new StackPane();
root.getChildren().add(listView);
primaryStage.setScene(new Scene(root, 200, 250));
primaryStage.show();
}

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

private class RadioListCell extends ListCell<RadioButton>
{

@Override
public void updateItem(RadioButton obj, boolean empty)
{
super.updateItem(obj, empty);
if (empty)
{
setText(null);
setGraphic(null);
}
else
{
setGraphic(obj);
}
}

}
}

问题:有没有更好的解决方案?

最佳答案

重复一遍:将控件添加为数据项不是解决方案!

相反,请根据需要使用具有控件的自定义单元格,并配置项目/列表/选择的状态,就像 QA cited by the OP 中一样。 。唯一缺少的部分是反向同步(从 radio 状态到列表选择):要实现这一点,请在单元中安装一个监听器。

类似(修改后的示例):

public class RadioButtonListView extends Application {

public static final ObservableList names =
FXCollections.observableArrayList();
private ToggleGroup group = new ToggleGroup();

@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("List View Sample");

final ListView listView = new ListView();
listView.setPrefSize(200, 250);
listView.setEditable(true);

names.addAll(
"Adam", "Alex", "Alfred", "Albert",
"Brenda", "Connie", "Derek", "Donny",
"Lynne", "Myrtle", "Rose", "Rudolph",
"Tony", "Trudy", "Williams", "Zach"
);

listView.setItems(names);
listView.setCellFactory(param -> new RadioListCell());

StackPane root = new StackPane();
root.getChildren().add(listView);
primaryStage.setScene(new Scene(root, 200, 250));
primaryStage.show();
}

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

private class RadioListCell extends ListCell<String> {

RadioButton radioButton;
ChangeListener<Boolean> radioListener = (src, ov, nv) -> radioChanged(nv);
WeakChangeListener<Boolean> weakRadioListener = new WeakChangeListener(radioListener);

public RadioListCell() {
radioButton = new RadioButton();
radioButton.selectedProperty().addListener(weakRadioListener);
radioButton.setFocusTraversable(false);
// let it span the complete width of the list
// needed in fx8 to update selection state
radioButton.setMaxWidth(Double.MAX_VALUE);
}

protected void radioChanged(boolean selected) {
if (selected && getListView() != null && !isEmpty() && getIndex() >= 0) {
getListView().getSelectionModel().select(getIndex());
}
}

@Override
public void updateItem(String obj, boolean empty) {
super.updateItem(obj, empty);
if (empty) {
setText(null);
setGraphic(null);
radioButton.setToggleGroup(null);
} else {
radioButton.setText(obj);
radioButton.setToggleGroup(group);
radioButton.setSelected(isSelected());
setGraphic(radioButton);
}
}
}
}
<小时/>

更新:

该示例在 fx9 中运行良好,但在 fx8 中出现问题:

  • 当单击单选按钮外部(行尾部空白中的某个位置)时,所选单选按钮并不总是更新。这可以通过强制单选按钮拉伸(stretch)到列表的整个宽度来解决。

  • 当 listView 的选择更改时, radio 的选定状态并不总是更新。这可以通过在单元格的选定属性中安装监听器并更新该监听器中的 radio 来处理。

  • 当小区被重新使用时, radio 的选定状态不会可靠地更新。这需要进一步挖掘...

关于javaFX: ListView 选择模型内的单选按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47757368/

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