3

私のアプリケーションは、JPA 読み取りデータを TableView に使用し、それらを変更して表示します。表は、JavaFx 2.0.3 で変更されたレコードを更新しました。JavaFx 2.1、2.2 では、テーブルは更新を更新しなくなりました。他の人にも同様の問題があることがわかりました。私の計画は、誰かが 2.1 と 2.2 で問題を修正するまで、2.0.3 を使い続けることでした。これはバグではなく、修正されないことがわかりました。うーん、どう対処したらいいのかわからない。以下は、問題を示すためにサンプル デモから変更されたコードです。新しいレコードを追加するか、テーブルから古いレコードを削除すると、テーブルが正常に更新されます。レコードを変更すると、追加、削除、または並べ替えのアクションが実行されるまで、テーブルは変更を更新しません。変更したレコードを削除して再度追加すると、テーブルが更新されます。ただし、変更されたレコードはテーブルのボタンに置​​かれます。変更されたレコードを削除すると、同じレコードを追加してからレコードを元の場所に移動すると、テーブルが更新されなくなります。以下は完全なコードです。これに光を当ててください。

    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.geometry.HPos;
    import javafx.geometry.Insets;
    import javafx.geometry.Pos;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.layout.GridPane;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.VBox;
    import javafx.scene.text.Font;
    import javafx.stage.Modality;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;

    public class Main extends Application {

        private TextField firtNameField = new TextField();
        private TextField lastNameField = new TextField();
        private TextField emailField = new TextField();
        private Stage editView;
        private Person fPerson;

        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 String getLastName() {
                return lastName.get();
            }

            public void setLastName(String fName) {
                lastName.set(fName);
            }

            public String getEmail() {
                return email.get();
            }

            public void setEmail(String fName) {
                email.set(fName);
            }
        }
        private TableView<Person> table = new TableView<Person>();
        private final ObservableList<Person> data =
                FXCollections.observableArrayList(
                new Person("Jacob", "Smith", "jacob.smith@example.com"),
                new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
                new Person("Ethan", "Williams", "ethan.williams@example.com"),
                new Person("Emma", "Jones", "emma.jones@example.com"),
                new Person("Michael", "Brown", "michael.brown@example.com"));

        public static void main(String[] args) {
            launch(args);
        }

        @Override
        public void start(Stage stage) {
            Scene scene = new Scene(new Group());
            stage.setTitle("Table View Sample");
            stage.setWidth(535);
            stage.setHeight(535);
            editView = new Stage();

            final Label label = new Label("Address Book");
            label.setFont(new Font("Arial", 20));

            TableColumn firstNameCol = new TableColumn("First Name");
            firstNameCol.setCellValueFactory(
                    new PropertyValueFactory<Person, String>("firstName"));
            firstNameCol.setMinWidth(150);

            TableColumn lastNameCol = new TableColumn("Last Name");
            lastNameCol.setCellValueFactory(
                    new PropertyValueFactory<Person, String>("lastName"));
            lastNameCol.setMinWidth(150);
            TableColumn emailCol = new TableColumn("Email");
            emailCol.setMinWidth(200);
            emailCol.setCellValueFactory(
                    new PropertyValueFactory<Person, String>("email"));

            table.setItems(data);
            table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
    //--- create a edit button and a editPane to edit person   
            Button addButton = new Button("Add");
            addButton.setOnAction(new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent event) {
                    fPerson = null;
                    firtNameField.setText("");
                    lastNameField.setText("");
                    emailField.setText("");
                    editView.show();
                }
            });
            Button editButton = new Button("Edit");
            editButton.setOnAction(new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent event) {
                    if (table.getSelectionModel().getSelectedItem() != null) {
                        fPerson = table.getSelectionModel().getSelectedItem();
                        firtNameField.setText(fPerson.getFirstName());
                        lastNameField.setText(fPerson.getLastName());
                        emailField.setText(fPerson.getEmail());
                        editView.show();
                    }
                }
            });
            Button deleteButton = new Button("Delete");
            deleteButton.setOnAction(new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent event) {
                    if (table.getSelectionModel().getSelectedItem() != null) {
                        data.remove(table.getSelectionModel().getSelectedItem());
                    }
                }
            });
            HBox addEditDeleteButtonBox = new HBox();
            addEditDeleteButtonBox.getChildren().addAll(addButton, editButton, deleteButton);
            addEditDeleteButtonBox.setAlignment(Pos.CENTER_RIGHT);
            addEditDeleteButtonBox.setSpacing(3);

            GridPane editPane = new GridPane();
            editPane.getStyleClass().add("editView");
            editPane.setPadding(new Insets(3));
            editPane.setHgap(5);
            editPane.setVgap(5);
            Label personLbl = new Label("Person:");
            editPane.add(personLbl, 0, 1);
            GridPane.setHalignment(personLbl, HPos.LEFT);

            firtNameField.setPrefWidth(250);
            lastNameField.setPrefWidth(250);
            emailField.setPrefWidth(250);
            Label firstNameLabel = new Label("First Name:");
            Label lastNameLabel = new Label("Last Name:");
            Label emailLabel = new Label("Email:");

            editPane.add(firstNameLabel, 0, 3);
            editPane.add(firtNameField, 1, 3);
            editPane.add(lastNameLabel, 0, 4);
            editPane.add(lastNameField, 1, 4);
            editPane.add(emailLabel, 0, 5);
            editPane.add(emailField, 1, 5);
            GridPane.setHalignment(firstNameLabel, HPos.RIGHT);
            GridPane.setHalignment(lastNameLabel, HPos.RIGHT);
            GridPane.setHalignment(emailLabel, HPos.RIGHT);

            Button saveButton = new Button("Save");
            saveButton.setOnAction(new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent event) {
                    if (fPerson == null) {
                        fPerson = new Person(
                                firtNameField.getText(),
                                lastNameField.getText(),
                                emailField.getText());
                        data.add(fPerson);
                    } else {
                        int k = -1;
                        if (data.size() > 0) {
                            for (int i = 0; i < data.size(); i++) {
                                if (data.get(i) == fPerson) {
                                    k = i;
                                }
                            }
                        }
                        fPerson.setFirstName(firtNameField.getText());
                        fPerson.setLastName(lastNameField.getText());
                        fPerson.setEmail(emailField.getText());
                        data.set(k, fPerson);
                        table.setItems(data);

    //  The following will work, but edited person has to be added to the button
    //
    //                    data.remove(fPerson);
    //                    data.add(fPerson);

    // add and remove refresh the table, but now move edited person to original spot, 
    // it failed again with the following code
    //                    while (data.indexOf(fPerson) != k) {
    //                        int i = data.indexOf(fPerson);
    //                        Collections.swap(data, i, i - 1);
    //                    }
                    }
                    editView.close();
                }
            });
            Button cancelButton = new Button("Cancel");
            cancelButton.setOnAction(new EventHandler<ActionEvent>() {

                @Override
                public void handle(ActionEvent event) {
                    editView.close();
                }
            });

            HBox saveCancelButtonBox = new HBox();
            saveCancelButtonBox.getChildren().addAll(saveButton, cancelButton);
            saveCancelButtonBox.setAlignment(Pos.CENTER_RIGHT);
            saveCancelButtonBox.setSpacing(3);

            VBox editBox = new VBox();
            editBox.getChildren().addAll(editPane, saveCancelButtonBox);

            Scene editScene = new Scene(editBox);
            editView.setTitle("Person");
            editView.initStyle(StageStyle.UTILITY);
            editView.initModality(Modality.APPLICATION_MODAL);
            editView.setScene(editScene);
            editView.close();

            final VBox vbox = new VBox();
            vbox.setSpacing(5);
            vbox.getChildren().addAll(label, table, addEditDeleteButtonBox);
            vbox.setPadding(new Insets(10, 0, 0, 10));

            ((Group) scene.getRoot()).getChildren().addAll(vbox);

            stage.setScene(scene);
            stage.show();
        }
    }
4

7 に答える 7

5

Updating rows in Tableview への回答を参照してください。これらのゲッターを追加すると、うまくいきます。
また、dataObservableListtableView の項目として設定されているため、このdataリストへの変更は にも反映されtable.getItems()ます。つまり、table.setItems(data)再度行う必要はありません。

于 2012-06-30T10:39:45.693 に答える
5

TableView.java コードを見ると、実行するだけのプライベート refresh() があります

getProperties().put(TableViewSkinBase.REFRESH, Boolean.TRUE); 

最後に、以下のコードが機能しました(Java8)。(定数の名前は REFRESH ではなく RECREATE であることに注意してください)

tableView.getProperties().put(TableViewSkinBase.RECREATE, Boolean.TRUE);

(javafx のコードを読むと、セルの再作成が強制されます)

于 2015-03-29T07:07:05.337 に答える
5

JavaFX 2.1 TableView refresh itemsで TableView の更新をトリガーするための簡単な回避策を見つけました。それは私にとって問題を解決しました。

これをコードに追加します。

tableView.getColumns().get(0).setVisible(false);
tableView.getColumns().get(0).setVisible(true);
于 2014-02-21T11:50:07.167 に答える
0

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

public static <T,U> void refreshTableView(final TableView<T> tableView, final List<TableColumn<T,U>> columns, final List<T> rows) {
    if (tableView == null) {
        throw new NullPointerException();
    }
    if (columns == null) {
        throw new NullPointerException();
    }
    if (rows == null) {
        throw new NullPointerException();
    }

    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:20:13.587 に答える
0

私は同じ問題を抱えており、JPA で使用される POJO に追加できないと、SimpleStringPropertyこれが少し問題になります。しかし、次の動作に気付いたので、これは修正可能な問題であるように思われます。

  1. 私のアプリケーションでは、テーブルの行をクリックすると、画面にいくつかのテキスト フィールドが表示され、ユーザーはそれを編集できます。
  2. その時点で、ユーザーはデータを保存するか、同じデータまたは変更されたデータで新しいアイテムを作成できます。ユーザーが新しいアイテムを作成し、それがテーブルビューが表す監視可能なリストに挿入されると、変更はすぐにテーブルビューの内容に反映されます。ただし、ユーザーが変更を保存しただけでは、新しいデータはテーブルに反映されません。新しいデータをリストに入れるには、私は単純にやっています

    trialList.set(currentIndex, tempTrial);
    
  3. そして、これが修正可能な問題であると私が指摘しているのは次のとおりです。影響を受ける行をテーブルのビューからスクロールしてからスクロールして戻すと、「新しい」値が表示されるようになりました。

うまくいけば、これは修正できます。申し訳ありませんが、これはいわば答えではありませんが、修正のための洞察を提供する可能性があります。

于 2012-07-10T15:12:47.397 に答える
0

これは私のために働いた

@FXML 
private void refreshTableView()
{
  firstNameCol.setVisible(false);
  lastNameCol.setVisible(false);
  emailCol.setVisible(false); 
  firstNameCol.setVisible(true);
  lastNameCol.setVisible(true);
  emailCol.setVisible(true);
} 
于 2013-08-01T18:02:30.333 に答える