【发布时间】:2018-04-12 17:30:40
【问题描述】:
我有 TableView 和模型类,只有两个属性字段 name 和 selected。我尝试使用 RadioButton 制作 TableCell,它允许您选择一项且仅一项。问题是,当我单击 RadioButton 时,它会将新值保存到模型类,但未选择项中的旧值不会被覆盖,所以我有两个具有 selected 属性的项目,但它显示为只选择了一个。这是我的最小可执行代码。
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;
}
}
数据模型类Model.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.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);
}
}
【问题讨论】:
-
可以发一下主课吗? (相反,您再次发布了单元实现。)
-
抱歉,更新了问题。