label.setText()处的JavaFX空指针异常

时间:2017-04-13 17:00:17

标签: java javafx nullpointerexception

对不起。我不会说英语,所以请理解我

我正在为java创建smartmirror但我遇到了setText()函数的问题。

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

我听说过platform.run later()方法和任务,但是他们不能工作。

请帮帮我T.T 有我的来源

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);
            }
        });

    }

}

1 个答案:

答案 0 :(得分:0)

首先,我建议您不要使用公共属性,我建议您检查Why use getters and setters?,然后将您的3个公共字段更改为私有字段,然后为其创建getter和setter。

关于您的问题,我还没有看到您的fxml代码,但请确保您为您的标签提供了一个名为fx:id的标识,因此它不会导致它为空。 另外,请确保您在WeatherController

中提及了fx:controller