我有这个Java表的例子,它每秒生成一次值。
简短的例子:
MainApp.java
public class MainApp extends Application
{
private TableView<Employee> table;
private TextField txtField;
private ObservableList<Employee> data;
MyService myService;
@Override
public void start(Stage stage) throws Exception
{
Label lbl = new Label("Enter text below to filter: ");
initFilter();
initTable();
myService = new MyService();
myService.setDelay(new Duration(300));
myService.setPeriod(new Duration(1000));
myService.start();
VBox container = new VBox();
container.getChildren().addAll(lbl, txtField, table);
StackPane root = new StackPane();
root.getChildren().add(container);
Scene scene = new Scene(root, 500, 400);
stage.setScene(scene);
stage.show();
}
class MyService extends ScheduledService<Void>
{
@Override
protected Task<Void> createTask()
{
return new Task<Void>()
{
@Override
protected Void call() throws Exception
{
data = getTableData();
table.setItems(FXCollections.observableArrayList(data));
return null;
}
};
}
}
public static void main(String[] args)
{
launch(args);
}
private void initTable()
{
table = new TableView<>();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn<Employee, String> empIdCol = new TableColumn<>("Employee ID");
empIdCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, String>, ObservableValue<String>>()
{
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Employee, String> p)
{
return p.getValue().empIdProperty();
}
});
TableColumn<Employee, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, String>, ObservableValue<String>>()
{
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Employee, String> p)
{
return p.getValue().nameProperty();
}
});
TableColumn<Employee, Number> ageCol = new TableColumn<>("Age");
ageCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, Number>, ObservableValue<Number>>()
{
@Override
public ObservableValue<Number> call(TableColumn.CellDataFeatures<Employee, Number> p)
{
return p.getValue().ageProperty();
}
});
TableColumn<Employee, String> cityCol = new TableColumn<>("City");
cityCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, String>, ObservableValue<String>>()
{
@Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Employee, String> p)
{
return p.getValue().cityProperty();
}
});
table.getColumns().setAll(empIdCol, nameCol, ageCol, cityCol);
}
private void initFilter()
{
txtField = new TextField();
txtField.setPromptText("Filter");
txtField.textProperty().addListener(new InvalidationListener()
{
@Override
public void invalidated(Observable o)
{
if (txtField.textProperty().get().isEmpty())
{
table.setItems(data);
return;
}
ObservableList<Employee> tableItems = FXCollections.observableArrayList();
ObservableList<TableColumn<Employee, ?>> cols = table.getColumns();
for (int i = 0; i < data.size(); i++)
{
for (int j = 0; j < cols.size(); j++)
{
TableColumn col = cols.get(j);
String cellValue = col.getCellData(data.get(i)).toString();
cellValue = cellValue.toLowerCase();
if (cellValue.contains(txtField.textProperty().get().toLowerCase()))
{
tableItems.add(data.get(i));
break;
}
}
}
table.setItems(tableItems);
}
});
}
private ObservableList<Employee> getTableData()
{
ObservableList<Employee> list = FXCollections.observableArrayList();
String[] name =
{
"Sriram", "Pete", "Eric", "Dawson", "John"
};
String[] city =
{
"New York", "Chicago", "Little Rock", "Los Angeles", "Oakland"
};
for (int i = 0; i < 5; i++)
{
Employee emp = new Employee();
emp.setName(name[i]);
emp.setAge((int) (Math.random() * 100));
emp.setCity(city[i]);
emp.setEmpId(String.valueOf(i + 1000));
list.add(emp);
}
return list;
}
}
Employee.java
public class Employee {
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleIntegerProperty age = new SimpleIntegerProperty();
private SimpleStringProperty city = new SimpleStringProperty();
private SimpleStringProperty empId = new SimpleStringProperty();
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
public String getName() {
return name.get();
}
public SimpleIntegerProperty ageProperty() {
return age;
}
public void setAge(Integer age) {
this.age.set(age);
}
p
ublic Integer getAge() {
return age.get();
}
public SimpleStringProperty cityProperty() {
return city;
}
public String getCity() {
return city.get();
}
public void setCity(String city) {
this.city.set(city);
}
public SimpleStringProperty empIdProperty() {
return empId;
}
public void setEmpId(String empId) {
this.empId.set(empId);
}
public String getEmpId() {
return empId.get();
}
}
我注意到我用来过滤内容的过滤器仅适用于当前的Service运行。 对于下一次运行,不应用过滤器。
答案 0 :(得分:1)
使用FilteredList
管理过滤。不是直接更新列表,而是从服务中替换其源列表的内容。当文本字段中的文本发生更改时,只需更新已过滤列表的谓词。
另外,您的代码会从后台线程更新TableView
,这违反了JavaFX的线程规则。这在以下示例中已得到修复。
SSCCE:
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class FilteredTableViewExample extends Application {
private TableView<Employee> table;
private TextField txtField;
private FilteredList<Employee> tableData;
private ObservableList<Employee> data;
MyService myService;
@Override
public void start(Stage stage) throws Exception {
Label lbl = new Label("Enter text below to filter: ");
initFilter();
initTable();
myService = new MyService();
myService.setDelay(new Duration(300));
myService.setPeriod(new Duration(1000));
myService.start();
VBox container = new VBox();
container.getChildren().addAll(lbl, txtField, table);
StackPane root = new StackPane();
root.getChildren().add(container);
Scene scene = new Scene(root, 500, 400);
stage.setScene(scene);
stage.show();
}
class MyService extends ScheduledService<List<Employee>> {
@Override
protected Task<List<Employee>> createTask() {
Task<List<Employee>> task = new Task<List<Employee>>() {
@Override
protected List<Employee> call() throws Exception {
return getTableData();
}
};
task.setOnSucceeded(e -> data.setAll(task.getValue()));
return task ;
}
}
public static void main(String[] args) {
launch(args);
}
private void initTable() {
table = new TableView<>();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn<Employee, String> empIdCol = new TableColumn<>("Employee ID");
empIdCol.setCellValueFactory(p -> p.getValue().empIdProperty());
TableColumn<Employee, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(p -> p.getValue().nameProperty());
TableColumn<Employee, Number> ageCol = new TableColumn<>("Age");
ageCol.setCellValueFactory(p -> p.getValue().ageProperty());
TableColumn<Employee, String> cityCol = new TableColumn<>("City");
cityCol.setCellValueFactory(p -> p.getValue().cityProperty());
table.getColumns().setAll(empIdCol, nameCol, ageCol, cityCol);
data = FXCollections.observableArrayList();
tableData = new FilteredList<>(data);
table.setItems(tableData);
}
private void initFilter() {
txtField = new TextField();
txtField.setPromptText("Filter");
txtField.textProperty().addListener((obs, oldText, newText) -> {
if (txtField.textProperty().get().isEmpty()) {
tableData.setPredicate(employee -> true);
return;
}
tableData.setPredicate(employee -> {
String text = newText.toLowerCase();
for (TableColumn<Employee, ?> col : table.getColumns()) {
String cellValue = col.getCellData(employee).toString();
cellValue = cellValue.toLowerCase();
if (cellValue.contains(text)) {
return true;
}
}
return false;
});
});
}
private List<Employee> getTableData() {
List<Employee> list = new ArrayList<>();
String[] name = { "Sriram", "Pete", "Eric", "Dawson", "John" };
String[] city = { "New York", "Chicago", "Little Rock", "Los Angeles", "Oakland" };
for (int i = 0; i < 5; i++) {
Employee emp = new Employee();
emp.setName(name[i]);
emp.setAge((int) (Math.random() * 100));
emp.setCity(city[i]);
emp.setEmpId(String.valueOf(i + 1000));
list.add(emp);
}
return list;
}
public static class Employee {
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleIntegerProperty age = new SimpleIntegerProperty();
private SimpleStringProperty city = new SimpleStringProperty();
private SimpleStringProperty empId = new SimpleStringProperty();
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
public String getName() {
return name.get();
}
public SimpleIntegerProperty ageProperty() {
return age;
}
public void setAge(Integer age) {
this.age.set(age);
}
public Integer getAge() {
return age.get();
}
public SimpleStringProperty cityProperty() {
return city;
}
public String getCity() {
return city.get();
}
public void setCity(String city) {
this.city.set(city);
}
public SimpleStringProperty empIdProperty() {
return empId;
}
public void setEmpId(String empId) {
this.empId.set(empId);
}
public String getEmpId() {
return empId.get();
}
}
}