javaFX:listview selectionmodel中的单选按钮
我需要javaFX:listview selectionmodel中的单选按钮,java,javafx,Java,Javafx,我需要单选按钮在列表视图中,因此我找到了以下答案: 但问题是ListView中选定的单元格和选定的RadioButton未绑定。如果单击列表中的单元格,我希望自动选择相应的单选按钮 所以我的问题是如何将这两者结合起来 更新: 因此,我唯一能做到这一点的方法与@Sedrick Jefferson answer类似,但没有在RadioButton前面添加StackPane。 我将单选按钮列表名称单选按钮添加到切换组,并将侦听器添加到selectedToggleProperty:选择新建单选按钮时,
单选按钮
在列表视图
中,因此我找到了以下答案:
但问题是ListView
中选定的单元格和选定的RadioButton
未绑定。如果单击列表中的单元格,我希望自动选择相应的单选按钮
所以我的问题是如何将这两者结合起来
更新:
因此,我唯一能做到这一点的方法与@Sedrick Jefferson answer类似,但没有在RadioButton
前面添加StackPane
。
我将单选按钮列表
名称单选按钮添加到切换组
,并将侦听器添加到selectedToggleProperty
:选择新建单选按钮
时,我在列表视图中选择相应的行
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);
}
}
}
}
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.ListCell;
导入javafx.scene.control.ListView;
导入javafx.scene.control.RadioButton;
导入javafx.scene.control.ToggleGroup;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.StackPane;
导入javafx.stage.stage;
公共类RadioButtonListView扩展了应用程序
{
公共静态最终可观察列表名称单选按钮
=FXCollections.observableArrayList();
private-ToggleGroup-group=new-ToggleGroup();
@凌驾
公共无效开始(阶段primaryStage)
{
setTitle(“列表视图示例”);
最终ListView ListView=新建ListView();
setPrefSize(200250);
listView.setEditable(true);
字符串[]名称=
{
“亚当”、“亚历克斯”、“阿尔弗雷德”、“阿尔伯特”,
“布伦达”,“康妮”,“德里克”,“唐尼”,
“林恩”、“桃金娘”、“玫瑰”、“鲁道夫”,
“托尼”、“特鲁迪”、“威廉姆斯”、“扎克”
};
for(字符串名称:名称)
{
名称RadioButtons.add(新的RadioButton(名称));
}
group.getToggles().addAll(名称单选按钮);
setItems(名称单选按钮);
group.selectedToggleProperty().addListener((obs、oldSel、newSel)->{
listView.getSelectionModel().select((单选按钮)newSel);
listView.getFocusModel().focus(listView.getSelectionModel().getSelectedIndex());
});
setCellFactory(参数->新建RadioListCell());
listView.getSelectionModel().SelectEditeProperty().addListener((obs、oldSel、newSel)->
{
if(newSel!=null)
{
RadioButton tempRadioButton=(RadioButton)newSel;
tempRadioButton.setSelected(真);
}
如果(oldSel!=null)
{
RadioButton tempRadioButton=(RadioButton)oldSel;
tempRadioButton.setSelected(假);
}
});
StackPane root=新的StackPane();
root.getChildren().add(listView);
原始阶段。设置场景(新场景(根,200250));
primaryStage.show();
}
公共静态void main(字符串[]args)
{
发射(args);
}
私有类RadioListCell扩展了ListCell
{
@凌驾
public void updateItem(RadioButton obj,布尔空)
{
super.updateItem(对象,空);
if(空)
{
setText(空);
设置图形(空);
}
其他的
{
设置图形(obj);
}
}
}
}
问题:有没有更好的解决办法 重复:添加控件作为数据项不是解决方案 相反,使用一个自定义单元格,该单元格根据需要具有一个控件,并使用项/列表/选择的状态进行配置,就像在中一样。唯一缺少的部分是反向同步(从无线电状态到列表选择):要实现这一点,请在单元中安装一个侦听器 类似(修改后的示例):
公共类RadioButtonListView扩展应用程序{
公共静态最终可观察列表名称=
FXCollections.observableArrayList();
private-ToggleGroup-group=new-ToggleGroup();
@凌驾
公共无效开始(阶段primaryStage){
setTitle(“列表视图示例”);
最终ListView ListView=新建ListView();
setPrefSize(200250);
listView.setEditable(true);
name.addAll(
“亚当”、“亚历克斯”、“阿尔弗雷德”、“阿尔伯特”,
“布伦达”,“康妮”,“德里克”,“唐尼”,
“林恩”、“桃金娘”、“玫瑰”、“鲁道夫”,
“托尼”、“特鲁迪”、“威廉姆斯”、“扎克”
);
setItems(名称);
setCellFactory(参数->新建RadioListCell());
StackPane root=新的StackPane();
root.getChildren().add(listView);
原始阶段。设置场景(新场景(根,200250));
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
私有类RadioListCell扩展了ListCell{
单选按钮单选按钮;
ChangeListener radioListener=(src、ov、nv)->radioChanged(nv);
WeakChangeListener weakRadioListener=新的WeakChangeListener(radioListener);
公共放射室(){
radioButton=新的radioButton();
radioButton.selectedProperty().addListener(weakRadioListener);
radioButton.setFocusTraversable(假);
//让它跨越列表的整个宽度
//fx8中需要更新选择状态
radioButton.setMaxWidth(双倍最大值);
}
受保护的无效项已更改(已选择布尔值){
if(selected&&getListView()!=null&&isEmpty()&&getIndex()>=0){
getListView().getSelectionModel().select(getIndex());
}
}
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);
}
}
}
}