我是JavaFX的新手,我不知道如何解决这个问题。所以,我在TableView中有一个复选框列。例如,我选择3个第一个框并向下滚动表格。但是当我转到表格顶部时,未选中复选框。 这是一些代码:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import java.util.LinkedList;
import java.util.List;
public class App extends Application
{
List<User> list = new LinkedList<>();
TableColumn<User, Integer> id;
TableColumn<User, String> firstName;
TableColumn<User, Boolean> selected;
TableView<User> tableView;
public static void main(String[] args)
{
launch();
}
@Override
public void start(Stage stage) throws Exception
{
stage.setHeight(500);
stage.setWidth(500);
stage.setMinHeight(200);
stage.setMinHeight(100);
stage.setTitle("Table view");
tableView = new TableView<>();
ObservableList<User> list = FXCollections.observableArrayList();
for(int i = 0; i < 40; i++)
{
list.add(new User(i, "first name", "last name"));
}
id = new TableColumn("ID");
id.setCellValueFactory(new PropertyValueFactory<User, Integer>("id"));
firstName = new TableColumn("First Name");
firstName.setCellValueFactory(new PropertyValueFactory<User, String>("firstName"));
TableColumn<User, String> lastName = new TableColumn("Last Name");
lastName.setCellValueFactory(new PropertyValueFactory<User, String>("lastName"));
selected = new TableColumn("Select");
Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>> booleanCellFactory = new Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>>()
{
@Override
public TableCell<User, Boolean> call(TableColumn<User, Boolean> p)
{
return new CheckBoxCell();
}
};
selected.setCellValueFactory(new PropertyValueFactory<User, Boolean>("active"));
selected.setCellFactory(booleanCellFactory);
tableView.getColumns().addAll(id, firstName, lastName, selected);
tableView.setItems(list);
BorderPane pane = new BorderPane();
pane.setCenter(tableView);
Scene scene = new Scene(pane);
stage.setScene(scene);
stage.show();
}
class CheckBoxCell extends TableCell<User, Boolean>
{
private CheckBox checkbox;
@Override
protected void updateItem(Boolean item, boolean empty)
{
super.updateItem(item, empty);
checkbox = new CheckBox();
checkbox.setAlignment(Pos.CENTER);
setAlignment(Pos.CENTER);
setGraphic(checkbox);
checkbox.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent actionEvent)
{
if(!checkbox.isSelected())
{
list.remove(tableView.getItems().get(getTableRow().getIndex()));
} else
{
list.add(tableView.getItems().get(getTableRow().getIndex()));
}
System.out.println(list);
}
});
}
}
}
数据类“User”:
public class User
{
private int id;
private String firstName;
private String lastName;
User(int id, String firstName, String lastName)
{
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
}
答案 0 :(得分:1)
在Table Column“slected”
的代码中selected.setCellValueFactory(new PropertyValueFactory<User, Boolean>("active"));
您将属性值工厂设置为“活动”但您的用户类中没有“活动”属性。当您移动滚动条tableview触发器updateItem方法时,因为您没有活动属性(即使您有属性默认值) value为false)checkbox.setSelected(item); line将取消选中复选框,因为项值始终为false。
要解决此问题,请在用户选择/取消选中复选框时定义在用户类中激活的BooleanProperty和更新属性值。
以下是正在运行的整个代码
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.scene.layout.BorderPane;
import java.util.LinkedList;
import java.util.List;
public class TestApp extends Application {
List<User> list = new LinkedList<>();
TableColumn<User, Integer> id;
TableColumn<User, String> firstName;
TableColumn<User, Boolean> selected;
TableView<User> tableView;
public static void main(String[] args)
{
launch();
}
@Override
public void start(Stage stage) throws Exception
{
stage.setHeight(500);
stage.setWidth(500);
stage.setMinHeight(200);
stage.setMinHeight(100);
stage.setTitle("Table view");
tableView = new TableView<>();
ObservableList<User> list = FXCollections.observableArrayList();
for(int i = 0; i < 40; i++)
{
list.add(new User(i, "first name", "last name"));
}
id = new TableColumn("ID");
id.setCellValueFactory(new PropertyValueFactory<User, Integer>("id"));
firstName = new TableColumn("First Name");
firstName.setCellValueFactory(new PropertyValueFactory<User, String>("firstName"));
TableColumn<User, String> lastName = new TableColumn("Last Name");
lastName.setCellValueFactory(new PropertyValueFactory<User, String>("lastName"));
selected = new TableColumn("Select");
Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>> booleanCellFactory = new Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>>()
{
@Override
public TableCell<User, Boolean> call(TableColumn<User, Boolean> p)
{
return new CheckBoxCell();
}
};
selected.setCellValueFactory(new PropertyValueFactory<User, Boolean>("active"));
selected.setCellFactory(booleanCellFactory);
tableView.getColumns().addAll(id, firstName, lastName, selected);
tableView.setItems(list);
BorderPane pane = new BorderPane();
pane.setCenter(tableView);
Scene scene = new Scene(pane);
stage.setScene(scene);
stage.show();
}
class CheckBoxCell extends TableCell<User, Boolean>
{
private CheckBox checkbox = new CheckBox();
public CheckBoxCell(){
checkbox.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent actionEvent)
{
if(!checkbox.isSelected())
{
list.remove(tableView.getItems().get(getTableRow().getIndex()));
User user = getTableView().getItems().get(getTableRow().getIndex());
user.setActive(false);
} else
{
list.add(tableView.getItems().get(getTableRow().getIndex()));
User user = getTableView().getItems().get(getTableRow().getIndex());
user.setActive(true);
}
System.out.println(list);
}
});
}
@Override
protected void updateItem(Boolean item, boolean empty)
{
super.updateItem(item, empty);
if(!empty && item != null) {
checkbox.setAlignment(Pos.CENTER);
checkbox.setSelected(item);
setAlignment(Pos.CENTER);
setGraphic(checkbox);
}
}
}
用户类:
public class User
{
private IntegerProperty id;
private StringProperty firstName;
private StringProperty lastName;
private BooleanProperty active;
User(int id, String firstName, String lastName)
{
this.id = new SimpleIntegerProperty(id);
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
this.active = new SimpleBooleanProperty(false);
}
public int getId() {
return id.get();
}
public IntegerProperty idProperty() {
return id;
}
public void setId(int id) {
this.id.set(id);
}
public String getFirstName() {
return firstName.get();
}
public StringProperty firstNameProperty() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public String getLastName() {
return lastName.get();
}
public StringProperty lastNameProperty() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public boolean getActive() {
return active.get();
}
public BooleanProperty activeProperty() {
return active;
}
public void setActive(boolean active) {
this.active.set(active);
}
}
答案 1 :(得分:0)
有很多问题。
首先,TableCell
个实例将被重用。您需要将CheckBox
的值设置为item
的值。
@Override
protected void updateItem(Boolean item, boolean empty)
{
super.updateItem(item, empty);
checkbox = new CheckBox();
if(!empty && item != null)
checkbox.setSelected(item);
....
}
其次,您有两个名为list
的变量。 TableView
未绑定到顶部声明的List<User>
,这可能就是您的行不会自行删除的原因。
你应该替换这一行:
List<User> list = new LinkedList<>();
有了这个:
ObservableList<User> list = FXCollections.observableArrayList();
最后,您应该为数据对象使用JavaFX属性,它们将使用TableView
执行得更快(无需使用反射来访问值),并且可以使用JavaFX控件提供更好的处理。