我有tableview和model类,只有两个属性字段, name
,和 selected
. 我试着用单选按钮制作tablecell,它允许你选择一个并且只能选择一个项目。问题是,当我单击单选按钮时,它会将新值保存到模型类中,但未选中项中的旧值不会被覆盖,因此我有两个带有 selected
属性为true,但它显示为仅选择了一个。这是我的最小可执行代码。
tablecell类radiobuttontablecell.java
import javafx.geometry.Pos;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableView;
import javafx.scene.layout.HBox;
import javax.swing.table.TableColumn;
public class RadioButtonTableCell extends TableCell<Model, Boolean> {
private RadioButton radioButton = new RadioButton();
private HBox hBox = new HBox();
public RadioButtonTableCell(javafx.scene.control.TableColumn<Model, Boolean> column) {
hBox.getChildren().add(radioButton);
hBox.setAlignment(Pos.CENTER);
radioButton.disableProperty().bind(column.editableProperty().not());
radioButton.setOnMouseEntered(event -> {
final TableView<Model> tableView = getTableView();
tableView.getSelectionModel().select(getTableRow().getIndex());
super.startEdit();
tableView.edit(tableView.getSelectionModel().getSelectedIndex(), column);
});
radioButton.selectedProperty().addListener((observable, oldValue, newValue) -> {
if (isEditing()) {
commitEdit(newValue);
}
});
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
@Override
protected void updateItem(Boolean item, boolean empty) {
super.updateItem(item, empty);
if (empty) setGraphic(null);
else {
radioButton.setSelected(item);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
setGraphic(hBox);
}
}
public RadioButton getRadioButton() {
return this.radioButton;
}
}
数据模型.java
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Model {
private StringProperty name = new SimpleStringProperty();
private BooleanProperty selected = new SimpleBooleanProperty();
public Model(String name, boolean selected) {
this.name.set(name);
this.selected.set(selected);
}
public BooleanProperty selectedProperty() {
return selected;
}
public StringProperty nameProperty() {
return name;
}
@Override
public String toString() {
return "Model{" +
"name=" + name +
", selected=" + selected +
'}';
}
}
main类main.java
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Model> tableView = new TableView<>();
tableView.setEditable(true);
ToggleGroup toggleGroup = new ToggleGroup();
TableColumn<Model, Boolean> selectedColumn = new TableColumn<>("selected");
selectedColumn.setCellValueFactory(item -> item.getValue().selectedProperty());
selectedColumn.setCellFactory(tableCell -> {
RadioButtonTableCell cell = new RadioButtonTableCell(selectedColumn);
toggleGroup.getToggles().add(cell.getRadioButton());
return cell;
});
selectedColumn.setEditable(true);
TableColumn<Model, String> nameColumn = new TableColumn<>("name");
nameColumn.setCellValueFactory(item -> item.getValue().nameProperty());
tableView.getColumns().addAll(nameColumn, selectedColumn);
Scene scene = new Scene(tableView);
ObservableList<Model> list = FXCollections.observableArrayList();
list.add(new Model("Alisa", true));
list.add(new Model("Bob", false));
list.add(new Model("Jonh", false));
list.add(new Model("Sam", false));
list.add(new Model("Maria", false));
tableView.setItems(list);
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setOnCloseRequest(event -> {
for (Model item : tableView.getItems()) {
System.out.println(item.toString());
}
});
}
public static void main(String[] args) {
launch(args);
}
}
1条答案
按热度按时间v6ylcynt1#
我明白你的习惯
TableCell
导入到swing
我不知道为什么,因为我不知道你在哪里用它,但我认为这不是问题所在。如我所见,你从不把它们加到ToggleGroup
,将它们分组,如果选择其中一个,则将取消选择其他组。我写了一个简单的例子
RadioButton
在一个TableCell
,我为每个RadioButton
这个ToggleGroup
来处理选择。下面是代码: