2017-03-05 5 views
1

ok, encore une fois. Voici un nouveau projet avec le code correspondant. Comme vous pouvez le voir dans le champ de texte, même si initData doit avoir initialisé la variable testVar, cela ne se produit pas et dans initialize() la variable est null. J'ai besoin d'obtenir la variable là-bas, donc je peux obtenir des données d'une connexion réseau dans une table. Voici le code:ObjectOutputStream non disponible dans PlayerList.java - impossible d'obtenir les données pour la table

FXMLController.java:

package de.freakyonline.testproject; 

import java.net.URL; 
import java.util.ResourceBundle; 
import javafx.event.ActionEvent; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.Label; 
import javafx.scene.control.TextArea; 

public class FXMLController implements Initializable { 
    String testVar; 

    @FXML 
    private ResourceBundle resources; 

    @FXML 
    private URL location; 

    @FXML 
    private TextArea testTextArea; 

    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
    // Here it's null  
     testTextArea.appendText("TestVar: " + testVar); 

    } 

    void initData(Remote remoteObj) { 
     this.testVar = remoteObj.getVar(); 
    }  
} 

MainApp.java:

package de.freakyonline.testproject; 

import javafx.application.Application; 
import static javafx.application.Application.launch; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 


public class MainApp extends Application { 
    Thread remote; 
    Remote remoteObj; 

    String testVar = new String("success"); 

    @Override 
    public void start(Stage stage) throws Exception { 

     FXMLLoader root = new FXMLLoader(
      getClass().getResource("/fxml/Scene.fxml") 
     ); 

     try { 
      remoteObj = new Remote(testVar); 
      remote = new Thread(remoteObj); 
     } catch (Exception ex) { ex.printStackTrace(); } 
     remote.start(); 

     Scene scene = new Scene((Parent) root.load()); 
     FXMLController controller = root.<FXMLController>getController(); 
     controller.initData(remoteObj); 

     scene.getStylesheets().add("/styles/Styles.css"); 

     stage.setTitle("TestProjects ..."); 
     stage.setScene(scene); 
     stage.show(); 


    } 

    /** 
    * The main() method is ignored in correctly deployed JavaFX application. 
    * main() serves only as fallback in case the application can not be 
    * launched through deployment artifacts, e.g., in IDEs with limited FX 
    * support. NetBeans ignores main(). 
    * 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     launch(args); 
    } 

} 

Scene.fxml:

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

<?import javafx.scene.control.TextArea?> 
<?import javafx.scene.layout.BorderPane?> 

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.freakyonline.testproject.FXMLController"> 
    <center> 
     <TextArea fx:id="testTextArea" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" /> 
    </center> 
</BorderPane> 

Remote.java:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package de.freakyonline.testproject; 

import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.Socket; 

/** 
* 
* @author uwe 
*/ 
public class Remote implements Runnable { 
    private String testVar; 

    public Remote (String testVar) { 
     this.testVar = testVar; 
    } 

    public String getVar() { 
     return testVar; 
    } 

    public void run() { 
    } 
} 
+0

S'il vous plaît réduire le code à la partie pertinente, que personne ne veut lire les pages de code –

+0

fait :) merci. –

+0

Essaie de revenir en arrière à partir de quel point il est nul –

Répondre

0

La méthode initialize() d'un contrôleur est appelée par le FXMLLoader lorsque le FXML est chargé, c'est-à-dire qu'il est appelé pendant l'appel de load(). Dans votre exemple de code, vous appelez initData()après vous appelez load(), donc clairement testVar ne peut pas avoir été initialisé lorsque la méthode initialize() est exécutée. Étant donné que le contrôleur dans l'exemple de code est créé par le FXMLLoader, vous ne pouvez pas appeler initData(...) avant que initialize() ne soit appelée.

(A part. En utilisant des techniques de débogage simples, comme l'utilisation d'un débogueur pas à travers, ou même l'impression juste un message lorsque chaque méthode est invoquée, il serait très clair que la question est ici)

le moyen le plus correctif est juste pour déplacer le code qui dépend de testVar la méthode initData() (ou une autre méthode qui est appelée aprèstestVar est initialisées):

public class FXMLController implements Initializable { 
    String testVar; 

    @FXML 
    private ResourceBundle resources; 

    @FXML 
    private URL location; 

    @FXML 
    private TextArea testTextArea; 

    @Override 
    public void initialize(URL url, ResourceBundle rb) { 

    } 

    void initData(Remote remoteObj) { 
     this.testVar = remoteObj.getVar(); 
     testTextArea.appendText("TestVar: " + testVar); 
    }  
} 

le léger inconvénient est que l'initialisation du contr oller est réparti sur plusieurs méthodes, exécutées à différents moments du cycle de vie du contrôleur. Les autres options incluent la configuration du contrôleur en code, au lieu de spécifier la classe du contrôleur dans le fichier FXML ou en utilisant une fabrique de contrôleurs. L'inconvénient de définir le contrôleur dans le code est que si vous utilisez un outil (tel que Scene Builder) pour concevoir le FXML, il ne sera pas conscient de la classe de contrôleur utilisée. L'utilisation d'une fabrique de contrôleurs est plus complexe, mais évite ce problème.