JavaFX2.1 TableView刷新项
我有一个共同的问题,似乎是这样。重置项目后,我的表视图不会刷新项目。我检查了数据,是新的 我尝试了来自internet的多种解决方案,但没有成功。 无法重置所有列,因为它会添加一个空的列和一个额外的列(不知道为什么),并且“调整大小”会中断 我的表格不可编辑。新数据已更改 如果I更改项目的顺序,并且行更改(:|),则数据将刷新 我就是没有主意 目前,刷新代码非常简单JavaFX2.1 TableView刷新项,java,javafx,tableview,javafx-8,fxml,Java,Javafx,Tableview,Javafx 8,Fxml,我有一个共同的问题,似乎是这样。重置项目后,我的表视图不会刷新项目。我检查了数据,是新的 我尝试了来自internet的多种解决方案,但没有成功。 无法重置所有列,因为它会添加一个空的列和一个额外的列(不知道为什么),并且“调整大小”会中断 我的表格不可编辑。新数据已更改 如果I更改项目的顺序,并且行更改(:|),则数据将刷新 我就是没有主意 目前,刷新代码非常简单 ObservableList<User> data = FXCollections.observableArrayLi
ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);
observeList data=FXCollections.observearraylist(User.getrelailers());
转销商\表.集合项目(数据);
同样,新数据是正确的。当我选择tableView时,它会返回新的正确项。更新:
最后,tableview刷新在JavaFX 8u60中解决,可供早期访问
关于刷新,请参阅。
关于空白栏,请参阅。基本上,它不是一列,即您不能单击此空白列来选择项目项目。它只是一个空白区域,样式类似于一行
更新:如果您是通过
reseller\u table.setItems(数据)
更新tableView,则不需要使用SimpleStringProperty
。如果您只更新一行/项目,这将非常有用。下面是刷新表数据的完整示例:
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Dddeb extends Application {
public static class Product {
private String name;
private String code;
public Product(String name, String code) {
this.name = name;
this.code = code;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
private TableView<Product> productTable = new TableView<Product>();
@Override
public void start(Stage stage) {
Button refreshBtn = new Button("Refresh table");
refreshBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent arg0) {
// You can get the new data from DB
List<Product> newProducts = new ArrayList<Product>();
newProducts.add(new Product("new product A", "1201"));
newProducts.add(new Product("new product B", "1202"));
newProducts.add(new Product("new product C", "1203"));
newProducts.add(new Product("new product D", "1244"));
productTable.getItems().clear();
productTable.getItems().addAll(newProducts);
//productTable.setItems(FXCollections.observableArrayList(newProducts));
}
});
TableColumn nameCol = new TableColumn("Name");
nameCol.setMinWidth(100);
nameCol.setCellValueFactory(new PropertyValueFactory<Product, String>("name"));
TableColumn codeCol = new TableColumn("Code");
codeCol.setCellValueFactory(new PropertyValueFactory<Product, String>("code"));
productTable.getColumns().addAll(nameCol, codeCol);
productTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
// You can get the data from DB
List<Product> products = new ArrayList<Product>();
products.add(new Product("product A", "0001"));
products.add(new Product("product B", "0002"));
products.add(new Product("product C", "0003"));
//productTable.getItems().addAll(products);
productTable.setItems(FXCollections.observableArrayList(products));
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.getChildren().addAll(productTable, refreshBtn);
Scene scene = new Scene(new Group());
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.setWidth(300);
stage.setHeight(500);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
及
两者几乎相等。所以我第一次用它来填充表格,第二次刷新表格时用它来填充。它仅用于演示目的。我已经在JavaFX2.1中测试了代码。最后,您可以(也应该)通过移动问题答案中的代码片段来编辑问题以改进问题。initialize()方法
refresh()方法
observeList data=FXCollections.observearraylist(User.getrelailers());
转销商\表.集合项目(数据);
我终于找到了一个很难解决的方法来刷新所有行
void refreshTable() {
final List<Item> items = tableView.getItems();
if( items == null || items.size() == 0) return;
final Item item = tableView.getItems().get(0);
items.remove(0);
Platform.runLater(new Runnable(){
@Override
public void run() {
items.add(0, item);
}
});
}
void refreshttable(){
最终列表项=tableView.getItems();
if(items==null | | items.size()==0)返回;
最终项目=tableView.getItems().get(0);
项目。删除(0);
Platform.runLater(新的Runnable(){
@凌驾
公开募捐{
项目。添加(0,项目);
}
});
}
我想我已经很好地描述了表刷新的问题。解决方法:
tableView.getColumns().get(0).setVisible(false);
tableView.getColumns().get(0).setVisible(true);
我在提神方面也有类似的问题。我的解决方案是将
observateList
上的操作限制为那些可以正确使用bind()
的操作
假设observeList obsList
是TableView
的基础列表
然后obsList.clear()
同时调用setItem(obsList)
也不能触发刷新…但是
obsList.removeAll(obsList)
(被observeList
覆盖)工作正常,因为它正确触发了changeEvent
用全新的内容重新填充列表,其工作原理如下:
obsList.removeAll(obsList)代码>
obsList.add(…)//e、 g.在循环中…
或
obsList.removeAll(obsList)代码>
FXCollections.copy(obsList,someSourceList)
向Ingo致以最诚挚的问候真是一个臭虫!这里是另一个解决方法
public void forceRefresh() {
final TableColumn< Prospect, ? > firstColumn = view.getColumns().get( 0 );
firstColumn.setVisible( false );
new Timer().schedule( new TimerTask() { @Override public void run() {
Platform.runLater( new Runnable() { @Override public void run() {
firstColumn.setVisible( true ); }});
}}, 100 );
}
public void forceRefresh(){
final TableColumnfirstColumn=view.getColumns().get(0);
firstColumn.setVisible(false);
新建计时器()。计划(新建计时器任务(){@Override public void run()){
Platform.runLater(新Runnable(){@Override public void run()){
setVisible(true);}};
}}, 100 );
}
我已经做了一件好事。我鼓励大家用另一种更优雅的方式来修复它,因为我的解决方法非常难看 我有一个用例,除了Aubin提供的解决方案之外,没有其他任何帮助。我修改了这个方法,并通过删除一个项并将其添加到表的项列表中对其进行了更改,因为它最终只能可靠地工作。使用这个hack,ColumnVisible切换只在第一次完成了这项工作
我在Jira任务中也报告了这一点:
公共作废表项刷新(最终可观察列表项){
if(items==null | | items.size()==0)
返回;
int idx=items.size()-1;
最终T项=items.get(idx);
项目。删除(idx);
新建计时器()。计划(新建计时器任务()){
@凌驾
公开募捐{
Platform.runLater(新的Runnable(){
@凌驾
公开募捐{
项目。添加(项目);
}
});
}
}, 100);
}
我也遇到了同样的问题,经过一些搜索,这是我的解决办法。我发现,如果删除列,然后重新添加,表就会更新
public static <T,U> void refreshTableView(final TableView<T> tableView, final List<TableColumn<T,U>> columns, final List<T> rows) {
tableView.getColumns().clear();
tableView.getColumns().addAll(columns);
ObservableList<T> list = FXCollections.observableArrayList(rows);
tableView.setItems(list);
}
用户1236048的解决方案是正确的,但关键点没有被调用。在用于表的可观察列表的POJO类中,不仅要设置getter和setter方法,还要设置一个名为Property的新方法。在Oracle的tableview教程()中,他们忽略了关键部分
下面是Person类的外观:
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public SimpleStringProperty firstNameProperty(){
return firstName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public SimpleStringProperty lastNameProperty(){
return lastName;
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
public SimpleStringProperty emailProperty(){
return email;
}
}您应该使用可观察属性,而不是手动刷新。
这个问题的答案举例说明了目的:
基于丹尼尔·德莱昂的回答
publicstaticvoidrefresh\u表(TableView表){
for(int i=0;ivoid refreshTable() {
final List<Item> items = tableView.getItems();
if( items == null || items.size() == 0) return;
final Item item = tableView.getItems().get(0);
items.remove(0);
Platform.runLater(new Runnable(){
@Override
public void run() {
items.add(0, item);
}
});
}
tableView.getColumns().get(0).setVisible(false);
tableView.getColumns().get(0).setVisible(true);
public void forceRefresh() {
final TableColumn< Prospect, ? > firstColumn = view.getColumns().get( 0 );
firstColumn.setVisible( false );
new Timer().schedule( new TimerTask() { @Override public void run() {
Platform.runLater( new Runnable() { @Override public void run() {
firstColumn.setVisible( true ); }});
}}, 100 );
}
public <T> void tableItemsRefresh(final ObservableList<T> items) {
if (items == null || items.size() == 0)
return;
int idx = items.size() -1;
final T item = items.get(idx);
items.remove(idx);
new Timer().schedule(new TimerTask() {
@Override
public void run() {
Platform.runLater(new Runnable() {
@Override
public void run() {
items.add(item);
}
});
}
}, 100);
}
public static <T,U> void refreshTableView(final TableView<T> tableView, final List<TableColumn<T,U>> columns, final List<T> rows) {
tableView.getColumns().clear();
tableView.getColumns().addAll(columns);
ObservableList<T> list = FXCollections.observableArrayList(rows);
tableView.setItems(list);
}
refreshTableView(myTableView, Arrays.asList(col1, col2, col3), rows);
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public SimpleStringProperty firstNameProperty(){
return firstName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public SimpleStringProperty lastNameProperty(){
return lastName;
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
public SimpleStringProperty emailProperty(){
return email;
}
private void updateMyTableView() {
// update table view WORKAROUND !!!
if (myTableView != null) {
ObservableList<TableColumn<Entry, ?>> columns = myTableView.getColumns();
for (TableColumn<Entry, ?> column : columns) {
// at this point, we look for the specific column, which should
// always be visible
// therefore we use the "Column Title" String, e.g. "First name"
if (column.getText().equals("Column Title")) {
column.setVisible(false);
column.setVisible(true);
}
}
}
}
Platform.runLater(new Runnable() {
public void run() {
updateMyTableView();
}
});
// refresh table
table.getItems().clear();
table.setItems(listEqualToOld);
// refresh table
table.setItems(listEqualToOld);
/**
* Extended TableRow that updates its item if equal but not same.
* Needs custom skin to update cells on invalidation of the
* item property.<p>
*
* Looks ugly, as we have to let super doing its job and then
* re-check the state. No way to hook anywhere else into super
* because all is private. <p>
*
* Super might support a configuration option to check against
* identity vs. against equality.<p>
*
* Note that this is _not_ formally tested! Any execution paths calling
* <code>updateItem(int)</code> other than through
* <code>indexedCell.updateIndex(int)</code> are not handled.
*
* @author Jeanette Winzenburg, Berlin
*/
public class IdentityCheckingTableRow<T> extends TableRow<T> {
@Override
public void updateIndex(int i) {
int oldIndex = getIndex();
T oldItem = getItem();
boolean wasEmpty = isEmpty();
super.updateIndex(i);
updateItemIfNeeded(oldIndex, oldItem, wasEmpty);
}
/**
* Here we try to guess whether super updateIndex didn't update the item if
* it is equal to the old.
*
* Strictly speaking, an implementation detail.
*
* @param oldIndex cell's index before update
* @param oldItem cell's item before update
* @param wasEmpty cell's empty before update
*/
protected void updateItemIfNeeded(int oldIndex, T oldItem, boolean wasEmpty) {
// weed out the obvious
if (oldIndex != getIndex()) return;
if (oldItem == null || getItem() == null) return;
if (wasEmpty != isEmpty()) return;
// here both old and new != null, check whether the item had changed
if (oldItem != getItem()) return;
// unchanged, check if it should have been changed
T listItem = getTableView().getItems().get(getIndex());
// update if not same
if (oldItem != listItem) {
// doesn't help much because itemProperty doesn't fire
// so we need the help of the skin: it must listen
// to invalidation and force an update if
// its super wouldn't get a changeEvent
updateItem(listItem, isEmpty());
}
}
@Override
protected Skin<?> createDefaultSkin() {
return new TableRowSkinX<>(this);
}
public static class TableRowSkinX<T> extends TableRowSkin<T> {
private WeakReference<T> oldItemRef;
private InvalidationListener itemInvalidationListener;
private WeakInvalidationListener weakItemInvalidationListener;
/**
* @param tableRow
*/
public TableRowSkinX(TableRow<T> tableRow) {
super(tableRow);
oldItemRef = new WeakReference<>(tableRow.getItem());
itemInvalidationListener = o -> {
T newItem = ((ObservableValue<T>) o).getValue();
T oldItem = oldItemRef != null ? oldItemRef.get() : null;
oldItemRef = new WeakReference<>(newItem);
if (oldItem != null && newItem != null && oldItem.equals(newItem)) {
forceCellUpdate();
}
};
weakItemInvalidationListener = new WeakInvalidationListener(itemInvalidationListener);
tableRow.itemProperty().addListener(weakItemInvalidationListener);
}
/**
* Try to force cell update for equal (but not same) items.
* C&P'ed code from TableRowSkinBase.
*/
private void forceCellUpdate() {
updateCells = true;
getSkinnable().requestLayout();
// update the index of all children cells (RT-29849).
// Note that we do this after the TableRow item has been updated,
// rather than when the TableRow index has changed (as this will be
// before the row has updated its item). This will result in the
// issue highlighted in RT-33602, where the table cell had the correct
// item whilst the row had the old item.
final int newIndex = getSkinnable().getIndex();
for (int i = 0, max = cells.size(); i < max; i++) {
cells.get(i).updateIndex(newIndex);
}
}
}
@SuppressWarnings("unused")
private static final Logger LOG = Logger
.getLogger(IdentityCheckingListCell.class.getName());
}
// usage
table.setRowFactory(p -> new IdentityCheckingTableRow());
/**
* Searches the table for an existing Patient.
*/
@FXML
public void handleSearch() {
String fname = this.fNameSearch.getText();
String lname = this.lNameSearch.getText();
LocalDate bdate = this.bDateSearch.getValue();
if (this.nameAndDOBSearch(fname, lname, bdate)) {
this.patientData = this.controller.processNursePatientSearch(fname, lname, bdate);
} else if (this.birthDateSearch(fname, lname, bdate)) {
this.patientData = this.controller.processNursePatientSearch(bdate);
} else if (this.nameSearch(fname, lname, bdate)) {
this.patientData = this.controller.processNursePatientSearch(fname, lname);
}
this.patientTable.setItems(this.patientData);
}
/**
* Adds a listener to the modelChangedProperty to update the table view
*/
private void createUpdateWorkAroundListener() {
model.modelChangedProperty.addListener(
(ObservableValue<? extends Boolean> arg0, final Boolean oldValue, final Boolean newValue) -> updateTableView()
);
}
/**
* Work around to update table view
*/
private void updateTableView() {
TableColumn<?, ?> firstColumn = scenarioTable.getColumns().get(0);
firstColumn.setVisible(false);
firstColumn.setVisible(true);
}
解決於台灣台北
resolve in Taiwan Taipei.
public class CostAnalytics{
protected WritableObjectValue<Double> subtotal=new SimpleObjectProperty<Double>();//利用WritableObjectValue達到自動更新目的,不需要使用個別Column操作setVisable(false)及setVisable(true)
//...
public void setQuantity(double quantity) {
this.pcs.firePropertyChange("quantity", this.quantity, quantity);
this.quantity.set(quantity);
this.calsSubtotal();
}
public WritableObjectValue<Double> getSubtotal() {//利用WritableObjectValue達到自動更新目的,不需要使用個別Column操作setVisable(false)及setVisable(true)
return subtotal;
}
///...
}
TableColumn<CostAnalytics, Double> subtotal = new TableColumn<CostAnalytics, Double>(
"小計");
subtotal.setCellValueFactory(new Callback<CellDataFeatures<CostAnalytics, Double>, ObservableValue<Double>>() {
public ObservableValue<Double> call(
CellDataFeatures<CostAnalytics, Double> p) {
WritableObjectValue<Double> result = p.getValue().getSubtotal();// //利用WritableObjectValue達到自動更新目的,不需要使用個別Column操作setVisable(false)及setVisable(true)
// return (ObservableValue<Double>)
// result;//利用WritableObjectValue達到自動更新目的,不需要使用個別Column操作setVisable(false)及setVisable(true)
// return new
// ReadOnlyObjectWrapper<Double>(p.getValue().getSubtotal());//造成無法自動更新
return (ObservableValue<Double>) p.getValue().getSubtotal();// 利用WritableObjectValue達到自動更新目的,不需要使用個別Column操作setVisable(false)及setVisable(true)
}
});
//wierd JavaFX bug
reseller_table.setItems(null);
reseller_table.layout();
ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);
tableView.refresh();
Question db = center.getSelectionModel().getSelectedItem();
new QuestionCrud().deleteQ(db.getId());
ObservableList<Question> aftDelete = FXCollections.observableArrayList(
(new QuestionCrud()).all()
);
center.setItems(aftDelete);
//To get all customer details
def getCustomerDetails : ObservableBuffer[Customer] = {
val customerDetails = new ObservableBuffer[Customer]()
try {
val resultSet = statement.executeQuery("SELECT * FROM MusteriBilgileri")
while (resultSet.next()) {
val musteriId = resultSet.getString("MusteriId")
val musteriIsmi = resultSet.getString("MusteriIsmi")
val urununTakildigiTarih = resultSet.getDate("UrununTakildigiTarih").toString
val bakimTarihi = resultSet.getDate("BakimTarihi").toString
val urununIsmi = resultSet.getString("UrununIsmi")
val telNo = resultSet.getString("TelNo")
val aciklama = resultSet.getString("Aciklama")
customerDetails += new Customer(musteriId,musteriIsmi,urununTakildigiTarih,bakimTarihi,urununIsmi,telNo,aciklama)
}
} catch {
case e => e.printStackTrace
}
customerDetails
}
var table = new TableView[Customer](model.getCustomerDetails)
table.columns += (customerIdColumn,customerNameColumn,productInstallColumn,serviceDateColumn,
productNameColumn,phoneNoColumn,detailColumn)
table.setItems(FXCollections.observableArrayList(model.getCustomerDetails.delegate))
val model = new ScalaJdbcConnectSelect
ObservableList<Area> area = FXCollections.observableArrayList();
this.areaTable.setItems(getAreaData());
private ObservableList<Area> getAreaData() {
try {
area = AreaDAO.searchEmployees(); // To inform ObservableList
return area;
} catch (ClassNotFoundException | SQLException e) {
System.out.println("Error: " + e);
return null;
}
}
@FXML
private void handleNewArea() {
Area tempArea = new Area();
boolean okClicked = showAreaDialog(tempArea);
if (okClicked) {
addNewArea(tempArea);
this.area.add(tempArea); // To inform ObservableList
}
}
ButtonRefresh.setOnAction((event) -> {
tacheTable.getItems().clear();
PopulateTable();
});