2017-09-27 6 views
0

J'ai pris un coup à ce sujet hier mais la documentation de TableView m'a un peu confus. Après avoir travaillé dessus pendant quelques heures, j'ai abandonné. Je me demandais si des experts javafx peuvent m'aider avec ça. Je souhaite mettre à jour un TableView dans un thread d'arrière-plan régulièrement lorsque des éléments de ma base de données changent. Plutôt que d'afficher toute mon application, j'ai essayé de la décomposer en un exemple simple. Remplacer toutes les occurrences de ListView avec TableView et ....JavaFx: J'ai besoin de quelque chose de similaire à cela mais pour un TableView au lieu d'un ListView

Alors quoi?

import java.util.List; 
import java.util.stream.Collectors; 
import java.util.stream.IntStream; 
import java.util.stream.Stream; 

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.event.Event; 
import javafx.event.EventType; 
import javafx.scene.Scene; 
import javafx.scene.control.ListView; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 
/** 
* An example of triggering a JavaFX ListView when an item is modified. 
* 
* Displays a list of strings. It iterates through the strings adding 
* exclamation marks with 2 second pauses in between. Each modification is 
* accompanied by firing an event to indicate to the ListView that the value 
* has been modified. 
* 
* @author Mark Fashing 
*/ 
public class ListViewTest extends Application { 

    /** 
    * Informs the ListView that one of its items has been modified. 
    * 
    * @param listView The ListView to trigger. 
    * @param newValue The new value of the list item that changed. 
    * @param i The index of the list item that changed. 
    */  
    public static <T> void triggerUpdate(ListView<T> listView, T newValue, int i) { 
     EventType<? extends ListView.EditEvent<T>> type = ListView.editCommitEvent(); 
     Event event = new ListView.EditEvent<>(listView, type, newValue, i); 
     listView.fireEvent(event); 
    } 

    @Override 
    public void start(Stage primaryStage) { 
     // Create a list of mutable data. StringBuffer works nicely. 
     final List<StringBuffer> listData = Stream.of("Fee", "Fi", "Fo", "Fum") 
       .map(StringBuffer::new) 
       .collect(Collectors.toList()); 
     final ListView<StringBuffer> listView = new ListView<>(); 
     listView.getItems().addAll(listData); 
     final StackPane root = new StackPane(); 
     root.getChildren().add(listView); 
     primaryStage.setScene(new Scene(root)); 
     primaryStage.show(); 
     // Modify an item in the list every 2 seconds. 
     new Thread(() -> { 
      IntStream.range(0, listData.size()).forEach(i -> { 
       try { 
        Thread.sleep(2000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.println(listData.get(i)); 
       Platform.runLater(() -> { 
        // Where the magic happens. 
        listData.get(i).append("!"); 
        triggerUpdate(listView, listData.get(i), i); 
       });    
      }); 
     }).start(); 
    } 

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

} 

Voici ma première tentative:

Créer une classe personne ....

package org.pauquette.example; 

import javafx.beans.property.SimpleStringProperty; 

public class Person { 
     private final SimpleStringProperty email; 
     private final SimpleStringProperty firstName; 
     private final SimpleStringProperty lastName; 

     Person(String fName, String lName, String email) { 
      this.firstName = new SimpleStringProperty(fName); 
      this.lastName = new SimpleStringProperty(lName); 
      this.email = new SimpleStringProperty(email); 
     } 

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

     public String getFirstName() { 
      return firstName.get(); 
     } 

     public String getLastName() { 
      return lastName.get(); 
     } 

     public void setEmail(String fName) { 
      email.set(fName); 
     } 

     public void setFirstName(String fName) { 
      firstName.set(fName); 
     } 

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

Créer une classe modèle extrêmement simple ...

package org.pauquette.example; 

import javafx.collections.*; 

public class PeopleModel { 

    private ObservableList<Person> people=FXCollections.observableArrayList(
       new Person("Jacob", "Smith", "[email protected]"), 
       new Person("Isabella", "Johnson", "[email protected]"), 
       new Person("Ethan", "Williams", "[email protected]"), 
       new Person("Emma", "Jones", "[email protected]"), 
       new Person("Michael", "Brown", "[email protected]") 
      ); 

    public ObservableList<Person> getPeople() { 
      return people; 
    } 

} 

Maintenant, créez un TableView de juste firstName et construire les colonnes puis mettre à jour le firstName toutes les 2 secondes .......

package org.pauquette.example; 

import java.util.stream.IntStream; 

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 
/** 
* An example of triggering a JavaFX TableView when an item is modified. 
* 
* Displays a list of strings. It iterates through the strings adding 
* exclamation marks with 2 second pauses in between. Each modification is 
* accompanied by firing an event to indicate to the TableView that the value 
* has been modified. 
* 
* @author Mark Fashing-Modified for TableView by Bryan Pauquette 
*/ 
public class TableViewTest extends Application { 

    /* 
    public static <T> void triggerUpdate(TableView<T> listView, T newValue, int i) { 
     EventType<? extends TableView.EditEvent<T>> type = TableView.editCommitEvent(); 
     Event event = new TableView.EditEvent<>(listView, type, newValue, i); 
     listView.fireEvent(event); 
    }*/ 

    @Override 
    public void start(Stage primaryStage) { 
     final TableView<Person> listView = new TableView<Person>(); 
     final PeopleModel model=new PeopleModel(); 
     final ObservableList<Person> listData=model.getPeople(); 
     listView.getItems().addAll(listData); 
     final StackPane root = new StackPane(); 
     buildColumns(listView,listData); 
     root.getChildren().add(listView); 

     primaryStage.setScene(new Scene(root)); 
     primaryStage.show(); 
     // Modify an item in the list every 2 seconds. 
     new Thread(() -> { 
      IntStream.range(0, listData.size()).forEach(i -> { 
       try { 
        Thread.sleep(2000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.println(listData.get(i)); 
       Platform.runLater(() -> { 
        // Where the magic happens. 
        Person p=listData.get(i); 
        p.setFirstName(new StringBuilder(p.getFirstName()).append("!").toString()); 
        //triggerUpdate(listView, listData.get(i), i); 
       });    
      }); 
     }).start(); 
    } 


    private void buildColumns(TableView<Person> listView,ObservableList<Person> listData) { 
     TableColumn<Person, String> dataCol = new TableColumn<Person, String>("First Name"); 
     dataCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));  
     listView.getColumns().add(dataCol); 
     listView.setItems(listData); 
    } 

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

} 

La méthode que je me bats avec est triggerUpdate .....

Je veux la colonne prenom pour obtenir mis à jour dans la vue avec un point d'exclamation en annexe toutes les 2 secondes, tout comme dans la simple liste originale vue.

Répondre

0

Voici le code de travail .....

package org.pauquette.example; 

import java.util.Observable; 

import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.value.ObservableValue; 

public class Person extends Observable { 
     private final SimpleStringProperty email; 
     private final SimpleStringProperty firstName; 
     private final SimpleStringProperty lastName; 

     Person(String fName, String lName, String email) { 
      this.firstName = new SimpleStringProperty(fName); 
      this.lastName = new SimpleStringProperty(lName); 
      this.email = new SimpleStringProperty(email); 
     } 

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

     public String getFirstName() { 
      return firstName.get(); 
     } 

     public String getLastName() { 
      return lastName.get(); 
     } 

     public void setEmail(String emailIn) { 
      email.setValue(emailIn); 
      setChanged(); 
      notifyObservers(email); 
     } 

     public void setFirstName(String fNameIn) { 
      firstName.setValue(fNameIn); 
      setChanged(); 
      notifyObservers(firstName); 

     } 

     public void setLastName(String lNameIn) { 
      lastName.setValue(lNameIn); 
      setChanged(); 
      notifyObservers(); 
     } 

    public ObservableValue<String> firstNameProperty() { 
     return firstName; 
    } 
} 

Et ......

package org.pauquette.example; 
import java.util.stream.IntStream; 

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.beans.value.ObservableValue; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableColumn.CellDataFeatures; 
import javafx.scene.control.TableView; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 
import javafx.util.Callback; 
/** 
* An example of triggering a JavaFX TableView when an item is modified. 
* 
* Displays a list of strings. It iterates through the strings adding 
* exclamation marks with 2 second pauses in between. Each modification is 
* accompanied by firing an event to indicate to the TableView that the value 
* has been modified. 
* 
* @author Mark Fashing-Modified for TableView by Bryan Pauquette 
*/ 
public class TableViewTest extends Application { 

    /* 
    public static <T> void triggerUpdate(TableView<T> listView, T newValue, int i) { 
     EventType<? extends TableView.EditEvent<T>> type = TableView.editCommitEvent(); 
     Event event = new TableView.EditEvent<>(listView, type, newValue, i); 
     listView.fireEvent(event); 
    }*/ 

    @Override 
    public void start(Stage primaryStage) { 
     final TableView<Person> listView = new TableView<Person>(); 
     final PeopleModel model=new PeopleModel(); 
     final ObservableList<Person> listData=model.getPeople(); 

     /* int row=0; 
     for (Person p : listData) { 
      p.addObserver(new PersonObserver(listView,row)); 
      row++; 
     }*/ 
     listView.getItems().addAll(listData); 


     final StackPane root = new StackPane(); 
     buildColumns(listView,listData); 
     root.getChildren().add(listView); 

     primaryStage.setScene(new Scene(root)); 
     primaryStage.show(); 
     // Modify an item in the list every 2 seconds. 
     new Thread(() -> { 
      IntStream.range(0, listData.size()).forEach(i -> { 
       try { 
        Thread.sleep(2000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.println(listData.get(i)); 
       Platform.runLater(() -> { 
        // Where the magic happens. 
        Person p=listData.get(i); 
        p.setFirstName(new StringBuilder(p.getFirstName()).append("!").toString()); 
        //triggerUpdate(listView, listData.get(i), i); 
       });    
      }); 
     }).start(); 
    } 




    private void buildColumns(TableView<Person> listView,ObservableList<Person> listData) { 
     TableColumn<Person, String> dataCol = new TableColumn<Person, String>("First Name"); 
     //dataCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 
     dataCol.setCellValueFactory(new Callback<CellDataFeatures<Person, String>, ObservableValue<String>>() { 
     public ObservableValue<String> call(CellDataFeatures<Person, String> p) { 
       // p.getValue() returns the Person instance for a particular TableView row 
       return p.getValue().firstNameProperty(); 
      } 
     }); 


     listView.getColumns().add(dataCol); 
     listView.setItems(listData); 
    } 

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

} 
+0

En fait, vous ne même pas besoin d'étendre Observable dans votre classe POJO. Fonctionne encore. quand j'ai enlevé ça. –