0

The title describes it rather well; A PopupWindow opens, and is used as a menu for my game. However, when I try to use a button to close the menu, Eclipse says "The local variable pw may not have been initialized" :\

My Java code:

package com.bipbapapps.leagueclickerapp;


import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.TextView;

public class MainClass extends Activity implements OnClickListener {

public float goldCount;
Button minionClick;
Button storeClick;
Button storeDismiss;
TextView textGoldCount;
String textTotal;
private SharedPreferences prefs;

@Override
public void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //Set full-screen
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.mainlayout);

    prefs = getSharedPreferences("LeagueClicker", Context.MODE_PRIVATE);


    goldCount = prefs.getFloat("goldCount", 0.0f);

    //Linking the variables
    minionClick = (Button) findViewById(R.id.minioncentreid);
    storeClick = (Button) findViewById(R.id.storeimageid);
    storeDismiss = (Button) findViewById(R.id.menudismissid);
    textGoldCount = (TextView) findViewById(R.id.textviewtop);

    //String which will display at the top of the app
    textTotal = goldCount + " Gold";

    //Setting TextView to the String
    textGoldCount.setText(textTotal);
    textGoldCount.setGravity(Gravity.CENTER);
    Typeface tf = Typeface.createFromAsset(getAssets(), "mechanical.ttf");
    textGoldCount.setTypeface(tf);
    textGoldCount.setTextSize(35);

    //Setting onClickListener
    minionClick.setOnClickListener(this);
    storeClick.setOnClickListener(this);
    storeDismiss.setOnClickListener(this);


}


@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()){
    case R.id.minioncentreid:
    goldCount += 1.0;
    prefs.edit().putFloat("goldCount", goldCount).commit();
    textTotal = goldCount + " Gold";
    textGoldCount.setText(textTotal);
    textGoldCount.setGravity(Gravity.CENTER);
    break;

    case R.id.storeimageid:
        LayoutInflater inflater = (LayoutInflater)
           this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        PopupWindow pw = new PopupWindow(
           inflater.inflate(R.layout.storemenu, null, false), 
           300, 
           450, 
           true);
        pw.showAtLocation(v, Gravity.CENTER, 0, 0);

    case R.id.menudismissid:
        pw.dismiss();
        break;

    }


}


@Override
public void onPause(){
    super.onPause();
    prefs.edit().putFloat("goldCount", goldCount).commit();
}

@Override
public void onResume(){
    super.onResume();
    goldCount = prefs.getFloat("goldCount", 0.0f);
}

@Override
public void onStop(){
    super.onStop();
    prefs.edit().putFloat("goldCount", goldCount).commit();
    Log.d(prefs.getFloat("goldCount", 0.0f)+"derprolw", "ejwfjbrea");
}

}

Does anyone know how I can set the button to dismiss the PopupWindow?

EDIT: The LogCat errors which are now produced:

04-22 15:20:04.478: E/AndroidRuntime(3491): FATAL EXCEPTION: main
04-22 15:20:04.478: E/AndroidRuntime(3491): Process: com.bipbapapps.leagueclickerapp, PID: 3491
04-22 15:20:04.478: E/AndroidRuntime(3491): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bipbapapps.leagueclickerapp/com.bipbapapps.leagueclickerapp.MainClass}: java.lang.NullPointerException
04-22 15:20:04.478: E/AndroidRuntime(3491):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at android.os.Handler.dispatchMessage(Handler.java:102)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at android.os.Looper.loop(Looper.java:136)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at android.app.ActivityThread.main(ActivityThread.java:5017)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at java.lang.reflect.Method.invokeNative(Native Method)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at java.lang.reflect.Method.invoke(Method.java:515)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at dalvik.system.NativeStart.main(Native Method)
04-22 15:20:04.478: E/AndroidRuntime(3491): Caused by: java.lang.NullPointerException
04-22 15:20:04.478: E/AndroidRuntime(3491):     at com.bipbapapps.leagueclickerapp.MainClass.onCreate(MainClass.java:66)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at android.app.Activity.performCreate(Activity.java:5231)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
04-22 15:20:04.478: E/AndroidRuntime(3491):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)

EDIT 2:

So, with some help and editing, we've figured out the code:

//Initialize variables from popup window
     LayoutInflater inflater = (LayoutInflater)
           this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    PopupWindow pw = new PopupWindow(
               inflater.inflate(R.layout.storemenu, null, false)); 
    storeDismiss = (Button) pw.getContentView().findViewById(R.id.menudismissid);

In place of "storeDismiss = (Button) findViewById(R.id.menudismissid);". The only issue now is that the button doesn't actually dismiss the menu :(

frogatto
  • 28,539
  • 11
  • 83
  • 129
BipBapApps
  • 73
  • 1
  • 10
  • Are you missing a `break;` at the end of the `case R.id.storeimageid` and before the `case R.id.menudismissid`? What line is Eclipse complaining about? – jedison Apr 22 '14 at 18:25

1 Answers1

0

I don't think you can use variable defined inside one case block in another case block. Because there is no particular sequence of execution for case blocks. Better approach would be, declare PopupWindow as member variable of the class.

public class MainClass extends Activity implements OnClickListener {

public float goldCount;
Button minionClick;
Button storeClick;
Button storeDismiss;
TextView textGoldCount;
String textTotal;
private SharedPreferences prefs;
PopupWindow pw;

@Override
public void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //Set full-screen
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.mainlayout);

    prefs = getSharedPreferences("LeagueClicker", Context.MODE_PRIVATE);


    goldCount = prefs.getFloat("goldCount", 0.0f);

    //Linking the variables
    minionClick = (Button) findViewById(R.id.minioncentreid);
    storeClick = (Button) findViewById(R.id.storeimageid);
    storeDismiss = (Button) findViewById(R.id.menudismissid);
    textGoldCount = (TextView) findViewById(R.id.textviewtop);

    //String which will display at the top of the app
    textTotal = goldCount + " Gold";

    //Setting TextView to the String
    textGoldCount.setText(textTotal);
    textGoldCount.setGravity(Gravity.CENTER);
    Typeface tf = Typeface.createFromAsset(getAssets(), "mechanical.ttf");
    textGoldCount.setTypeface(tf);
    textGoldCount.setTextSize(35);

    //Setting onClickListener
    minionClick.setOnClickListener(this);
    storeClick.setOnClickListener(this);
    storeDismiss.setOnClickListener(this);


}


@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    switch (v.getId()){
    case R.id.minioncentreid:
    goldCount += 1.0;
    prefs.edit().putFloat("goldCount", goldCount).commit();
    textTotal = goldCount + " Gold";
    textGoldCount.setText(textTotal);
    textGoldCount.setGravity(Gravity.CENTER);
    break;

    case R.id.storeimageid:
        LayoutInflater inflater = (LayoutInflater)
           this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if(pw == null) {
        pw = new PopupWindow(
           inflater.inflate(R.layout.storemenu, null, false), 
           300, 
           450, 
           true);
        }
        pw.showAtLocation(v, Gravity.CENTER, 0, 0);
         break;

    case R.id.menudismissid:
        if (pw != null) {
        pw.dismiss();
        }
        break;

    }

Also do not forget to put break statement at the end of first case block :)

Edit 1: You can access view elements of the PopUpWindow by

//Linking the variables
minionClick = (Button) findViewById(R.id.minioncentreid);
storeClick = (Button) findViewById(R.id.storeimageid);
textGoldCount = (TextView) findViewById(R.id.textviewtop);

//Initialize variables from popup window
 LayoutInflater inflater = (LayoutInflater)
       this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
PopupWindow pw = new PopupWindow(
           inflater.inflate(R.layout.storemenu, null, false), 
storeDismiss = pw.getContentView().findViewById(R.id.menudismissid);

Edit 2:

Official doc for dismiss function says that

public void dismiss ()

Added in API level 1 Dispose of the popup window. This method can be invoked only after showAsDropDown(android.view.View) has been executed. Failing that, calling this method will have no effect.

So your code for case 2 should be

case R.id.storeimageid:
        LayoutInflater inflater = (LayoutInflater)
           this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if(pw == null) {
        pw = new PopupWindow(
           inflater.inflate(R.layout.storemenu, null, false), 
           300, 
           450, 
           true);
        }
        pw.showAsDropDown(v, 0, 0, Gravity.CENTER);
         break;
Abhishek V
  • 12,488
  • 6
  • 51
  • 63
  • It doesn't seem to be working :\ This removes the error, but then my app crashes upon loading. – BipBapApps Apr 22 '14 at 19:11
  • Can you post the LogCat trace of the exception? – Abhishek V Apr 22 '14 at 19:14
  • Which is line 66? double click on this statement in logcat `at com.bipbapapps.leagueclickerapp.MainClass.onCreate(MainClass.java:66)`. It will show the line in code which is causing `NullPointerExceptio`n – Abhishek V Apr 23 '14 at 08:45
  • The line is "storeDismiss.setOnClickListener(this);". I've been messing around with the code, but I can't figure out anything - There's still no error, but the app just crashes upon loading. – BipBapApps Apr 23 '14 at 11:53
  • Seems like `storeDismiss` is null. Are you sure button with id `menudismissid` is there in `mainlayout` ? Can you post the code for `mainlayout.xml` file? – Abhishek V Apr 23 '14 at 12:42
  • Yeah, that's right; the button with id menudismissid is in the XML of the popupwindow, "storemenu.xml". So, why does the code not recognise the id in the storemenu XML? What can I do to link the java code to this button? I'm quite new at this, so I do appreciate the help. – BipBapApps Apr 23 '14 at 12:51
  • So now inflater and popupWindow cannot be resolved. Sorry if I'm being a pain, my code just doesn't want to work. – BipBapApps Apr 23 '14 at 13:06
  • That's fine..no problem..:) check Edit 1 – Abhishek V Apr 23 '14 at 13:17
  • Ahh, I see :) That's fixed the inflater error. Unfortunately popupWindow in the line "popupWindow.getContentView().findViewById(R.id.menudismissid);" still "cannot be resolved". None of the suggestions Eclipse makes to solve it are working for me. – BipBapApps Apr 23 '14 at 13:23
  • Ah! sorry..it should be `pw.getContentView()`.. check edit 1 again – Abhishek V Apr 23 '14 at 13:25
  • No problem :) I actually tried that earlier, but it produces two errors in the line "new PopupWindow( inflater.inflate(R.layout.storemenu, null, false), storeDismiss = pw.getContentView().findViewById(R.id.menudismissid);", saying "The constructor PopupWindow(View, Button) is undefined" and that there's a syntax error at the end of the line. If I put a bracket after ";", the syntax error goes away, but it then says "findViewById cannot be resolved or is not a field" – BipBapApps Apr 23 '14 at 13:34
  • Ah, never mind, on adding the bracket, Eclipse then tells me to remove it, leaving me with the massive errors. There's actually: -Type mismatch: cannot convert from View to Button -Syntax error, insert ")" to complete VariableInitializer – BipBapApps Apr 23 '14 at 13:38
  • Okay, so I *seem* to have fixed the code, now the button just doesn't actually dismiss the menu :P See my edited main post, please :) – BipBapApps Apr 23 '14 at 13:48