2012-11-14 22 views
8

Così sto cercando di imparare a utilizzare JavaFX Tableview e mi stumpled in questo tutorial:SimpleStringProperty e SimpleIntegerProperty TableView JavaFX

Oracle tableview tutorial

in questo tutorial mostrano che, al fine di riempire voi tableView si deve riempilo di stringhe, ma non solo qualsiasi stringa devi formattare String in un SimpleStringProperty

ho provato senza il formato e il risultato è stato che nessuna delle informazioni mostrerebbe!

Inoltre ho trovato che se si desidera aggiungere un Integer alla tabella che avrebbe dovuto dichiararlo come SimpleIntegerProperty

Ora io sono abbastanza nuovo per JavaFX, ma questo significa che quando creo un oggetto che ho formattare tutti i miei numeri interi e stringhe per poter riempire il mio TableView? sembra piuttosto stupido ma forse c'è uno scopo più alto? o c'è un modo per evitarlo?

+0

È un tutorial scritto male. Sopprimono troppi punti importanti, ad esempio Generics. –

risposta

23

Non è necessario utilizzare Proprietà negli oggetti dati della tabella per la visualizzazione, anche se l'utilizzo di Proprietà in determinate circostanze è auspicabile.

Il codice seguente mostrerà una tabella di persone basate su una classe Persona che ha solo campi String.

import javafx.application.Application; 
import javafx.collections.*; 
import javafx.geometry.Insets; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.VBox; 
import javafx.scene.text.Font; 
import javafx.stage.Stage; 

public class ReadOnlyTableView extends Application { 
    private TableView<Person> table = new TableView<Person>(); 
    private final ObservableList<Person> data = 
    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 static void main(String[] args) { launch(args); } 

    @Override public void start(Stage stage) { 
    stage.setTitle("Table View Sample"); 
    stage.setWidth(450); 
    stage.setHeight(500); 

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

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

    TableColumn lastNameCol = new TableColumn("Last Name"); 
    lastNameCol.setMinWidth(100); 
    lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 

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

    table.setItems(data); 
    table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 

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

    stage.setScene(new Scene(new Group(vbox))); 
    stage.show(); 
    } 

    public static class Person { 
    private String firstName; 
    private String lastName; 
    private String email; 

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

    public String getFirstName() { return firstName; } 
    public void setFirstName(String fName) { firstName = fName; } 
    public String getLastName() { return lastName; } 
    public void setLastName(String lName) { lastName = lName; } 
    public String getEmail() { return email; } 
    public void setEmail(String inMail) { email = inMail; } 
    } 
} 

Spiegazione

Lo scopo di utilizzare Proprietà e ObservableLists è che questi sono elementi ascoltabile. Quando vengono utilizzate le proprietà, se il valore di un attributo di proprietà nella modamodello cambia, la vista dell'elemento in TableView viene automaticamente aggiornata per corrispondere al valore datamodel aggiornato. Ad esempio, se il valore della proprietà di posta elettronica di una persona è impostato su un nuovo valore, quell'aggiornamento si rifletterà nel TableView perché esso ascolta la modifica della proprietà. Se invece fosse stata utilizzata una semplice stringa per rappresentare l'e-mail, il TableView non si aggiornerebbe in quanto ignorerebbe le modifiche del valore dell'email.

La documentazione PropertyValueFactory descrive questo processo in dettaglio:

Un esempio di come utilizzare questa classe è:

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

In questo esempio, la stringa "Nome" è usato come riferimento ad un assunto metodo firstNameProperty() nel tipo di classe Person (che è il tipo di classe dell'elenco degli elementi di TableView). Inoltre, questo metodo deve restituire un'istanza di proprietà. Se viene trovato un metodo che soddisfa questi requisiti , TableCell viene popolato con questo valore osservabile . Inoltre, TableView aggiungerà automaticamente un osservatore al valore restituito, in modo tale che eventuali modifiche attivate saranno osservate da TableView, determinando l'aggiornamento immediato della cella.

Se nessun metodo corrispondente a questo modello esiste, v'è caduta attraverso supporto per tentare di chiamare get() o è() (che è , getFirstName() o isFirstName() nell'esempio precedente).Se esiste un metodo che corrisponde a questo modello, il valore restituito da questo metodo è avvolto in un ReadOnlyObjectWrapper e restituito a TableCell. Tuttavia, in questa situazione, ciò significa che TableCell non sarà in grado di osservare il valore ObservableValue per le modifiche (come nel caso del primo approccio sopra riportato ).

Aggiornamento

Ecco un esempio che contrasta con il primo esempio che dimostra come una TableView può osservare e automaticamente aggiorna in base alle modifiche ad esso è ObservableList di articoli e modifiche per il valore di un elemento di proprietà sulla base attributo.

import javafx.application.Application; 
import javafx.beans.property.*; 
import javafx.collections.*; 
import javafx.event.*; 
import javafx.geometry.Insets; 
import javafx.scene.*; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.VBox; 
import javafx.scene.text.Font; 
import javafx.stage.Stage; 

public class PropertyBasedTableView extends Application { 
    private TableView<Person> table = new TableView<Person>(); 
    private final ObservableList<Person> data = FXCollections.observableArrayList(); 
    private void initData() { 
    data.setAll(
     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 static void main(String[] args) { launch(args); } 

    @Override public void start(Stage stage) { 
    initData(); 

    stage.setTitle("Table View Sample"); 
    stage.setWidth(450); 
    stage.setHeight(500); 

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

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

    TableColumn lastNameCol = new TableColumn("Last Name"); 
    lastNameCol.setMinWidth(100); 
    lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 

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

    table.setItems(data); 
    table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 
    table.setPrefHeight(300); 

    final Button setEmailButton = new Button("Set first email in table to [email protected]"); 
    setEmailButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override public void handle(ActionEvent event) { 
     if (data.size() > 0) { 
      data.get(0).setEmail("[email protected]"); 
     } 
     } 
    }); 

    final Button removeRowButton = new Button("Remove first row from the table"); 
    removeRowButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override public void handle(ActionEvent event) { 
     if (data.size() > 0) { 
      data.remove(0); 
     } 
     } 
    }); 

    final Button resetButton = new Button("Reset table data"); 
    resetButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override public void handle(ActionEvent event) { 
     initData(); 
     } 
    }); 

    final VBox vbox = new VBox(10); 
    vbox.setPadding(new Insets(10, 0, 0, 10)); 
    vbox.getChildren().addAll(label, table, setEmailButton, removeRowButton, resetButton); 

    stage.setScene(new Scene(new Group(vbox))); 
    stage.show(); 
    } 

    public static class Person { 
    private final StringProperty firstName; 
    private final StringProperty lastName; 
    private final StringProperty 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 StringProperty firstNameProperty() { return firstName; } 
    public String getLastName() { return lastName.get(); } 
    public void setLastName(String lName) { lastName.set(lName); } 
    public StringProperty lastNameProperty() { return lastName; } 
    public String getEmail() { return email.get(); } 
    public void setEmail(String inMail) { email.set(inMail); } 
    public StringProperty emailProperty() { return email; } // if this method is commented out then the tableview will not refresh when the email is set. 
    } 
} 
+0

Prima di tutto ti ringrazio tanto per la tua risposta se potessi averti dato più di 1 pollice in su :) In secondo luogo, quindi, come si dice che convertendo le stringhe in una proprietà SimpleString la tabella verrà aggiornata automaticamente? E scegliendo di non dover aggiornare il tavolo manuelly? –

+0

Aggiunta una citazione da PropertyValueFactory alla risposta per rispondere alla domanda aggiuntiva di Marc. – jewelsea

+0

la tabella si aggiornerà automaticamente quando viene modificata una delle proprietà e, in caso affermativo, come si fa? cambiate l'elenco o impostate il valore usando object.setName() (ad esempio) –

Problemi correlati