具有自定义单元格工厂的 javafx ListView 不保留选定的单元格
javafx ListView with custom cell factory not retaining the selected cell
我有一个 controlsfx CheckListView(甚至与 javafx ListView 控件有同样的问题),我想在其中显示 RadioButtons 而不是 CheckBox。所以我在一些 javafx 教程的帮助下实现了自定义单元工厂,并且它正在运行。
问题是我选择了第一个单选按钮并向下滚动一点,这样我顶部的几个单选按钮就会向上滚动并且现在不可见。然后我再次向上滚动,现在选择消失了。
我调试代码时了解到每次都会创建新的单元格,这导致了这个问题,但遗憾的是无法找出解决方案。
我附上了一个示例代码,它是我从堆栈溢出中得到的,它有同样的问题。
package application;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
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.StackPane;
import javafx.stage.Stage;
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> {
@Override
public void updateItem(String obj, boolean empty) {
super.updateItem(obj, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
RadioButton radioButton = new RadioButton(obj);
radioButton.setToggleGroup(group);
// Add Listeners if any
setGraphic(radioButton);
}
}
}
}
这方面需要你的帮助。(我使用的是 javafx 8)
您应该为单元格创建一个单选按钮(而不是每次调用 updateItem(...)
时都创建一个新单选按钮,并使用您的适当逻辑在 updateItem(...)
方法中更新其选定状态数据表示。
private class RadioListCell extends ListCell<String> {
private final RadioButton radioButton = new RadioButton();
RadioListCell() {
radioButton.setToggleGroup(group);
// Add listeners here...
}
@Override
public void updateItem(String obj, boolean empty) {
super.updateItem(obj, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
radioButton.setText(obj);
radioButton.setSelected(...);
setGraphic(radioButton);
}
}
}
例如:
import java.util.Objects;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
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.StackPane;
import javafx.stage.Stage;
public class RadioButtonListView extends Application {
public static final ObservableList<String> names = FXCollections.observableArrayList();
private ToggleGroup group = new ToggleGroup();
private String selectedName ;
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("List View Sample");
final ListView<String> 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> {
private final RadioButton radioButton = new RadioButton();
RadioListCell() {
radioButton.setToggleGroup(group);
radioButton.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
selectedName = getItem();
}
});
}
@Override
public void updateItem(String obj, boolean empty) {
super.updateItem(obj, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
radioButton.setText(obj);
radioButton.setSelected(Objects.equals(obj, selectedName));
setGraphic(radioButton);
}
}
}
}
我有一个 controlsfx CheckListView(甚至与 javafx ListView 控件有同样的问题),我想在其中显示 RadioButtons 而不是 CheckBox。所以我在一些 javafx 教程的帮助下实现了自定义单元工厂,并且它正在运行。 问题是我选择了第一个单选按钮并向下滚动一点,这样我顶部的几个单选按钮就会向上滚动并且现在不可见。然后我再次向上滚动,现在选择消失了。
我调试代码时了解到每次都会创建新的单元格,这导致了这个问题,但遗憾的是无法找出解决方案。
我附上了一个示例代码,它是我从堆栈溢出中得到的,它有同样的问题。
package application;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
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.StackPane;
import javafx.stage.Stage;
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> {
@Override
public void updateItem(String obj, boolean empty) {
super.updateItem(obj, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
RadioButton radioButton = new RadioButton(obj);
radioButton.setToggleGroup(group);
// Add Listeners if any
setGraphic(radioButton);
}
}
}
}
这方面需要你的帮助。(我使用的是 javafx 8)
您应该为单元格创建一个单选按钮(而不是每次调用 updateItem(...)
时都创建一个新单选按钮,并使用您的适当逻辑在 updateItem(...)
方法中更新其选定状态数据表示。
private class RadioListCell extends ListCell<String> {
private final RadioButton radioButton = new RadioButton();
RadioListCell() {
radioButton.setToggleGroup(group);
// Add listeners here...
}
@Override
public void updateItem(String obj, boolean empty) {
super.updateItem(obj, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
radioButton.setText(obj);
radioButton.setSelected(...);
setGraphic(radioButton);
}
}
}
例如:
import java.util.Objects;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
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.StackPane;
import javafx.stage.Stage;
public class RadioButtonListView extends Application {
public static final ObservableList<String> names = FXCollections.observableArrayList();
private ToggleGroup group = new ToggleGroup();
private String selectedName ;
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("List View Sample");
final ListView<String> 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> {
private final RadioButton radioButton = new RadioButton();
RadioListCell() {
radioButton.setToggleGroup(group);
radioButton.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
selectedName = getItem();
}
});
}
@Override
public void updateItem(String obj, boolean empty) {
super.updateItem(obj, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
radioButton.setText(obj);
radioButton.setSelected(Objects.equals(obj, selectedName));
setGraphic(radioButton);
}
}
}
}