0

I have 4 images as buttons and when the correct button is selected, an arrow button appears which is working fine.

My problem is that I'm trying to change the background resource of each button to change when this arrow is clicked but I'm getting a null pointer exception at this line :

happybutton.setBackgroundResource(R.drawable.mum1);

I have declared the nextArrow button in my java onCreate -

nextArrow = (Button) findViewById(R.id.nextArrow);
nextArrow.setOnClickListener(onClickListener);

class:

protected void onCreate (Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.expressions);

        Button happybutton = (Button) findViewById(R.id.happybutton);
        happybutton.setOnClickListener(onClickListener);
        Button sadbutton = (Button)findViewById(R.id.sadbutton);
        sadbutton.setOnClickListener(onClickListener);
        Button worriedbutton = (Button) findViewById(R.id.worriedbutton);
        worriedbutton.setOnClickListener(onClickListener);
        Button excitedbutton = (Button) findViewById(R.id.excitedbutton);
        excitedbutton.setOnClickListener(onClickListener);
        //Button nextArrow = (Button) findViewById(R.id.nextArrow);
        //nextArrow.setOnClickListener(onClickListener);

        tick = (ImageView) findViewById(R.id.tick);
        cross = (ImageView)findViewById(R.id.cross);
        cross2 = (ImageView) findViewById(R.id.cross2);
        cross3 = (ImageView) findViewById(R.id.cross3);

        nextArrow = (Button) findViewById(R.id.nextArrow);
        nextArrow.setOnClickListener(onClickListener);


        tryagain = MediaPlayer.create(Expressions.this,R.raw.tryagain);
        correct = MediaPlayer.create(Expressions.this,R.raw.correct);

    }

private OnClickListener onClickListener = new OnClickListener(){

    public void onClick(final View view){
        switch(view.getId()){

        case R.id.happybutton:

            tick.setVisibility(View.VISIBLE);
            nextArrow.setVisibility(View.VISIBLE);
            correct.start();
            break;

        case R.id.sadbutton:

            cross.setVisibility(View.VISIBLE);
            tryagain.start();
            break;

        case R.id.worriedbutton:

            cross3.setVisibility(View.VISIBLE);
            tryagain.start();
            break;

        case R.id.excitedbutton:

            cross2.setVisibility(View.VISIBLE);
            tryagain.start();
            break;


        case R.id.nextArrow:

            happybutton.setBackgroundResource(R.drawable.mum1);
            worriedbutton.setBackgroundResource(R.drawable.mum2);
            sadbutton.setBackgroundResource(R.drawable.mum3);
            excitedbutton.setBackgroundResource(R.drawable.mum4);
            break;
        }   
    }   

Logcat:

 07-31 16:17:11.312: E/AndroidRuntime(7818): FATAL EXCEPTION: main
    07-31 16:17:11.312: E/AndroidRuntime(7818): java.lang.NullPointerException
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at 
com.example.Autism_App.Expressions$1.onClick(Expressions.java:84)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at android.view.View.performClick(View.java:4383)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at android.view.View$PerformClick.run(View.java:18097)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at android.os.Handler.handleCallback(Handler.java:725)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at android.os.Handler.dispatchMessage(Handler.java:92)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at android.os.Looper.loop(Looper.java:176)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at android.app.ActivityThread.main(ActivityThread.java:5279)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at java.lang.reflect.Method.invokeNative(Native Method)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at java.lang.reflect.Method.invoke(Method.java:511)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
    07-31 16:17:11.312: E/AndroidRuntime(7818):     at dalvik.system.NativeStart.main(Native Method)

xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/question"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="29dp"
        android:text="Which face is the happy face?"
        android:textSize="80sp" />

    <Button
        android:id="@+id/happybutton"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignLeft="@+id/excitedbutton"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="43dp"
        android:background="@drawable/happyface"/>

    <Button
        android:id="@+id/nextArrow"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="65dp"
        android:visibility="invisible"
        android:background="@drawable/nextarrow" />

    <Button
        android:id="@+id/worriedbutton"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignBaseline="@+id/happybutton"
        android:layout_alignBottom="@+id/happybutton"
        android:layout_alignLeft="@+id/sadbutton"
        android:background="@drawable/worriedface" />

    <Button
        android:id="@+id/sadbutton"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_below="@+id/question"
        android:layout_marginRight="113dp"
        android:layout_marginTop="29dp"
        android:layout_toLeftOf="@+id/nextArrow"
        android:background="@drawable/sadface" />

    <Button
        android:id="@+id/excitedbutton"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignBaseline="@+id/sadbutton"
        android:layout_alignBottom="@+id/sadbutton"
        android:layout_alignLeft="@+id/question"
        android:layout_marginLeft="116dp"
        android:background="@drawable/excitedface" />

    <ImageView
        android:id="@+id/cross2"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignLeft="@+id/excitedbutton"
        android:layout_alignTop="@+id/excitedbutton"
        android:src="@drawable/cross"
        android:visibility="invisible" />

    <ImageView
        android:id="@+id/cross"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignLeft="@+id/sadbutton"
        android:layout_alignTop="@+id/sadbutton"
        android:src="@drawable/cross"
        android:visibility="invisible" />

    <ImageView
        android:id="@+id/tick"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignLeft="@+id/excitedbutton"
        android:layout_alignTop="@+id/worriedbutton"
        android:src="@drawable/tick"
        android:visibility="invisible" />

    <ImageView
        android:id="@+id/cross3"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignLeft="@+id/worriedbutton"
        android:layout_alignTop="@+id/worriedbutton"
        android:src="@drawable/cross"
        android:visibility="invisible" />

</RelativeLayout>

Am I missing something really obvious?

6
  • Is your HappyButton already defined at that point??It seems that you reach HappyButton.setBackground without having implemented it... Commented Jul 31, 2014 at 15:29
  • It's defined in onCreate? - Button happybutton = (Button) findViewById(R.id.happybutton); happybutton.setOnClickListener(onClickListener); Commented Jul 31, 2014 at 15:31
  • can you post your xml layout? Commented Jul 31, 2014 at 15:37
  • where have you placed the buttons???is it inside fragment_main.xml or activity_main.xml ??? Commented Jul 31, 2014 at 15:41
  • 2
    Add your entire onCreate() method to the question. Do you perhaps declare happybutton twice, once as an instance field which never gets initialized, and a second time as a local variable in onCreate, which does get initialized but then forgotten? Consider logging happybutton both at the end of onCreate() and the start of onClick() Commented Jul 31, 2014 at 15:45

3 Answers 3

5

You are initializing a local variable not the instance field

protected void onCreate (Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.expressions);

    Button happybutton = (Button) findViewById(R.id.happybutton);
    happybutton.setOnClickListener(onClickListener);

When you say Button happybutton you are creating a new variable whose scope is confined to the onCreate() method, and will supersede the instance field of that name for the duration of this method. You initialize this variable, so calling its setOnClickListener method works fine. But the variable disappears at the end of the onCreate() method, and other methods see only the never-initialized instance field of the same name.

Instead, simply initialize the instance field which you your presumably already declared outside of onCreate()

Button happybutton;

protected void onCreate (Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.expressions);

    happybutton = (Button) findViewById(R.id.happybutton);
    happybutton.setOnClickListener(onClickListener);

This can be a fairly subtle mistake, since superceding an instance field with a local variable is entirely valid code which will not trigger any compiler complaints.

Sign up to request clarification or add additional context in comments.

1 Comment

I have deleted my answer. No point to double it. You are perfectly right!
0

I believe, that class memeber happybutton is not initialized.

3 Comments

If the line on which the NPE occurs is correctly reported, then yes, it would be null there. What is puzzling however is that coderoligist seems to say that a method of happybutton is being called in onCreate, and if it were not initialized it should fail with an NPE there instead.
it's initialised in my onCreate method - Button happybutton = (Button) findViewById(R.id.happybutton); happybutton.setOnClickListener(onClickListener);
Button happybutton - this is local variable, remove Button.
0

The buttons should be class variables like so:

public class MyClass {
    Button happybutton;
    Button sadbutton;
    Button worriedbutton;
    Button excitedbutton;

    protected void onCreate (Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.expressions);

        happybutton = (Button) findViewById(R.id.happybutton);
        happybutton.setOnClickListener(onClickListener);
        sadbutton = (Button)findViewById(R.id.sadbutton);
        sadbutton.setOnClickListener(onClickListener);
        worriedbutton = (Button) findViewById(R.id.worriedbutton);
        worriedbutton.setOnClickListener(onClickListener);
        excitedbutton = (Button) findViewById(R.id.excitedbutton);
        excitedbutton.setOnClickListener(onClickListener);
...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.