I keep getting the error message Error: java.lang.NullPointerException at runtime. Obviously I understand that this shows when I am referencing some variable that has a null value when it should have some value. Thought it best to show you the code so I can put it into context.
public class MarathonAdmin
{
private List<Runner> runners;
/**
* Constructor for objects of class MarathonAdmin
*/
public MarathonAdmin()
{
// initialise instance variables
List<Runner> runners = new ArrayList<>();
}
public void readInRunners()
{
String pathName = OUFileChooser.getFilename();
File aFile = new File(pathName);
Scanner bufferedScanner = null;
try
{
String runnerName;
int runnerAge;
String ageGroup;
Scanner lineScanner;
String currentLine;
bufferedScanner = new Scanner(new BufferedReader(new FileReader(aFile)));
while (bufferedScanner.hasNextLine())
{
currentLine = bufferedScanner.nextLine();
lineScanner = new Scanner(currentLine);
lineScanner.useDelimiter(",");
runnerName = lineScanner.next();
runnerAge = lineScanner.nextInt();
Runner runnerObject = new Runner();
if (runnerAge < 18)
{
ageGroup = "junior";
runnerObject.setAgeGroup(ageGroup);
}
else
if (runnerAge > 54)
{
ageGroup = "senior";
runnerObject.setAgeGroup(ageGroup);
}
else
{
ageGroup = "standard";
runnerObject.setAgeGroup(ageGroup);
}
runnerObject.setName(runnerName);
runners.add(runnerObject);
}
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
finally
{
try
{
bufferedScanner.close();
}
catch (Exception anException)
{
System.out.println("Error: " + anException);
}
}
}
The test code to create an instance of the class is:
MarathonAdmin ma = new MarathonAdmin();
ma.readInRunners();
There is a class in use called Runners which is already set up with its protocols. The class compiles but the ma.readInRunner(); message ends in an error. The text file that the program is to run from has no errors.
I'm somewhat new to programming and so find it hard to troubleshoot issues. Hopefully someone can help me out.
In the constructor it should be
public MarathonAdmin()
{
// initialise instance variables
this.runners = new ArrayList<>();
}
and not
public MarathonAdmin()
{
// initialise instance variables
List<Runner> runners = new ArrayList<>();
}
The problem is that you have made a Try-catch block, but in the catch part you are not printing the stacktrace, see:
catch (Exception anException)
{
System.out.println("Error: " + anException); // just prints: Error: java.lang.NullPointerException
}
Improve this catch block for debugging, for example like this:
catch (Exception e) {
e.printStackTrace(); //prints the full stacktrace
}
Now you should get a full stacktrace that also shows you the line number and you will be able to debug it yourself ;-)
In fact you probably should remove that try-catch blocks at all.
Related
I've working on an assignment that asks me to alter a method in a class to take content from a textfile and use it to create multiple instances of various subclasses of the Event Class. Here is the text file:
Event=ThermostatNight,time=0
Event=LightOn,time=2000
Event=WaterOff,time=8000
Event=ThermostatDay,time=10000
Event=Bell,time=9000
Event=WaterOn,time=6000
Event=LightOff,time=4000
Event=Terminate,time=12000
The Event=* is the name of the subclass, while time=* is a parameter that is used in the subclass' constructor. The Event class itself is an abstract class and is used for inheritance.
public class Restart extends Event {
Class eventClass;
String eventInput;
Long timeDelay;
public Restart(long delayTime, String filename) {
super(delayTime);
eventsFile = filename;
}
public void action() {
List<String> examples = Arrays.asList("examples1.txt", "examples2.txt", "examples3.txt", "examples4.txt");
for (String example : examples) {
//finding pattern using Regex
Pattern pattern = Pattern.compile(example);
Matcher matcher1 = pattern.matcher(eventsFile);
if (matcher1.find()) {
File file = new File(example);
String line;
try {
FileReader fileReader = new FileReader(file);
Scanner sc = new Scanner(file);
BufferedReader bufferedReader =
new BufferedReader(fileReader);
while ((line = bufferedReader.readLine()) != null) {
sc.useDelimiter("\n");
//Parsing through text
while (sc.hasNext()) {
String s = sc.next();
String[] array1 = s.split(",");
String[] array2 = array1[0].split("=");
eventInput = array2[1];
String[] array3 = array1[1].split("=");
String timeInput = array3[1];
try {
eventClass = Class.forName(eventInput);
timeDelay = Long.parseLong(timeInput);
try {
addEvent(new eventClass(timeDelay));
}
//catch block
catch(NoSuchMethodException e){
System.out.println("No Such Method Error");
} catch (Exception e) {
System.out.println("error");
}
//catch block
} catch (ClassNotFoundException ex) {
System.out.println("Unable to locate Class");
} catch (IllegalAccessException ex) {
System.out.println("Illegal Acces Exception");
} catch (InstantiationException ex) {
System.out.println("Instantiation Exception");
}
}
}
//Close bufferedReader
bufferedReader.close();
}
//catch block
catch (FileNotFoundException ex) {
System.out.println(
"Unable to open file '" +
file + "'");
} catch (IOException ex) {
ex.printStackTrace();
}
break;
}
//if input match is not found
else {
System.out.println("No Match Found");}
}
}
I seem to be able to parse fine, and find the strings i'm looking for, but I'm not able to use eventInput which I've pulled from the text file as a parameter to create a new event.
eventClass = Class.forName(eventInput);
doesn't seem to be turning my string into an acceptable parameter either.
Any help would be much appreciated!
I know I'm probably missing something key here, but I've been staring at it too long that it seems like a lost cause.
Here is the Event class:
public abstract class Event {
private long eventTime;
protected final long delayTime;
public Event(long delayTime) {
this.delayTime = delayTime;
start();
}
public void start() { // Allows restarting
eventTime = System.currentTimeMillis() + delayTime;
}
public boolean ready() {
return System.currentTimeMillis() >= eventTime;
}
public abstract void action();
} ///:~
I think you've misunderstood how reflection works. Once you have a Class object (the output from Class.forName(), you have to find the appropriate constructor with
Constructor<T> constructor = eventClass.getConstructor(parameter types)
and then create a new instance with
constructor.newInstance(parameters);
For a no-arg constructor there's a shortcut
eventClass.newInstance();
I strongly suggest you read the tutorials on reflection before proceeding.
This question already has an answer here:
javafx using objects from MainController or other Controllers in proper Controller class
(1 answer)
Closed 5 years ago.
sorry. I don't speak english well so please understand me
I'm making smartmirror for java but I have problem with setText() function.
after calling weather api and saving location name to variable, I start label.setText() but it has null pointer exception.
I heard about platform.run later() method and task , but they don't work.
please help me T.T
There are my source
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);
}
});
}
}
First of all, I'm not recommending on using public attributes, I suggest you to check Why use getters and setters? so change your 3 public field to a private ones and then make getters and setters to them.
About your problem, I haven't seen your fxml code for it, but make sure you gave your label an identity also known as fx:id so it wouldn't cause it to be null.
Also make sure that you gave reference to your WeatherController in fx:controller
It is showing temp_lib is not declared, but it is already declared.
Library temp_lib is already declared after try and return, temp_lib is written at last but also it is asking for me to initialize the variables.
int numAdded=0;
File inputfile;
inputfile = new File("export_Library.txt");
try {
Library temp_lib;
Scanner inputScanner = new Scanner(inputfile);
System.out.println("processing a library...");
String name=inputScanner.nextLine();
int capacity=Integer.parseInt(inputScanner.next());
temp_lib=new Library(name,capacity);
LibraryItem item=new LibraryItem();
while(inputScanner.hasNextLine()){
item.setTitle(inputScanner.nextLine());
item.setID_code(inputScanner.nextLine());
item.setYearOfPublication(Integer.parseInt(inputScanner.nextLine()));
if(inputScanner.next()=="1")
{
item.setOnLoan(true);
}
else
{
item.setOnLoan(false);
}
item.setReplacementCost(inputScanner.nextDouble());
}
inputScanner.close();
}
catch (IOException e) {
System.out.println("IO Exception reading shapes from file"+e);
e.printStackTrace() ;
//return temp_lib;
}
return temp_lib;
Library temp_lib; must be before the try-catch block in order to be in scope after the try-catch block.
Library temp_lib = null; // you must give it an initial value, or the code
// won't compile
try {
...
}
catch (..) {
...
}
return temp_lib;
Whenever I run my code, the inv.txt file changes from having 25 lines of the character 1 to nothing, could someone tell me what I'm doing wrong?
PS the main class includes inventory.addItem();
public class inventory {
File inventory = new File("Resources/inv.txt");
File db = new File("Resources/db.txt");
FileWriter write;
StringBuilder writethis;
public void addItem(int item, int slot){
int i;
Scanner scan = null;
try {
scan = new Scanner(inventory);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
write = new FileWriter(inventory);
} catch (IOException e) {
e.printStackTrace();
}
for(i = 1; i < slot; i++)writethis.append(scan.nextLine());
System.out.println(writethis.toString());
}
}
Use write = new FileWriter(inventory, true);
It will append data to existing file. See the documentation on FileWriter Constructor for further details.
I'm learning now how to do serialization using Java Language. I have read some posts and docs about the subject and I tried to do a simple example (below)
public class SterializeObject implements java.io.Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private transient int code;
public SterializeObject (String n, int c){
name = n;
code = c;
}
public void printAtributes (){
System.out.println("name: " + name + "; code: " + code);
}
}
public class MainClass {
public static void main(String[] agrs) {
SterializeObject ob1 = new SterializeObject("ana", 1);
SterializeObject ob2 = new SterializeObject("rita", 2);
try {
FileOutputStream fileOut = new FileOutputStream("file.data");
ObjectOutputStream outObj = new ObjectOutputStream(fileOut);
outObj.writeObject(ob1);
outObj.writeObject(ob2);
outObj.close();
System.out.println("Objects were serialized!");
} catch (IOException e) {
e.printStackTrace();
}
ArrayList<SterializeObject> list = new ArrayList<SterializeObject>();
try {
FileInputStream fileInput = new FileInputStream("file.data");
ObjectInputStream inputObj = new ObjectInputStream(fileInput);
Object o;
try {
while ((o = inputObj.readObject()) != null) {
list.add((SterializeObject) o);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Erro foi aqui! (1)");
}
inputObj.close();
fileInput.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Erro foi aqui! (2)");
}
for (int i = 0; i < list.size(); ++i) {
list.get(i).printAtributes();
}
}
}
I created a Class SterializeObject that implements java.io.Serializable with two variables: one string (name) and one int (code) that is transient. Then In the main I generate two instances of that class and I tried to write it in a file, that I have done successfully! After that, I try to read the two object with a Loop.. there is my problem.. since the ObjectInputStream dosen't have some kind of method to see if we are in the end or not. So, I tried to do with this condition: (o = inputObj.readObject()) != null.
My output is this:
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at MainClass.main(MainClass.java:30)
Objects were serialized!
Erro foi aqui! (2)
name: ana; code: 0
name: rita; code: 0
I get the objects, but I get an error because, I think, is trying to access to something that doesn't exist.
Someone can tell me other way to do it?
Best Regards.
Read as many objects as the number of written objects, or write the list of objects itself, instead of writing every object one after the other.
(Or rely on the EOFException to detect the end of the stream, but this is ugly).
As many of you told me to do, I created a ArrayList and serialized the ArrayList.
My code is:
public class MainClass {
public static void main(String[] agrs) {
SterializeObject ob1 = new SterializeObject("ana", 1);
SterializeObject ob2 = new SterializeObject("rita", 2);
ArrayList <SterializeObject> list = new ArrayList<>();
list.add(ob1);
list.add(ob2);
ArrayList <SterializeObject> input = new ArrayList<SterializeObject>();
try {
FileOutputStream fileOut = new FileOutputStream("file.data");
ObjectOutputStream outObj = new ObjectOutputStream(fileOut);
outObj.writeObject(list);
outObj.close();
System.out.println("Objects were serialized!");
} catch (IOException e) {
e.printStackTrace();
}
try {
FileInputStream fileInput = new FileInputStream("file.data");
ObjectInputStream inputObj = new ObjectInputStream(fileInput);
Object o;
try {
input = (ArrayList<SterializeObject>) inputObj.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Erro foi aqui! (1)");
}
inputObj.close();
fileInput.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Erro foi aqui! (2)");
}
for (int i = 0; i < input.size(); ++i) {
input.get(i).printAtributes();
}
}
}
And the output is:
Objects were serialized!
name: ana; code: 0
name: rita; code: 0
Thank you for the help!
Close the FileOutputStream also along with ObjectOutputStream
fileOut.close();
Why don't you add both object to an ArrayList, and serialize the ArrayList. Then you just have to Deserialize the ArrayList and it will be populated with both objects.
You can do this by placing the readObject call inside a try-catch block and catching that EOFException you get, signaling you have read all the objects.
Replace your while loop with this piece of code
do{
try
{
o = inputObj.readObject();
list.add((SterializeObject) o);
}
catch(EOFException e)
{
o = null;
}
}while (o != null);