I'm just starting out with learning Java, and have run into a problem. When trying to run an Android application, I get a NullPointerException when the method makeResponse is called.
Code extract (full code appended at the end of this post):
private String makeResponse(String input){
//This doesn't work yet. I keep getting null pointer exceptions on the line beginning "int id" line, but can't tell why.
String response = "You picked "+input;
if (sw==null){
response+=" and sw is null"; //This doesn't activate
}
if (input==null){
response+=" and input is null"; //This doesn't activate
}
int id = sw.getIdFromName(input); //If this line (and the following one) are commented out, the method runs with no problem, but neither of the if clauses above trigger.
response+=", that has id "+String.valueOf(id);
return response;
}
(sw is a field of the parent class, set in another method. sw is an instance of a self-made class - full code at the end)
The exception is thrown at the line beginning "int id ="
My initial searching for NullPointerException told me that it was "thrown when an application attempts to use null in a case where an object is required." - hence the two "if" clauses in my code above, to try to find which object was unexpectedly null. Since neither of these are, I concluded that sw.getIdFromName must be returning a null of type Integer (as in this similar problem: Java: null pointer exception when unboxing Integer?). However, I don't see how this is possible in sw.getIdFromName as shown below (nameLookup is a String array, a field of sw):
public int getIdFromName(String name){
for (int i=0;i<267;i++){
if (nameLookup[i].equals(name)){
return i;
}
}
return -1;
}
(Incidentally, if there is a better way of searching a String array for a search term, I would be grateful if someone could tell me - binarySearch doesn't appear to be defined on String arrays).
Following the advice of the top commenter in the question linked above, I tried replacing "int id" with "Integer id" in makeResponse, but with no effect - the same exception is thrown at the same place.
Any advice would be gratefully appreciated.
Judging from the comments in the stackoverflow question linked above, providing a stack trace would not provide any new information, but I'd be happy to do so if asked.
P.s. this is my first question here, so apologies if I make some breach of etiquette or inane mistake.
Full code listings:
ConversationActivity.java:
package com.example.Conversation;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
public class ConversationActivity extends Activity {
/** Called when the activity is first created. */
StationsWrapper sw;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/**Setting the adapter for the AutoComplete*/
final AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.ACTextView1);
String[] stationsArray = getResources().getStringArray(R.array.stations);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, stationsArray);
textView.setAdapter(adapter);
/**Code below grabs the data from stations.xml and puts it in a readable object */
this.sw = new StationsWrapper();
/** Code below is to set a click function for the AutoComplete*/
OnItemClickListener ACListener = new OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View v, int position,
long id) {
TextView reply = (TextView) findViewById(R.id.reply);
reply.setText("working...");
String ChosenStation = (String) parent.getItemAtPosition(position);
reply.setText(makeResponse(ChosenStation));
//Toast.makeText(ConversationActivity.this, "You clicked "+parent.getItemAtPosition(position), Toast.LENGTH_SHORT).show();
textView.setText("");
}
};
textView.setOnItemClickListener(ACListener);
}
private String makeResponse(String input){
//This doesn't work yet. I keep getting null pointer exceptions on the line beginning "int id" line, but can't tell why.
String response = "You picked "+input;
if (sw==null){
response+=" and sw is null"; //This doesn't activate
}
if (input==null){
response+=" and input is null"; //This doesn't activate
}
int id = sw.getIdFromName(input); //If this line (and the following one) are commented out, the method runs with no problem, but neither of the if clauses above trigger.
response+=", that has id "+String.valueOf(id);
return response;
}
}
StationsWrapper.java:
package com.example.Conversation;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class StationsWrapper {
private int[][] stats;
private String[] nameLookup;
public StationsWrapper(){
//Constructor. Grabs data from XML, and whacks it into relevant arrays.
//stats is an integer array, indexed first by station id (1-267), and then by datatype (0 for line, 1 for zone)
final int[][] stats = new int[267][2];
final String[] nameLookup = new String[267];
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean bline = false;
boolean bzone= false;
String curStation;
int curID;
String curLine;
String curZone;
public void startElement(String uri, String localName,String qName,
Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("STATION")){
curStation=attributes.getValue(0);
curID=Integer.parseInt(attributes.getValue(1));
}
if (qName.equalsIgnoreCase("LINE")) {
bline = true;
}
if (qName.equalsIgnoreCase("ZONE")) {
bzone = true;
}
}
public void endElement(String uri, String localName,
String qName) throws SAXException {
if (qName.equalsIgnoreCase("Station")){
nameLookup[curID-1]=curStation;
int intLine=(convLineToInt(curLine));
stats[curID-1][0]=intLine;
int intZone=(convZoneToInt(curZone));
stats[curID-1][1]=intZone;
}
}
public void characters(char ch[], int start, int length) throws SAXException {
if (bline) {
//System.out.println("Line : " + new String(ch, start, length));
curLine=new String(ch, start, length);
bline = false;
}
if (bzone) {
//System.out.println("Zone : " + new String(ch, start, length));
curZone=new String(ch, start, length);
bzone = false;
}
}
};
saxParser.parse("c:\\Users\\Jack Jackson\\Coding\\Java\\stations.xml", handler);
} catch (Exception e) {
e.printStackTrace();
}
this.stats=stats;
this.nameLookup=nameLookup;
}
public static void main(String[] args){
//Nothing to see here, move it along folks.
}
public String[] getNameLookup(){
return nameLookup;
}
public int getIdFromName(String name){
for (int i=0;i<nameLookup.length;i++){
if (nameLookup[i].equals(name)){
return i;
}
}
return -1;
}
public int returnData(int id, int datapoint){
return stats[id][datapoint];
}
public void displayStats(){
for (int i=0;i<267;i++){
for (int j=0;j<2;j++){
System.out.print(stats[i][j]);
System.out.print(" ");
}
System.out.println("");
}
}
}