it-swarm.com.de

JavaFX 2.1 TableView-Aktualisierungselemente

Ich habe dieses gemeinsame Problem, wie es scheint. Meine Tabellenansicht aktualisiert meine Elemente nicht, nachdem ich sie zurückgesetzt habe. Ich habe die Daten geprüft und es sind die neuen. 

Ich habe mehrere Lösungen aus dem Internet ausprobiert, aber kein Erfolg. 

Alle Spalten können nicht zurückgesetzt werden, da dadurch eine zusätzliche leere hinzugefügt wird (weiß nicht warum) und die Größenänderung bricht einfach ab.

Meine Tabelle ist nicht editierbar. Die neuen Daten werden geändert.

Die Daten werden aktualisiert, wenn ich Reihenfolge ändern der Elemente und die Zeilen ändern (: |).

Ich bin nur ohne Ideen.

Im Moment ist der Aktualisierungscode ziemlich einfach.

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

Wieder sind die neuen Daten korrekt. Wenn ich das tableView auswähle, wird das neue korrekte Element zurückgegeben.

54
user1236048

Ich hatte ein ähnliches Problem mit der Erfrischung. Meine Lösung bestand darin, die Operationen auf dem ObservableList auf diejenigen zu beschränken, die mit bind() korrekt funktionieren.

Angenommen, ObservableList obsList ist die zugrunde liegende Liste für TableView.

Dann
obsList.clear() (von Java.util.List<> geerbt) wird nicht aktualisieren das TableView aber korrekt.

Auch der Aufruf von setItem(obsList) hat funktioniert nicht eine Aktualisierung ausgelöst ... aber ...

obsList.removeAll(obsList) (überschrieben von ObservableList) funktioniert einwandfrei weil es das changeEvent korrekt auslöst.

Das Nachfüllen einer Liste mit komplett neuem Inhalt funktioniert dann wie folgt:

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

oder

  • obsList.removeAll(obsList);
  • FXCollections.copy(obsList, someSourceList)

Viele Grüße Ingo

36
Ingo

Problemumgehung:

 tableView.getColumns().get(0).setVisible(false);
 tableView.getColumns().get(0).setVisible(true);
59
Daniel De León

Da JavaFX 8u60 verwendet werden kann (vorausgesetzt, tableView ist eine Instanz von TableView class):

tableView.refresh();

Aus der Dokumentation:

Der Aufruf von refresh () zwingt das TableView-Steuerelement zur Neuerstellung von und Füllen Sie die erforderlichen Zellen erneut auf, um die visuellen Begrenzungen von .__ zu füllen. Steuerung. Mit anderen Worten, dies zwingt die TableView zu einer Aktualisierung von wird dem Benutzer angezeigt. Dies ist nützlich, wenn das zugrunde liegende Datenquelle hat sich in einer Weise geändert, die von TableView nicht beobachtet wird selbst.

37
Elltz

UPDATE:
Schließlich wird die Aktualisierung der Tabellenansicht in JavaFX 8u60 aufgelöst, das für einen frühen Zugriff verfügbar ist.


Informationen zum Aktualisieren finden Sie in den Zeilen in Tableview aktualisieren .
Und über die leere Spalte siehe JavaFx 2 TableView mit Einzelspalte erstellen . Im Grunde ist es keine Spalte, d. H. Sie können das Element nicht auswählen, wenn Sie auf diese leeren Spaltenelemente klicken. Es ist nur ein leerer Bereich im Stil einer Reihe.


UPDATE: Wenn Sie die tableView über reseller_table.setItems(data) aktualisieren, müssen Sie SimpleStringProperty nicht verwenden. Es wäre nützlich, wenn Sie nur eine Zeile/einen Artikel aktualisieren. Hier ist ein ausführliches Beispiel zum Aktualisieren der Tabellendaten: 

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

Beachten Sie, dass

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

und 

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

sind fast gleichwertig. Also habe ich die eine verwendet, um die Tabelle zum ersten Mal zu füllen, und eine andere, wenn die Tabelle aktualisiert wird. Es ist nur zu Demonstrationszwecken. Ich habe den Code in JavaFX 2.1 getestet. Und schließlich können (und sollten) Sie Ihre Frage bearbeiten, um sie zu verbessern, indem Sie die Code-Teile in Ihrer Antwort auf Ihre Frage verschieben.

7
Uluk Biy

Ich fand endlich eine hässliche Lösung, um alle Zeilen aufzufrischen.

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

Es scheint mehrere verschiedene Probleme um oldItems.equals (newItems) zu geben.

Der erste Teil von RT-22463 : tableView wird nicht aktualisiert, auch wenn items.clear () aufgerufen wird.

// refresh table 
table.getItems().clear();
table.setItems(listEqualToOld);    

das ist behoben. Wenn Sie die alten Elemente löschen, bevor Sie eine neue Liste festlegen, wird der alte Status gelöscht, und die Tabelle wird aktualisiert. Jedes Beispiel, bei dem dies nicht funktioniert, kann eine Regression sein.

Was immer noch nicht funktioniert, ist das erneute Einstellen von Elementen ohne vorheriges Löschen

// refresh table
table.setItems(listEqualToOld); 

Dies ist ein Problem, wenn die Tabelle Eigenschaften anzeigt, die nicht in die Gleichheitsentscheidung eines Artikels einbezogen sind (siehe Beispiel in RT-22463 oder Aubin's ) und - hoffentlich - von RT-39094 abgedeckt wird. 

UPDATE: RT-39094 Letzteres ist ebenfalls festgelegt, für 8u40! Sollte in ein paar Wochen in den EA sprudeln, spekulieren Sie auf u12 oder so. 

Der technische Grund scheint eine Gleichheitsprüfung in der Zellenimplementierung zu sein: Die Überprüfung auf Änderungen des Elements vor dem tatsächlichen Aufruf von updateItem (T, boolean) wurde eingeführt, um Leistungsprobleme zu beheben. Angemessen, nur um hart zu "ändern" == old.equals (new) wirft in einigen Zusammenhängen Probleme auf. 

Eine Umgehung, die für mich in Ordnung ist (keine formalen Tests!), Ist eine benutzerdefinierte TableRow, die bei Identitätsüberprüfungen einspringt:

/**
 * 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());

Beachten Sie, dass TableCell eine ähnliche hartcodierte Gleichheitsprüfung durchführt. Wenn die benutzerdefinierte Zeile nicht ausreicht, kann es erforderlich sein, eine benutzerdefinierte TableCell mit einer ähnlichen Problemumgehung zu verwenden (haben Sie jedoch kein Beispiel ausgeführt, bei dem dies erforderlich ist.)

3
kleopatra

Ich nehme an, dieser Thread hat eine sehr gute Beschreibung des Problems beim Aktualisieren der Tabelle.

2
Alex

Die Lösung von user1236048 ist korrekt, aber der Schlüsselpunkt wird nicht aufgerufen. In Ihren POJO-Klassen, die für die beobachtbare Liste der Tabelle verwendet werden, müssen Sie nicht nur Get- und Setter-Methoden festlegen, sondern auch eine neue, die als Property bezeichnet wird. In Oracle 'Tableview-Tutorial ( http://docs.Oracle.com/javafx/2/ui_controls/table-view.htm ) - haben sie diesen Schlüsselteil auslassen!

So sollte die Person-Klasse aussehen:

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

}

1
Kevin Reynolds

Ich habe einen Anwendungsfall, bei dem nichts anderes als die Lösung von Aubin geholfen hat. Ich passte die Methode an und änderte sie, indem ich ein Element entfernte und zur Elementliste der Tabellen hinzufügte, da es am Ende nur mit diesem Hack zuverlässig funktioniert. Die Spalte mit der sichtbaren Spalte erledigte den Job nur beim ersten Mal.

Ich habe es auch in der Jira-Aufgabe gemeldet: https://javafx-jira.kenai.com/browse/RT-22463

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

Sehen Sie sich dieses Problem in Jira an: https://bugs.openjdk.Java.net/browse/JDK-8098085

ein Kommentar 2012-09-20 08:50 gab einen Workaround, der funktioniert.

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

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

Ich hatte das gleiche Problem und nach einiger Suche ist dies meine Problemumgehung. Ich habe festgestellt, dass die Tabelle aktualisiert wird, wenn die Spalten entfernt und dann wieder hinzugefügt werden.

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


Verwendungsbeispiel:

refreshTableView(myTableView, Arrays.asList(col1, col2, col3), rows);
1
ceklock

Anstatt manuell zu aktualisieren, sollten Sie beobachtbare Eigenschaften verwenden. Die Antworten auf diese Frage zeigen den Zweck: SimpleStringProperty und SimpleIntegerProperty TableView JavaFX

1
Andreas

Basierend auf der Antwort von Daniel De León 

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

JavaFX8

Ich füge ein neues Element von einer DialogBox hinzu. Hier ist mein Code.

ObservableList<Area> area = FXCollections.observableArrayList();

Bei initialize () oder setApp ()

this.areaTable.setItems(getAreaData());

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

Hinzufügen über ein Dialogfeld.

@FXML
private void handleNewArea() {
    Area tempArea = new Area();
    boolean okClicked = showAreaDialog(tempArea);
    if (okClicked) {
        addNewArea(tempArea);
        this.area.add(tempArea); // To inform ObservableList
    }

}

Area ist ein gewöhnlicher JavaFX-POJO. 

1

Was für ein Fehler! Hier ist eine weitere Problemumgehung ...

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

Ich habe ein SSCCE gemacht, um den Fehler anzuzeigen. Ich ermutige jeden, es auf eine andere, elegantere Weise zu beheben, da meine Problemumgehung sehr hässlich ist!

1
Aubin

Dasselbe Problem hier, ich habe einige Lösungen ausprobiert und das Beste für mich ist folgendes:

Erstellen Sie in der Initialisierungsmethode des Controllers eine leere observableList und setzen Sie sie auf die Tabelle:

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

Verwenden Sie in Ihrer Update-Methode einfach die observableList, löschen Sie sie und fügen Sie die aktualisierten Daten hinzu:

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

Es ist nicht erforderlich, die Elemente der Tabelle erneut festzulegen

0
Tom

Ich bin nicht sicher, ob dies auf Ihre Situation zutrifft, aber ich werde posten, was für mich funktioniert hat.

Ich ändere meine Tabellenansicht basierend auf Abfragen/Suchvorgängen in eine Datenbank. Beispielsweise enthält eine Datenbanktabelle Patientendaten. Meine anfängliche Tabellenansicht in meinem Programm enthält alle Patienten. Ich kann dann nach firstName und lastName nach Patienten suchen. Ich verwende die Ergebnisse dieser Abfrage, um meine Beobachtungsliste erneut aufzufüllen. Dann setze ich die Elemente in der Tableview zurück, indem ich tableview.setItems (observableList) aufrufe:

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

Die if-Blöcke aktualisieren die ObservableList mit den Abfrageergebnissen.

0
user2951579

Meine Lösung ähnelt der Problemumgehung von Daniel De León , funktioniert jedoch auch, wenn Sie die erste Spalte (Index 0 in seinem Beispiel) ausblenden müssen. Natürlich können Sie einfach den Index in seiner Lösung ändern, aber wenn Sie die Spalten neu anordnen, funktioniert meine Lösung möglicherweise besser für Sie. Die Idee ist, die Spalte nach ihrem Namen auszublenden und anzuzeigen, anstatt sie zu verbergen und nach ihrem Index anzuzeigen: 

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

Am besten aktualisieren Sie Ihre Tabelle im UI-Aktualisierungsthread. Es funktioniert jedoch auch, indem Sie einfach updateMyTableView(); aufrufen, nachdem Sie etwas in Ihrer Tabelle geändert haben, da JavaFX im UI-Thread sowieso zu aktualisieren scheint (was nicht sicher ist).

Platform.runLater(new Runnable() {
    public void run() {
         updateMyTableView();
    }
});
0
Michael

initialize () -Methode

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

Benutzerklasse (Hibernate POJO-Klasse)

private SimpleStringProperty test;

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

public SimpleStringProperty testProperty() {
  return test;
}

refresh () -Methode

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

Ich weiß, dass diese Frage 4 Jahre alt ist, aber ich habe das gleiche Problem, ich habe die Lösungen von oben aus probiert und nicht funktioniert. Ich habe auch die Methode refresh () genannt, aber immer noch nicht mein erwartetes Ergebnis. Also ich poste hier meine Lösung vielleicht hilft jemandem.

Question db = center.getSelectionModel().getSelectedItem();
new QuestionCrud().deleteQ(db.getId());
ObservableList<Question> aftDelete = FXCollections.observableArrayList(
        (new QuestionCrud()).all()
        );
center.setItems(aftDelete);

Auch wenn ich vorher eine andere Variable in ObeservableList verwendet habe, um Elemente in die Tableview zu setzen, nenne ich dies eine "schmutzige Methode", aber bis ich eine bessere Lösung bekomme, ist ok.

0
Wolf Marian

Nach der Antwort von Daniel De León ... 

  • Ich habe eine Dummy-Eigenschaft "modelChangedProperty" in mein Modell eingeführt 
  • in meinem Modell wurde eine Methode refresh () erstellt, die den Wert dieser Eigenschaft ändert.
  • In meinem Controller habe ich der Dummy-Eigenschaft einen Listener hinzugefügt, der die Tabellenansicht aktualisiert. 

-

/**
 * 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);
}
0
Stefan

Ich habe versucht, die tableView (ScalaFx) für 3-4 Stunden zu aktualisieren. Endlich bekam ich eine Antwort. Ich möchte meine Lösung nur veröffentlichen, weil ich schon Stunden vergeudet habe. 

- Um die Zeilen aus der Datenbank abzurufen, deklarierte ich eine Methode, die ObservableBuffer zurückgibt.

Meine JDBC-Klasse

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

-Und ich habe ein TableView-Objekt erstellt. 

var table = new TableView[Customer](model.getCustomerDetails)
table.columns += (customerIdColumn,customerNameColumn,productInstallColumn,serviceDateColumn,
        productNameColumn,phoneNoColumn,detailColumn)

-Und endlich habe ich Lösung. In der Aktualisierungsschaltfläche habe ich diesen Code eingefügt. 

table.setItems(FXCollections.observableArrayList(model.getCustomerDetails.delegate))

model ist die Referenz meiner jdbc-Verbindungsklasse

val model = new ScalaJdbcConnectSelect

Dies ist der Code von scalafx, aber er gibt Javafx eine Idee

Nach der Suche nach allen möglichen Lösungen. Ich habe versucht, Daten zuerst zu löschen und dann in der Tabellenansicht tableView.getItems().clear(); hinzugefügt, was mein Problem jedoch nicht gelöst hat. Ich habe alle hier gegebenen Antworten ausprobiert, funktionierte jedoch nicht für mich und hatte immer noch veraltete Objekte in meinem Tisch, wie in der folgenden Abbildung gezeigt:

 enter image description here

Um das Problem zu beheben, habe ich ein DUMMY-Label erstellt und setGraphic wie folgt verwendet:

 enter image description here

0
Vishrant