2012-08-28 19 views
25

Buona sera a tutti,FXML multipla con i controller, la quota oggetto

ho trovato un sacco di posti già su questo argomento, ma ancora non riesce a passare un oggetto da Controller1 a controller2. C'è da qualche parte un tutorial completo o qualche progetto di esempio che fa questo?

ho ottenuto fino a questo punto fino a quando mi sono bloccato:

Paese classe

public class Country { 
private SimpleStringProperty country = new SimpleStringProperty(""); 

//Constructor 
public Country() { 
} 

//GETTERS 
public String getCountry() { 
    return country.get(); 
} 

//SETTERS 
public void setCountry(String value) { 
    country.set(value); 
} 

@Override 
public String toString() { 
    return getCountry(); 
} 
} 

All'avvio del programma, il FXML principale viene caricato (Sample.fxml). Questo contiene un riquadro dei bordi con una barra dei menu nel pannello superiore e un riquadro dei contenuti al centro. All'inizializzazione creo un nuovo oggetto Paese e lo memorizzo in una variabile globale. Ho un metodo che carica un altro FXML nel riquadro del contenuto, quando una voce di menu si fa clic:

SampleController.java

public class SampleController implements Initializable { 

@FXML 
private Pane pContent; 

private Country c; 

@FXML 
private void handleButtonAction(ActionEvent event) throws IOException { 
    System.out.println(c); //this prints Belgium, which is correct 

    URL url = getClass().getResource("Sub1.fxml"); 

    FXMLLoader fxmlloader = new FXMLLoader(); 
    fxmlloader.setLocation(url); 
    fxmlloader.setBuilderFactory(new JavaFXBuilderFactory()); 

    pContent.getChildren().clear(); 
    pContent.getChildren().add((Node) fxmlloader.load(url.openStream())); 
} 

@Override 
public void initialize(URL url, ResourceBundle rb) { 
    c = new Country(); 
    c.setCountry("Belgium"); 
} 

public Country getCountryFromSampleController(){ 
    return c; 
} 
} 

Ora desidero cogliere l'oggetto Paese in cui il Sub1.fxml ottiene caricato , il che significa che ho bisogno di recuperare l'oggetto paese initialize():

Sub1Controller.java

public class Sub1Controller implements Initializable { 

/** 
* Initializes the controller class. 
*/ 
@Override 
public void initialize(URL url, ResourceBundle rb) { 
    SampleController sp = new SampleController(); //I don't know how to fetch the original SampleController object 
    System.out.println(sp.getCountryFromSampleController()); 
    //this prints null, which is ofcourse logical because I make a new SampleController object.   
}  
} 

La domanda che ho, come posso ottenere l'oggetto SampleController 'originale' così posso usare il metodo getCountryFromRoot() per recuperare l'oggetto Paese con valore Belgio? Ho cercato su questo argomento per ore e ore e ho letto ogni post su StackOverflow a riguardo, ma sembra che non trovo il link mancante ... qualsiasi aiuto (preferibilmente con questo codice) è apprezzato!

Ci scusiamo per il lungo post, ho cercato di essere il più completo possibile il resto Non capirò mai ...

risposta

41

FXML è una semplice forma di MVC pattern. Il file FXML è una vista, il controller è ovvio, cosa manca? Il modello: un luogo in cui vengono archiviati tutti i dati relativi alla vista corrente e, quindi, che è possibile utilizzare per condividere i dati Paese tra i controller.


1. Uno dei possibili approccio di introdurre il modello è "contesto". Consideriamo un caso, allora avete un solo modello per l'intero progetto in modo da poter avere un contesto globale in una forma di Singleton

public class Context { 
    private final static Context instance = new Context(); 

    public static Context getInstance() { 
     return instance; 
    } 

    private Country country = new Country(); 

    public Country currentCountry() { 
     return country; 
    } 
} 

tuo SampleController avrà prossimi cambiamenti:

@Override 
public void initialize(URL url, ResourceBundle rb) { 
    Context.getInstance().currentCountry().setCountry("Belgium"); 
} 

E SubController1 possono accedere allo stesso modo:

@Override 
public void initialize(URL url, ResourceBundle rb) { 
    System.out.println(Context.getInstance().currentCountry().getCountry()); 
} 

2. Un altro modo è passare il contesto a SubController1 quindi caricare il suo xml. Funzionerà meglio se non si desidera avere un modello globale dell'applicazione.Quindi creare simile classe Context ma senza campi di esemplare, e:

public class Sub1Controller implements Initializable { 
    private Context context; 
    public void setContext(Context context) { 
     this.context = context; 
     // initialize country dependent data here rather then in initialize() 
    } 
} 

contesto Impostazione in SampleController:

Context currentContext = new Context(); 

@Override 
public void initialize(URL url, ResourceBundle rb) { 
    currentContext.currentCountry().setCountry("Belgium"); 
} 

@FXML 
private void handleButtonAction(ActionEvent event) throws IOException { 
    URL url = getClass().getResource("Sub1.fxml"); 

    FXMLLoader fxmlloader = new FXMLLoader(); 
    fxmlloader.setLocation(url); 
    fxmlloader.setBuilderFactory(new JavaFXBuilderFactory()); 

    pContent.getChildren().clear(); 
    pContent.getChildren().add((Node) fxmlloader.load(url.openStream())); 
      // here we go 
    ((Sub1Controller)fxmlloader.getController()).setContext(currentContext); 
} 
+0

Grazie mille volte Sergey, finalmente tutto ha un senso. Questa è la prima volta che devo creare una grande applicazione, ma sto ancora lottando su come "costruirla". Ho anche un'altra domanda di sicurezza che vorrei chiedere, ma non sono sicuro se questo è il sito giusto per chiederlo (non è relativo al codice) – Perneel

+0

Ehi, Sergey, mi dispiace di portare su questo vecchio argomento. Funziona ancora come un incantesimo ma quello che mi chiedo ... C'è un modo per massimizzare la larghezza e l'altezza dall'oggetto Node '(Nodo) fxmlloader.load (url.openStream())' quindi è legato al larghezza e altezza del riquadro (pContent)? – Perneel

+0

dovrebbe funzionare automaticamente, in caso contrario, fornire meglio il codice in una domanda separata –

Problemi correlati