65

私はこの共通の問題を抱えているようです。項目をリセットした後、テーブル ビューが項目を更新しません。データ確認しましたが新品です。

インターネットから複数のソリューションを試しましたが、成功しませんでした。

空の列が 1 つ余分に追加され (理由がわからない)、サイズ変更が壊れてしまうため、すべての列をリセットすることはできません。

私のテーブルは編集できません。新しいデータが変更されます。

アイテムの順序を変更して行が変更されると、データが更新されます (:|)。

私はただアイデアなしで残っています。

現時点では、更新コードは非常に単純です。

ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);

ここでも、新しいデータは正しいです。tableView を選択すると、新しい正しいアイテムが返されます。

4

26 に答える 26

63

回避策:

 tableView.getColumns().get(0).setVisible(false);
 tableView.getColumns().get(0).setVisible(true);
于 2012-09-27T03:45:16.117 に答える
62

JavaFX 8u60あなたが使用できるので( TableViewtableViewクラスのインスタンスであると仮定します):

tableView.refresh();

ドキュメントから:

refresh() を呼び出すと、TableView コントロールは、コントロールの視覚的な境界を設定するために必要なセルを強制的に再作成および再設定します。つまり、これにより、TableView がユーザーに表示する内容を強制的に更新します。これは、基になるデータ ソースが変更され、TableView 自体では監視されない場合に役立ちます。

于 2016-09-23T22:37:13.157 に答える
44

リフレッシュに関しても同様の問題がありました。ObservableList私の解決策は、 での操作をで正しく動作するものに制限することでしたbind()

ObservableList obsListが の基礎となるリストであると仮定しTableViewます。

その後
obsList.clear()(から継承java.util.List<>) は正しく更新されませんがTableView

また、更新をトリガーする呼び出しsetItem(obsList)機能しませんでした...しかし...

obsList.removeAll(obsList)(によって上書きされますObservableList)は、 changeEventを正しく起動するため、正常に動作します。

完全に新しいコンテンツでリストを補充すると、次のように機能します。

  • obsList.removeAll(obsList);
  • obsList.add(...); //e.g. in a loop...

また

  • obsList.removeAll(obsList);
  • FXCollections.copy(obsList, someSourceList)
于 2012-10-04T22:56:46.543 に答える
10

更新:
最後に、早期アクセスで利用可能なJavaFX 8u60でテーブルビューの更新が解決されました。


更新については、 Tableview での行の更新を参照してください。
空白の列については、JavaFx 2 create TableView with single column を参照してください。基本的には列ではありません。つまり、この空白列の項目をクリックして項目を選択することはできません。行のようなスタイルの空白の領域です。


更新:経由で tableView を更新している場合はreseller_table.setItems(data)、使用する必要はありませんSimpleStringProperty。1 つの行/アイテムのみを更新する場合に便利です。テーブル データを更新する実際の完全な例を次に示します。

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);
    }
}

ご了承ください

productTable.setItems(FXCollections.observableArrayList(newProducts));

productTable.getItems().clear();
productTable.getItems().addAll(newProducts);

ほぼ同等です。そのため、最初にテーブルを埋めるために1つを使用し、テーブルが更新されたときにもう1つを使用しました。これはデモ専用です。JavaFX 2.1 でコードをテストしました。最後に、質問への回答のコード部分を移動することで、質問を編集して改善することができます (そしてそうすべきです)。

于 2012-06-16T18:33:39.940 に答える
6

最後に、すべての行を更新するための醜い回避策を見つけました。

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);
        }
    });
 }
于 2012-07-24T05:42:13.320 に答える
2

このスレッドには、テーブルの更新に関する問題が非常によく説明されていると思います。

于 2012-09-22T23:55:00.473 に答える
1

Jira でこの問題を確認してください: https://bugs.openjdk.java.net/browse/JDK-8098085

コメント 2012-09-20 08:50 は、機能する回避策を提供しました。

//wierd JavaFX bug
reseller_table.setItems(null); 
reseller_table.layout(); 

ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);
于 2016-04-04T14:46:05.513 に答える
1

私は同じ問題を抱えていましたが、いくつかの検索の後、これが私の回避策です。列を削除してから再度追加すると、テーブルが更新されることがわかりました。

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);
于 2013-09-04T00:05:55.583 に答える
0

initialize() メソッド

fullNameColumn = new TableColumn("Full name");
fullNameColumn.setCellValueFactory(new PropertyValueFactory<User, String>("fullName"));
usernameColumn = new TableColumn("Username");
usernameColumn.setCellValueFactory(new PropertyValueFactory<User, String>("test"));
emailColumn = new TableColumn("Email");
emailColumn.setCellValueFactory(new PropertyValueFactory<User, String>("email"));
reseller_table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
reseller_table.getColumns().addAll(usernameColumn, fullNameColumn, emailColumn);

ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);

ユーザークラス (Hibernate POJO クラス)

private SimpleStringProperty test;

public void setFullName(String fullName) {
  this.fullName = fullName;
  this.test = new SimpleStringProperty(fullName);    
}

public SimpleStringProperty testProperty() {
  return test;
}

refresh() メソッド

ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);
于 2012-06-17T12:38:41.303 に答える
0

ダニエル・デ・レオンの答えに基づく

public static void refresh_table(TableView table) {
    for (int i = 0; i < table.getColumns().size(); i++) {
        ((TableColumn)(table.getColumns().get(i))).setVisible(false);
        ((TableColumn)(table.getColumns().get(i))).setVisible(true);
    }
}
于 2014-07-15T20:51:58.870 に答える
0

ここでも同じ問題があります。いくつかの解決策を試しましたが、私にとって最善の方法は次のとおりです。

コントローラーの initialize-method で、空の observableList を作成し、テーブルに設定します。

obsBericht = FXCollections.observableList(new ArrayList<Bericht>(0));
tblBericht.setItems(obsBericht);

update-method では、observableList を使用してクリアし、更新されたデータを追加します。

obsBericht.clear();
obsBericht.addAll(FXCollections.observableList(DatabaseHelper.getBerichte()));
// tblBericht.setItems(obsBericht);

テーブルの項目を再設定する必要はありません

于 2015-02-26T12:36:41.653 に答える
0

ダニエル・デ・レオンの答えに続いて...

  • モデルにダミー プロパティ「modelChangedProperty」を導入し、
  • モデルで、そのプロパティの値を変更するメソッド refresh() を作成しました。
  • コントローラーで、テーブル ビューを更新するダミー プロパティにリスナーを追加しました。

-

/**
 * 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);
}
于 2015-04-09T11:40:19.343 に答える
0

私の解決策はDaniel De Leónの回避策に似ていますが、最初の列 (彼の例ではインデックス 0) を非表示にする必要がある場合にも機能します。もちろん、彼のソリューションでインデックスを変更することもできますが、列を再配置する場合は、私のソリューションの方がうまくいく可能性があります。アイデアは、インデックスで列を非表示にして表示するのではなく、名前で列を非表示にして表示することです。

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);
            }
        }
    }
}

UI 更新スレッドでテーブルを更新することをお勧めします。updateMyTableView();ただし、 JavaFXはとにかくUIスレッドで更新されるように見えるため(それについてはわかりません)、テーブル内の何かを変更した後に呼び出すだけでも機能します。

Platform.runLater(new Runnable() {
    public void run() {
         updateMyTableView();
    }
});
于 2014-07-21T06:14:19.740 に答える
0

手動で更新する代わりに、監視可能なプロパティを使用する必要があります。この質問の回答は、目的の例です: SimpleStringProperty および SimpleIntegerProperty TableView JavaFX

于 2014-07-04T12:30:06.593 に答える
-11

私が始め終認したために変更されたTableColumnのvisable屬的方法を利用したデータバインディングの精神,若這いはJavaFXのバグ那也早くこの接は決着しました,この拖到Java8了還不解決。</p>

過トレース JavaFX のソース コード後、並沒有發現バグ。 </p>

                                                           解決於台灣台北

Column Visable Property の変更を使用することを確認しましたが、データ バインディングの自動化の目的に準拠していません。

JavaFX TableView のソースコードをトレースした後。Tableview バインディングの問題の問題コードを発見したことはありません。4 週間前に、POJO フィールドの型を DoubleProperty から WritableObjectValue に変更したところ、問題は解決しました。

                                               resolve in Taiwan Taipei.

サンプルコード:</p>

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)
        }

    });
于 2015-05-31T08:35:21.393 に答える