javaFX:listview selectionmodel中的单选按钮

时间:2017-12-11 16:36:48

标签: java javafx

我需要在RadioButtonsListView,所以我找到了答案:

javaFX:listview with Radio Button

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

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

更新 因此,我设法做到这一点的唯一方法与@Sedrick Jefferson答案相似,但没有在StackPane前添加RadioButton。 我将RadioButtons namesRadioButtons列表添加到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);
            }
        }

    }
}

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

1 个答案:

答案 0 :(得分:1)

重复:添加控件作为数据项解决方案!

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

像(修改过的例子):

     Foreigners
COU            
AUS     27311.0

更新

该示例在fx9中正常工作但在fx8中存在问题:

  • 当单击radiobutton外部(行的尾随空格中的某个位置)时,所选的无线电并不总是更新。这可以通过强制无线电扩展到列表的整个宽度来解决。

  • 当listView的选择发生变化时,并不总是更新所选的收音机状态。这可以通过在单元的selected属性中安装一个监听器来处理,并更新该监听器中的无线电。

  • 重新使用单元格时,无法可靠地更新无线电的选定状态。这需要进一步挖掘......