2017-04-13 217 views
0

对不起。我不会说英文很好,所以请理解我JavaFX空指针异常在label.setText()

我正在为java制作smartmirror,但是我遇到了setText()函数的问题。

在调用天气api并将位置名称保存到变量后,我启动label.setText(),但它有空指针异常。

我听说过platform.run later()方法和任务,但它们不起作用。

请帮我TT 有我的源

package SmartMirror.main; 

import java.io.IOException; 
public class SpeechClass { 
WeatherController weather = new WeatherController(); 


// Logger 
private Logger logger = Logger.getLogger(getClass().getName()); 

// Variables 
public String result; 

// Threads 
Thread speechThread; 
Thread resourcesThread; 
Thread openThread; 

// LiveRecognizer 
private LiveSpeechRecognizer recognizer; 

protected String location; 

public void Speech(){ 
    // Loading Message 
    logger.log(Level.INFO, "Loading..\n"); 

    // Configuration 
    Configuration configuration = new Configuration(); 

    // Load model from the jar 
    configuration.setAcousticModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us"); 
    configuration.setDictionaryPath("resource:/edu/cmu/sphinx/models/en-us/cmudict-en-us.dict"); 

    // if you want to use LanguageModelPath disable the 3 lines after which 
    // are setting a custom grammar-> 

    // configuration.setLanguageModelPath("resource:/edu/cmu/sphinx/models/en-us/en-us.lm.bin") 

    // Grammar 
    configuration.setGrammarPath("resource:/grammars"); 
    configuration.setGrammarName("grammar"); 
    configuration.setUseGrammar(true); 

    try { 
     recognizer = new LiveSpeechRecognizer(configuration); 
    } catch (IOException ex) { 
     logger.log(Level.SEVERE, null, ex); 
    } 

    // Start recognition process pruning previously cached data. 
    recognizer.startRecognition(true); 

    // Start the Thread 
    startSpeechThread(); 
    startResourcesThread(); 

} 


/** 
* Starting the main Thread of speech recognition 
*/ 
protected void startSpeechThread() { 

    // alive? 
    if (speechThread != null && speechThread.isAlive()) 
     return; 

    // initialise 
    speechThread = new Thread(() -> { 
     logger.log(Level.INFO, "You can start to speak...\n"); 
     try { 
      while (true) { 
       /* 
       * This method will return when the end of speech is 
       * reached. Note that the end pointer will determine the end 
       * of speech. 
       */ 
       SpeechResult speechResult = recognizer.getResult(); 
       if (speechResult != null) { 

        result = speechResult.getHypothesis(); 

        System.out.println("You said: [" + result + "]\n"); 

        if(result.equals("one")){ 
         System.out.println("startOpenThread"); 
         startWeatherThread(); 
         openThread.sleep(3000); 

         Platform.runLater(new Runnable(){ 
          @Override 
          public void run(){ 
           weather.setLabel(); 
           openweather(); 
          } 
         }); 

        } 
        // logger.log(Level.INFO, "You said: " + result + "\n") 

       } else 
        logger.log(Level.INFO, "I can't understand what you said.\n"); 

      } 
     } catch (Exception ex) { 
      logger.log(Level.WARNING, null, ex); 
     } 

     logger.log(Level.INFO, "SpeechThread has exited..."); 
    }); 


    // Start 
    speechThread.start(); 

} 



/** 
* Starting a Thread that checks if the resources needed to the 
* SpeechRecognition library are available 
*/ 
protected void startResourcesThread() { 

    // alive? 
    if (resourcesThread != null && resourcesThread.isAlive()) 
     return; 

    resourcesThread = new Thread(() -> { 
     try { 

      // Detect if the microphone is available 
      while (true) { 
       if (AudioSystem.isLineSupported(Port.Info.MICROPHONE)) { 
        // logger.log(Level.INFO, "Microphone is available.\n") 
       } else { 
        // logger.log(Level.INFO, "Microphone is not 
        // available.\n") 

       } 

       // Sleep some period 
       Thread.sleep(350); 
      } 

     } catch (InterruptedException ex) { 
      logger.log(Level.WARNING, null, ex); 
      resourcesThread.interrupt(); 
     } 
    }); 

    // Start 
    resourcesThread.start(); 
} 

protected void startWeatherThread() { 
    try{ 
     openThread = new Thread(() -> { 
      weather.Weather(); // 날씨를 변수에 저장 

     }); 

    } catch (Exception e){ 

    } 
    // Start 
    openThread.start(); 
} 

public void openweather(){ 
    Stage dialog = new Stage(StageStyle.TRANSPARENT); 
    dialog.initModality(Modality.WINDOW_MODAL); 
    dialog.initOwner(null); 

    Parent parent = null; 
    try { 
     parent = FXMLLoader.load(WeatherController.class.getResource("weather_scene.fxml")); 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    Scene scene = new Scene(parent); 
    dialog.setScene(scene); 
    dialog.setResizable(false); 
    dialog.show(); 
} 


} 


package SmartMirror.Weather; 

import java.io.BufferedReader; 


public class WeatherController { 

@FXML private Label labelLocation; 

public String locationResult="", weatherResult="", tempResult=""; 


    //날씨 API 
    public void Weather() { 
     try{ 

      //OpenAPI call하는 URL 
      String urlstr = "http://api.openweathermap.org/data/2.5/weather?" 
         +"q=Chuncheon" 
         +"&appid=f1bccf50c733316db790a00a2d5165c6&units=metric"; 
      URL url = new URL(urlstr); 
      BufferedReader bf; 
      String line; 
      String result=""; 

      //날씨 정보를 받아온다. 
      bf = new BufferedReader(new InputStreamReader(url.openStream())); 

      //버퍼에 있는 정보를 문자열로 변환. 
      while((line=bf.readLine())!=null){ 
       result=result.concat(line); 
       //System.out.println(line); 
      } 

      //문자열을 JSON으로 파싱 
      JSONParser jsonParser = new JSONParser(); 
      JSONObject jsonObj = (JSONObject) jsonParser.parse(result); 

      //날씨 출력 
      JSONArray weatherArray = (JSONArray) jsonObj.get("weather"); 
      JSONObject weather = (JSONObject) weatherArray.get(0); 

      //온도출력 
      JSONObject mainArray = (JSONObject) jsonObj.get("main"); 
      double ktemp = Double.parseDouble(mainArray.get("temp").toString()); 

      locationResult = (String) jsonObj.get("name"); 
      weatherResult = (String) weather.get("main"); 
      tempResult = Double.toString(ktemp) + "℃"; 


      System.out.println("startWeatherThread" + locationResult); 


      bf.close(); 
     }catch(Exception e){ 
      System.out.println(e.getMessage()); 
     } 


    } 


    public void setLabel(){ 
     Platform.runLater(new Runnable(){ 
      @Override 
      public void run(){ 
       System.out.println(locationResult); 
       labelLocation.setText(locationResult); 
      } 
     }); 

    } 

}

+0

您没有在控制器上调用'setLabel()':您正在调用它在不同的对象上(这恰好与控制器的类相同) 。很明显,注释了作为加载FXML文件一部分而创建的@ FXML的字段仅在实际控制器中初始化。 –

回答

0

首先,我不使用公共属性的推荐,我建议你检查Why use getters and setters?因此改变你的3个公共领域转化为私人领域,然后让他们获得和吸引他们。

关于你的问题,我还没有看到你的fxml代码,但要确保你给你的标签一个身份,也称为fx:id,所以它不会导致它为空。 此外,请确保您提供参考WeatherControllerfx:controller