2015-03-13 9 views
5

Non riesco a associare in fxml una raccolta a un modello personalizzato. Ecco il codice come lo farei in XAML:JavaFX8 elenca associazioni simili a xaml

<ListView ItemsSource="{Binding PersonCollection}"> 
    <StackPanel Orientation="Horizontal"> 
     <Label Content="{Binding FirstName}"></Label> 
     <ListView ItemsSource="{Binding MiddleNames}"> 
      <Label Content="{Binding}"></Label> 
     </ListView> 
     <Label Content="{Binding LastName}"></Label> 
    </StackPanel> 
</ListView> 

Qui il modello:

class Person 
{ 
    String FirstName, LastName; 
    String[] MiddleNames; 
} 

e la disposizione dovrebbe essere simile a questo:

John Ivy 
Robert Downey Junior 
Max more middlenames in fact even thousands are possible lastname 

È il legame di un possibile la raccolta di un modello personalizzato? Ho provato la cellfactory ma non riuscivo a farmi girare la testa, dato che tutti usavano solo stringhe.

+0

Che cos'è un modello personalizzato? – jewelsea

+0

Ho esteso la mia domanda per spiegare ulteriormente la configurazione. Ciò che essenzialmente fa è che per ogni elemento della collezione viene applicato il modello.Quindi per ogni elemento in PersonCollection genera un pannello orizzontale, etichetta firstname, etichetta lastname e un altro listview con un modello. – kadir

+0

Dove e come si specificano i dati di input (ad es. John Ivy, Robert Downey Junior ecc.)? È statico e non cambia mai o i dati del Dymanic che cambiano in fase di runtime? Sei sicuro di volere davvero un [ListView] (http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/list-view.htm#CEGGEDBF) qui (perché sarebbe strano) o è in realtà qualcosa di completamente diverso da un ListView JavaFX? (Non ho alcuna familiarità con xaml). – jewelsea

risposta

5

Io non sono sicuro al 100% questa è la risposta alla tua domanda, come io sono totalmente familiarità con XAML, ma si spera che è ...

Esempio Attuazione

L'esempio funziona impostando il model object (the Person) nello spazio dei nomi del caricatore FXML, che consente di utilizzare un'espressione di bind in FXML per legarsi alle proprietà dell'oggetto.

Nell'esempio, ci sono alcuni nomi inizialmente nel modello ed è possibile modificare l'elenco dei limiti nel modello usando i pulsanti aggiungi e rimuovi per aggiungere o rimuovere alcuni altri nomi in scatola nell'elenco.

sample image

Tutto il codice va in un pacchetto chiamato sample.names.

nome-display.fxml

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.control.Label?> 
<?import javafx.scene.control.ListView?> 
<?import javafx.scene.layout.HBox?> 

<?import javafx.geometry.Insets?> 

<?import javafx.scene.layout.VBox?> 
<?import javafx.scene.control.Button?> 
<VBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.names.NameDisplayController"> 
    <HBox prefHeight="150.0" prefWidth="220.0" spacing="5.0" > 
    <children> 
     <Label fx:id="firstNameLabel" text="${person.firstName}" /> 
     <ListView fx:id="middleNameList" prefWidth="100.0" items = "${person.middleNames}" /> 
     <Label fx:id="lastNameLabel" text="${person.lastName}" /> 
    </children> 
    <padding> 
     <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
    </padding> 
    </HBox> 
    <HBox alignment="CENTER" spacing="30.0"> 
    <children> 
     <Button mnemonicParsing="false" onAction="#addName" text="Add" /> 
     <Button mnemonicParsing="false" onAction="#removeName" text="Remove" /> 
    </children> 
    <padding> 
     <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
    </padding> 
    </HBox> 
</VBox> 

NameDisplayApp.java

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Scene; 
import javafx.scene.layout.Pane; 
import javafx.stage.Stage; 

import java.io.IOException; 

public class NameDisplayApp extends Application { 

    @Override 
    public void start(Stage stage) throws IOException { 
     Person person = new Person(
       "Bruce", 
       new String[] { "Simon", "Larry" }, 
       "Banner" 
     ); 

     FXMLLoader loader = new FXMLLoader(
       getClass().getResource(
         "name-display.fxml" 
       ) 
     ); 
     loader.getNamespace().put(
       "person", 
       person 
     ); 
     Pane pane = loader.load(); 

     NameDisplayController controller = loader.getController(); 
     controller.setPerson(person); 

     stage.setScene(new Scene(pane)); 
     stage.show(); 
    } 

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

NameDisplayController.java

import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.event.ActionEvent; 

public class NameDisplayController { 
    private Person person; 

    private ObservableList<String> sampleNames = FXCollections.observableArrayList(
      "George", "Henry", "Wallace" 
    ); 

    public void setPerson(Person person) { 
     this.person = person; 
    } 

    public void addName(ActionEvent actionEvent) { 
     if (!sampleNames.isEmpty()) { 
      person.getMiddleNames().add(
       sampleNames.remove(0) 
      ); 
     } 
    } 

    public void removeName(ActionEvent actionEvent) { 
     if (!person.getMiddleNames().isEmpty()) { 
      sampleNames.add(
        person.getMiddleNames().remove(0) 
      ); 
     } 
    } 
} 

Person.java

import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 

public class Person { 
    public StringProperty firstName; 
    public StringProperty lastName; 

    private ObservableList<String> middleNames; 

    public Person(String firstName, String[] middleNames, String lastName) { 
     this.firstName = new SimpleStringProperty(firstName); 
     this.middleNames = FXCollections.observableArrayList(middleNames); 
     this.lastName = new SimpleStringProperty(lastName); 
    } 

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

    public StringProperty firstNameProperty() { 
     return firstName; 
    } 

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

    public ObservableList<String> getMiddleNames() { 
     return middleNames; 
    } 

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

    public StringProperty lastNameProperty() { 
     return lastName; 
    } 

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

implementazioni alternative

Ci possono essere altri modi (forse più privilegiate) di fare questo - per esempio associando associazioni di elementi nel codice piuttosto che FXML (che è quello che faccio di solito) o iniettando il modello usando un sistema di iniezione dipendente. Si veda afterburner.fx per un esempio dell'approccio di iniezione - anche se non so se il postbruciatore colloca anche gli oggetti del modello nello spazio dei nomi FXML o semplicemente gli inietta nel controller (se non fa l'iniezione nello spazio dei nomi FXML che potrebbe essere una figata Inoltre potresti richiederlo).

+0

Questo è simile al progresso che ho ottenuto, tuttavia non ero in grado di creare modelli diversi da Stringhe. Cosa succede se voglio un elenco di pulsanti o riquadri? È possibile? Sono persino contento della risposta n. – kadir

+1

@kadir Quindi devi specificare una cellaFactory. – Puce

Problemi correlati