JavaFX 2.1 TableView aggiorna elementi


Ho questo problema comune, come sembra essere. La mia vista tabella non aggiornerà i miei articoli dopo averli ripristinati. Ho controllato i dati ed è quello nuovo.

Ho provato più soluzioni da Internet ma senza successo.

Non può reimpostare tutte le colonne perché ne aggiunge una vuota in più (non so perché) e il ridimensionamento si interrompe.

La mia tabella non è modificabile. I nuovi dati vengono modificati.

I dati vengono aggiornati se I modificano l'ordine degli elementi e le righe cambiano (:/).

Sono rimasto senza idee.

Al momento il codice di aggiornamento è piuttosto semplice.

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

Di nuovo i nuovi dati sono corretti. Quando effettuo una selezione a tableView restituisce il nuovo elemento corretto.

Author: kleopatra, 2012-06-16

24 answers

Ho avuto un problema simile con l'aggiornamento. La mia soluzione era limitare le operazioni su ObservableList a quelle che funzionano correttamente con bind().

Supponiamo che ObservableList obsList sia l'elenco sottostante per TableView.

Allora
obsList.clear() (ereditato da java.util.List<>) non aggiornerà il TableView correttamente ma.

Chiamando anche setItem(obsList) non ha funzionato per attivare un aggiornamento...ma...

obsList.removeAll(obsList) (sovrascritto da ObservableList) funziona bene perché spara il changeEvent correttamente.

La ricarica di un elenco con contenuti completamente nuovi funziona come segue:

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

O

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

Cordiali saluti Ingo

 33
Author: Ingo, 2018-06-04 10:59:07

Soluzione alternativa:

 tableView.getColumns().get(0).setVisible(false);
 tableView.getColumns().get(0).setVisible(true);
 58
Author: Daniel De León, 2012-09-27 03:45:16

Poiché JavaFX 8u60 puoi usare (supponendo che tableView sia un'istanza di TableView class):

tableView.refresh();

Dalla documentazione:

Chiamando refresh() forza il controllo TableView per ricreare e ripopolare le cellule necessarie per popolare i limiti visivi dell' controllo. In altre parole, questo costringe TableView ad aggiornare ciò che sta mostrando all'utente. Questo è utile nei casi in cui il sottostante origine dati è cambiato in un modo che non è osservato dal Vista tabella stesso.

 31
Author: Elltz, 2016-09-24 00:46:50

AGGIORNAMENTO:
Infine tableview rinfrescante è risolto in JavaFX 8u60 , che è disponibile per l'accesso anticipato.


Informazioni sull'aggiornamento vedere le righe di aggiornamento in Tableview .
E sulla colonna vuota vedi JavaFX 2 crea TableView con una singola colonna . Fondamentalmente non è una colonna, cioè non è possibile selezionare l'elemento facendo clic su questi elementi di colonna vuoti. È solo un'area vuota in stile come una riga.


AGGIORNAMENTO: Se si sta aggiornando tableView tramite reseller_table.setItems(data), quindi non è necessario utilizzare SimpleStringProperty. Sarebbe utile se si stesse aggiornando solo una riga / elemento. Ecco un esempio completo di aggiornamento dei dati della tabella:

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

Si noti che

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

E

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

Sono quasi equivalenti. Quindi ho usato quello per riempire la tabella per la prima volta e l'altro quando la tabella viene aggiornata. È solo a scopo dimostrativo. Ho testato il codice in JavaFX 2.1. E infine, puoi (e dovresti) modificare il tuo domanda per migliorarlo spostando i pezzi di codice nella risposta alla tua domanda.

 7
Author: Uluk Biy, 2017-05-23 11:47:07

Ho finalmente trovato una brutta soluzione per aggiornare tutte le righe.

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
Author: Javarian, 2012-07-24 05:51:55

Sembrano esserci diversi problemi separati intorno a oldItems.equals (newItems)

La prima parte di RT-22463: tableView non verrà aggiornata anche se si chiamano elementi.cancella ()

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

Questo è corretto. Cancellare i vecchi elementi prima di impostare un nuovo elenco cancella tutto il vecchio stato, aggiornando così la tabella. Qualsiasi esempio in cui questo non funziona potrebbe essere una regressione.

Ciò che ancora non funziona è reimpostare gli elementi senza prima cancellare

// refresh table
table.setItems(listEqualToOld); 

Questo è un problema se la tabella mostra le proprietà che non sono coinvolte nella decisione di parità di un elemento (vedi esempio in RT-22463 o di Aubin) e coperte-si spera-da RT-39094

AGGIORNA: RT-39094 anche quest'ultimo è fisso, per 8u40! Dovrebbe bolla fino in ea in un paio di settimane, speculando su u12 o tale.

La ragione tecnica sembra essere un controllo di uguaglianza nell'implementazione della cella: controllare le modifiche dell'elemento prima di essere effettivamente chiamata updateItem (T, boolean) è stato introdotto per risolvere i problemi di prestazioni. Ragionevole, solo per "cambiare" hard-code = = vecchio.equals (new) pone problemi in alcuni contesti.

Un work-around che va bene per me (nessun test formale!) è un TableRow personalizzato che salta se è richiesto il controllo dell'identità:

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

Si noti che TableCell ha un controllo di uguaglianza hard-coded simile, quindi se la riga personalizzata non è sufficiente potrebbe essere necessario utilizzare una TableCell personalizzata con una soluzione alternativa simile (non eseguire un esempio in cui è necessario, però)

 2
Author: kleopatra, 2014-10-24 11:59:41

Suppongo questo thread ha una descrizione molto buona del problema con l'aggiornamento della tabella.

 2
Author: Alex, 2015-03-13 01:31:56

Che BUG ! Ecco un'altra soluzione...

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

Ho fatto un SSCCEper mostrare il bug. Incoraggio tutti a risolverlo in un altro modo più elegante perché la mia soluzione è molto brutta!

 1
Author: Aubin, 2013-07-27 10:08:16

Ho un caso d'uso in cui nient'altro ha aiutato come soluzione da Aubin. Ho adattato il metodo e l'ho cambiato rimuovendo e aggiungendo un elemento all'elenco degli elementi delle tabelle poiché funziona alla fine solo affidabile con questo hack, la colonna visibile toggle ha fatto il lavoro solo la prima volta.

L'ho segnalato anche nel task Jira: 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
Author: Andreas Niemeyer, 2013-08-23 09:23:51

Ho avuto lo stesso problema e dopo qualche ricerca questa è la mia soluzione. Ho scoperto che se le colonne vengono rimosse e quindi aggiunte nuovamente la tabella viene aggiornata.

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


Esempio di utilizzo:

refreshTableView(myTableView, Arrays.asList(col1, col2, col3), rows);
 1
Author: ceklock, 2014-03-30 00:01:23

La soluzione di user1236048 è corretta, ma il punto chiave non viene richiamato. Nelle classi POJO utilizzate per l'elenco osservabile della tabella, non devi solo impostare i metodi getter e setter, ma uno nuovo chiamato Proprietà. Nel tutorial tableview di Oracle ( http://docs.oracle.com/javafx/2/ui_controls/table-view.htm ), hanno lasciato quella parte chiave fuori!

Ecco come dovrebbe essere la classe 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;
        }

}

 1
Author: Kevin Reynolds, 2014-06-12 22:24:46

Invece di aggiornare manualmente dovresti usare le proprietà osservabili. Le risposte di questa domanda esempi lo scopo: SimpleStringProperty e SimpleIntegerProperty TableView JavaFX

 1
Author: Andreas, 2017-05-23 11:54:37

Sulla base della risposta di 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
Author: Phloo, 2014-07-15 20:51:58

Dai un'occhiata a questo problema in Jira: https://bugs.openjdk.java.net/browse/JDK-8098085

Un commento 2012-09-20 08: 50 ha dato una soluzione che funziona.

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

ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);
 1
Author: Andrei Krasutski, 2016-04-04 14:46:05

JavaFX8

Sto aggiungendo un nuovo elemento da una finestra di dialogo. Ecco il mio codice.

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

Initialize () o 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;
    }
}

Aggiungi per finestra di dialogo.

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

}

Area è un POJO JavaFX ordinario. Spero che questo aiuti qualcuno.

 1
Author: Sudhakar Krishnan, 2017-03-02 13:10:05

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

Classe utente (Ibernazione classe POJO)

private SimpleStringProperty test;

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

public SimpleStringProperty testProperty() {
  return test;
}

Metodo Refresh ()

ObservableList<User> data = FXCollections.observableArrayList(User.getResellers());
reseller_table.setItems(data);
 0
Author: alex.dominte, 2012-06-17 12:38:41

La mia soluzione è simile alla soluzione alternativa di Daniel De León, ma funziona anche quando è necessario nascondere la prima colonna (indice 0 nel suo esempio). Ovviamente potresti semplicemente cambiare l'indice nella sua soluzione, ma se stai riorganizzando le colonne, la mia soluzione potrebbe funzionare meglio per te. L'idea è di nascondere e mostrare la colonna con il suo nome invece di nasconderla e mostrarla con il suo indice:

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

È meglio aggiornare la tabella nel thread di aggiornamento dell'interfaccia utente. Tuttavia, funziona anche semplicemente chiamando updateMyTableView(); dopo aver cambiato qualcosa nella tua tabella, dal momento che JavaFX sembra aggiornarsi comunque nel thread dell'interfaccia utente (non ne sono sicuro).

Platform.runLater(new Runnable() {
    public void run() {
         updateMyTableView();
    }
});
 0
Author: Michael, 2017-05-23 12:26:04

Non sono sicuro se questo si applica alla tua situazione, ma pubblicherò ciò che ha funzionato per me.

Cambio la mia vista tabella in base a query / ricerche in un database. Ad esempio, una tabella di database contiene i dati del paziente. La mia vista tabella iniziale nel mio programma contiene tutti i pazienti. Posso quindi cercare query per i pazienti per nome e cognome. Io uso i risultati di questa query per ripopolare la mia lista osservabile. Quindi reimpostare gli elementi nella tableview chiamando tableview.setItems (observableList):

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

I blocchi if aggiornano ObservableList con i risultati della query.

 0
Author: user2951579, 2014-11-30 18:06:42

Stesso problema qui, ho provato alcune soluzioni e il meglio per me sta seguendo:

In initialize-method of controller, creare un observableList vuoto e impostarlo sulla tabella:

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

Nel tuo metodo di aggiornamento, usa semplicemente observableList, cancellalo e aggiungi i dati aggiornati:

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

Non è necessario impostare nuovamente gli elementi della tabella

 0
Author: Tom, 2015-02-26 12:36:41

Seguendo la risposta di Daniel De León ...

  • Ho introdotto una proprietà fittizia "modelChangedProperty" nel mio modello e
  • ha creato un metodo refresh() nel mio modello che modifica il valore di quella proprietà.
  • Nel mio controller ho aggiunto un Listener alla proprietà dummy che aggiorna la vista tabella.

-

/**
 * 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
Author: Stefan, 2015-04-09 11:40:19

So che questa domanda ha 4 anni ma ho lo stesso problema, provai le soluzioni dall'alto e non funzionai. Ho anche chiamato il metodo refresh () ma ancora non il mio risultato previsto. Quindi pubblico qui la mia soluzione forse aiuterà qualcuno.

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

Anche se prima di questo ho usato un'altra variabile in ObeservableList per impostare gli elementi in tableview, lo chiamo un "metodo sporco" ma fino a quando non ottengo una soluzione migliore è ok.

 0
Author: Wolf Marian, 2016-12-30 19:38:48

Ho cercato di trovare un modo per aggiornare tableView(ScalaFx) per 3-4 ore. Finalmente ho avuto una risposta. Voglio solo pubblicare la mia soluzione perché ho sprecato già ore.

-Per recuperare le righe dal database, ho usato per dichiarare un metodo che restituisce ObservableBuffer.

La mia CLASSE JDBC

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

-E ho creato un oggetto TableView.

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

- E finalmente ho ottenuto la soluzione. Nel pulsante aggiorna, ho inserito questo codice;

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

Modello è il riferimento della mia classe di connessione jdbc

val model = new ScalaJdbcConnectSelect

Questo è il codice scalafx ma dà qualche idea a javafx

 0
Author: Muhammed Yalçın Kuru, 2017-02-21 15:45:47

Bene dopo aver cercato tutte le possibili soluzioni. Ho provato prima a cancellare i dati e poi aggiunto in tableview tableView.getItems().clear(); ancora questo non ha risolto il mio problema. Ho provato tutte le risposte date qui ma non ho funzionato per me e avevo ancora oggetti obsoleti nella mia tabella come mostrato nell'immagine qui sotto:

inserisci qui la descrizione dell'immagine

Per risolverlo ho creato un'etichetta FITTIZIA e ho usato setGraphic come segue:

inserisci qui la descrizione dell'immagine

 0
Author: Vishrant, 2018-04-26 21:28:59

我始終認為利用更改TableColumn的visable屬性的方法違反databinding的精神,若這是JavaFX的bug那也早就該接決了,不應該拖到Java8了還不解決。

Trtrace javafx的codice sorgente , , ,ugugugbug。enlistener。 。 。 。 也嘗試利用jface中的propertychangesupport方式宣告pojo。 。 。 。 最後將doppiaproprietà 改為 scrivibileobiettovalore,。 。

                                                           解決於台灣台北

Avevo consolidato use change Column La proprietà visibile non è conforme allo scopo di automazione del binding dei dati.

Dopo aver tracciato il codice sorgente di JavaFX TableView. Non ho mai scoperto alcun codice problema per Tableview binding problema. Dopo 4 settimane fa, ho cambiato il tipo di campo POJO da DoubleProperty a WritableObjectValue, il problema è stato risolto.

                                               resolve in Taiwan Taipei.

Codice di esempio:

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

    });
 -10
Author: 楊竣壹, 2015-05-31 08:35:21