Why is this MainActivity class code working? - java

I am writing tic tac toe game in which i am calling imageTapped when image is tapped to change its image to cross and then it calling aiturn to find valid move and change its image to circle. Now my question is how did calling non static method aiturn from non static method imageTapped works without creating its object.
package com.example.kapil.tictactoe;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private GameLogic gameLogic;
LinearLayout linearLayout;
TextView label;
public void imageTapped (View view) {
ImageView image = (ImageView) view;
label = findViewById(R.id.label);
String pos = image.getTag().toString();
//if button is already tapped
if (! gameLogic.setImage(Integer.valueOf(pos)))
return;
image.setImageResource(R.drawable.cross);
//return 1 for win 2 for draw otherwise 0
int win = gameLogic.logic();
if (win == 1) {
label.setText("You Win!!");
gameLogic.gameOver();
return;
} else if (win == 2) {
label.setText("Game Draws!!");
return;
}
aiturn();
}
public void aiturn () {
int move = gameLogic.aiMove();//return best move between 0 to 8
int rowNum = move/3;
int colNum = move%3;
if (rowNum == 0) {
linearLayout = findViewById(R.id.line1);
} else if (rowNum == 1) {
linearLayout = findViewById(R.id.line2);
} else if (rowNum == 2) {
linearLayout = findViewById(R.id.line3);
}
((ImageView) linearLayout.getChildAt(colNum)).setImageResource(R.drawable.circle);
label = findViewById(R.id.label);
//return 1 for win 2 for draw otherwise 0
int win = gameLogic.logic();
if (win == 1) {
label.setText("AI wins!!");
gameLogic.gameOver();
} else if (win == 2) {
label.setText("Game Draws!!");
}
}
//if play again button is pressed
public void Reset (View view) {
gameLogic.reset();
TextView label = findViewById(R.id.label);
label.setText("");
int ids[] = {R.id.line1,R.id.line2,R.id.line3};
for (int k=0;k<ids.length;k++) {
LinearLayout linearLayout = findViewById(ids[k]);
for (int i = 0; i < linearLayout.getChildCount(); i++) {
((ImageView) linearLayout.getChildAt(i)).setImageResource(R.mipmap.ic_launcher);
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gameLogic = new GameLogic();
}
}

This works because the Android framework creates the instances of Activities.

Now my question is how did calling non static method aiturn from non static method imageTapped works without creating its object.
Android apps are not launched using a public static void main(...) method like a classic Java app.
Instead, when your app is launched, the Android framework automatically creates instances of your app's Activity classes, and wires them up to the user interface (as per the XML file).
Then, when the user "taps", the framework calls the imageTapped method on the (existing) activity object. That then calls aiturn on the same object.
Or at least, I think that is the intent of the person who wrote that code. In reality, the imageTapped method doesn't appear to be an API method in the superclass hierarchy of your MainActivity class. So I suspect that it won't be called.
I'm not sure what you are actually trying to do, but maybe you should override onTouchEvent(...)

Related

Android: How to run a loop controlled by one button (start/pause)

I am working on a program in java (android) I would like it to start and continue asking questions, upon button click, until the user is prompted for input, once input is received the program should resume asking the questions. The program should pause when the button is clicked again.
I am new to OOP and self taught. I thought that a thread was going to be the most practical way to solve the issue. I cannot get the program to both loop and allow user input. When trying to use HandlerThread I loose the ability to input data in the EditText. Could someone help with getting this loop to run on start click and loop after input?
I have a functional program that works when the button is cycled:
Main layout begins with "START" button, on click the start button turns to "PAUSE" and a seperate repeat button is made visible (and functional).
The values are generated, the question is asked, and the user is prompted by popping up the soft keyboard and setting the cursor in the EditText field.
Once an answer is received and the "enter/done" keyboard button is clicked, the answer will be evaluated against the saved values. But I cannot get the program to loop, or if I get it to loop it skips input completely and continues to as questions with no time for input.
Please direct me on code cleanliness if needed, I want to learn what I am doing incorrectly.
MAIN.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
// Create appropriate objects for buttons, edit text, and text to speech
TextToSpeech tts;
EditText txt;
Button sbtn, rbtn;
// Array and int to store numbers
int[] num;
int added = 0;
// Boolean to check if questions is running
public boolean isRunning;
// Variables for random number range. TODO(Put into switch statement and list to select 1, 10, or 100s)
static int maxNum = 100;
static int minNum = 10;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initializing buttons and others
txt = findViewById(R.id.ans);
sbtn = findViewById(R.id.strButton);
rbtn = findViewById(R.id.rptButton);
rbtn.setVisibility(View.INVISIBLE);
// Initialize text to speech engine
tts = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if (status != TextToSpeech.ERROR) {
tts.setLanguage(Locale.ENGLISH);
}
}
});
// Start button click listener
sbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!isRunning) {
// Show repeat button, hide start and show pause
rbtn.setVisibility(View.VISIBLE);
sbtn.setText("Pause");
process();
isRunning = true;
} else {
sbtn.setText("Start");
rbtn.setVisibility(View.GONE);
isRunning = false;
}
}
});
// Repeat button click listener
rbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Repeat recently generated numbers
Utilities.speakNums(num[0], num[1], tts);
}
});
}
public void onPause() {
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onPause();
}
// Get input and compare with stored values, announce if user answer is correct or incorrect
public void submitAns() {
txt.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// If the event is a key-down event on the "enter/done" button
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
// Check to make sure the text field is not empty
if (TextUtils.isEmpty(txt.getText().toString())) {
Toast.makeText(MainActivity.this, "Enter a Number!", Toast.LENGTH_SHORT).show();
return false;
}
int intValue = Integer.parseInt(txt.getText().toString());
if (added == intValue) {
Toast.makeText(MainActivity.this, "Correct", Toast.LENGTH_SHORT).show();
tts.speak("Correct", TextToSpeech.QUEUE_ADD, null, null);
} else {
Toast.makeText(MainActivity.this, added + " is the Correct Answer!", Toast.LENGTH_SHORT).show();
tts.speak("Incorrect", TextToSpeech.QUEUE_FLUSH, null, null);
Utilities.speakAns(added, tts);
tts.speak("is the Correct answer", TextToSpeech.QUEUE_ADD, null, null);
}
txt.setText("");
return true;
}
return false;
}
});
}
public void process() {
num = Utilities.askQuestion(minNum, maxNum, tts);
added = Utilities.add(num[0], num[1]);
Utilities.focus(txt, getApplicationContext());
submitAns();
}
}
UTILITIES.java
import android.content.Context;
import android.speech.tts.TextToSpeech;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import java.util.Random;
public class Utilities {
// Function to generate random numbers in range
public static int randomGen(int minNum, int maxNum) {
final Random randNum = new Random();
return randNum.nextInt(maxNum - minNum) + minNum;
}
public static int add(int num1, int num2) {
return num1 + num2;
}
public static int sub(int num1, int num2) {
return num1 - num2;
}
// Speak individual numbers with operator in between speech
public static void speakNums(int r1, int r2, TextToSpeech tts) {
String toSpeak = Integer.toString(r1);
String nexToSpeak = Integer.toString(r2);
tts.speak(toSpeak, TextToSpeech.QUEUE_ADD, null, null);
tts.speak("Plus", TextToSpeech.QUEUE_ADD, null, null);
tts.speak(nexToSpeak, TextToSpeech.QUEUE_ADD, null, null);
}
// Speak answer
public static void speakAns(int a, TextToSpeech tts) {
String sumSpeak = Integer.toString(a);
tts.speak(sumSpeak, TextToSpeech.QUEUE_ADD, null, null);
}
// Request focus so that keyboard pops up as generate button is tapped
public static void focus(EditText txt, Context context) {
txt.requestFocus();
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(txt, InputMethodManager.SHOW_IMPLICIT);
}
// Generate question, speak question, and return array of random numbers for other operations
public static int[] askQuestion(int minNum, int maxNum, TextToSpeech tts) {
int r1 = randomGen(minNum, maxNum);
int r2 = randomGen(minNum, maxNum);
speakNums(r1, r2, tts);
return new int[] { r1, r2};
}
}
If you want to have a repeating/infinite series of events that involve user interaction (like answering a question) you should set it up as a series of chained events rather than trying to use an actual code loop or handler thread.
An example of how this could be set up is:
Generate a question to show (e.g. "What is 12 + 54?")
When the user is done answering, call a "submit" method that checks their answer and either shows an error or generates a new question to show.
Repeat the cycle above for as long as you want. No loops or handler threads are needed for this.
In terms of architecture, separating out as much of the question-generation and answer-processing logic into a ViewModel will help you tremendously, then the activity can just observe the relevant state in the view model (like what question to show).
Here is a simple example based on the description and example code you provided. There is a ViewModel that handles creating a question, checking the answer, and advancing to a new question, and an Activity that observes the relevant state from the ViewModel. Try it out in a blank app project to understand how it works.
ViewModel
public class MainViewModel extends ViewModel {
// Error string to observe - to show an error message or toast
private final MutableLiveData<String> error = new MutableLiveData<>("");
LiveData<String> getError() {
return error;
}
// Current question to show
private final MutableLiveData<String> question = new MutableLiveData<>("");
LiveData<String> getQuestion() {
return question;
}
// Text to show on the start/pause button
private final MutableLiveData<String> startPauseButton = new MutableLiveData<>("START");
LiveData<String> getStartPauseButton() {
return startPauseButton;
}
// private internal state, e.g. current question,
// expected answer, play/pause state
private int expected = 0;
private String current_question = "";
private boolean playing = false;
private final Random random = new Random();
private final int minNum = 10;
private final int maxNum = 100;
private int getNumber() {
return random.nextInt(maxNum - minNum) + minNum;
}
// Process a user's answer, and either show an error
// message or generate a new question to show
void submitAnswer(String ans) {
try {
int a = Integer.parseInt(ans);
if( a == expected ) {
generateNewQuestion();
question.postValue(current_question);
}
else {
error.postValue("Incorrect answer, try again");
}
}
catch (NumberFormatException e) {
error.postValue("Not a number - enter a number");
}
}
private void generateNewQuestion() {
int a = getNumber();
int b = getNumber();
expected = a + b;
current_question = "What is " + a + " + " + b + "?";
}
void clearError() {
error.postValue("");
}
// Called when the user clicks the play/pause button
void clickStartPause() {
playing = !playing;
if( playing ) {
startPauseButton.postValue("PAUSE");
question.postValue(current_question);
}
else {
startPauseButton.postValue("START");
question.postValue("");
}
}
public MainViewModel() {
generateNewQuestion();
}
}
Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView question = findViewById(R.id.question);
EditText answer = findViewById(R.id.answer);
Button start = findViewById(R.id.start);
Button submit = findViewById(R.id.submit);
question.setVisibility(View.GONE);
answer.setVisibility(View.GONE);
submit.setVisibility(View.GONE);
MainViewModel model = new ViewModelProvider(this).get(MainViewModel.class);
// Observe the current question, and if it is blank
// hide the question/answer/submit views
final Observer<String> questionObserver = questionTxt -> {
if( questionTxt == null || questionTxt.isEmpty() ) {
question.setVisibility(View.GONE);
answer.setVisibility(View.GONE);
submit.setVisibility(View.GONE);
}
else {
question.setVisibility(View.VISIBLE);
answer.setVisibility(View.VISIBLE);
submit.setVisibility(View.VISIBLE);
question.setText(questionTxt);
}
};
// Observe the error state, if it is non-blank show
// a toast then reset the state (so the toast only shows once)
final Observer<String> errorObserver = errorText -> {
if( errorText != null && !errorText.isEmpty() ) {
Toast.makeText(this, errorText, Toast.LENGTH_LONG).show();
model.clearError();
}
};
model.getError().observe(this, errorObserver);
model.getQuestion().observe(this, questionObserver);
model.getStartPauseButton().observe(this, start::setText);
submit.setOnClickListener(v -> {
model.submitAnswer(answer.getText().toString());
answer.setText("");
});
start.setOnClickListener(v -> model.clickStartPause());
}
XML
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/question"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<EditText
android:id="#+id/answer"
android:hint="Answer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/question"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<Button
android:id="#+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/answer"/>
<Button
android:id="#+id/submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/answer"/>
</androidx.constraintlayout.widget.ConstraintLayout>

Changing TextView from different class

I want to update TextView from another class which is not an activity, but the app keeps crushing..
I hope you can help
This is the class where I want to update text after knowing game result
public class GameLogic {
...
public void gameResult() {
OnePlayerGameActivity gameActivity = new OnePlayerGameActivity();
TextView result = (TextView) gameActivity.findViewById(R.id.game_result_textView);
getPlayerChoice();
int computer = computerChoice();
if (mPlayerChoice == computer) {
mPlayerStat += 0;
mOpponentChoice += 0;
} else if (mPlayerChoice == 1) { //ROCK
switch (computer) {
case 1: //ROCK
break;
case 2: //PAPER
mOpponentStat ++;
result.setText("LOST");
break;
...
all code can be found on my GitHub
You are creating just a dummy instance of your activity which has no relation with the one in memory, instead pass the activity instance using
// in your OnePlayerGameActivity.java
// inside some method
GameLogic obj = new GameLogic (); // instance of GameLogic for demo
obj.gameResult(OnePlayerGameActivity.this); // pass instance
and change the methods signature as
public void gameResult(OnePlayerGameActivity gameActivity ) {
TextView result = (TextView) gameActivity.findViewById(R.id.game_result_textView);

How to make a random number only once in an android app?

I'm developing a "guess the number" app, it generates a random number between 1 and 10,000 and you have to try guessing, it will tell you if your prediction it is too big , etc
But when you press the button to probe your number, it generates a new random number every time you press the button.Keep in mind i'm a newbie so i'm learning java for android, but i want to know how to make this simple app.
Here's my code:
package com.boodle.guessthenumber;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void guess (View view){
EditText textguess = (EditText) findViewById ( R.id.textguess );
TextView resulta = (TextView) findViewById(R.id.resulto);
String guessStr = textguess.getText().toString();
int theGuess = Integer.parseInt(guessStr);
int rand = (int) (Math.random()*10000+1);
if (theGuess > rand) {
resulta.setText(textguess.getText() + " is too big" );
}
if (theGuess < rand) {
resulta.setText(textguess.getText() + " is too small" );
}
if (rand == theGuess){
resulta.setText(textguess.getText() + " is the answer" );
}
}
}
Create rand as a member variable in your class:
public class MainActivity extends ActionBarActivity {
int rand;
initialize in onCreate():
rand = (int) (Math.random()*10000+1);
remove the initialization in your guess() function:
// not needed anymore:
// int rand = (int) (Math.random()*10000+1);
To make the number persist during orientation changes, add this code to your Activity:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("rand", rand);
super.onSaveInstanceState(savedInstanceState);
}
and then in onCreate() change your random number generation code to this:
if (savedInstanceState != null)
rand = savedInstanceState.getInt("rand");
else
rand = (int) (Math.random()*10000+1);
After you generate the number you have to store it in a persistent storage, for which you have many options: SharedPreferences (which can be passed between activities), a file, SQLiteDatabase...
When the activity starts, only if the number is not there - generate it!
The solution would be to create your random number in onCreate such that it is only created once and then simply access that variable in your guess method. Modify your code as follows:
public class MainActivity extends ActionBarActivity
{
private int rand;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
rand = (int) (Math.random()*10000+1);
}
// rest of code...
And then in guess remove the initialization and simply access the variable by name:
public void guess (View view)
{
// rest of code...
//int rand = (int) (Math.random()*10000+1);
if (theGuess > rand) {
resulta.setText(textguess.getText() + " is too big" );
}
// rest of code...
}
Also, just as a note, it is not necessary to post all the import statements and other similar code. Only posting the code relevant to your issue is the best way to invite concise answers.
The following solution will generate the number when the activity is started and the number will NOT change when the user rotates the screen. It will also make the activity a little bit more effective.
public class MainActivity extends ActionBarActivity {
TextView mResult;
EditText mTextGuess;
private int mNumber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
// you find your views in onCreate once, they don't change, it's effective
mResult = (TextView) findViewById(R.id.resulto);
mTextGuess = (EditText) findViewById(R.id.textguess);
// BRO-TIP: Google "Butterknife".
// Now you need to initialize the random number
// BUT you want it to stay the same when user rotates the screen, right?
if (savedInstanceState == null) {
// when the user first opens the app, generate new number
mNumber = (int) (Math.random()*10000+1);
} else {
// otherwise load the previously generated number from saved state
mNumber = savedInstanceState.getInt("mNumber");
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// here you save the number across orientation changes
outState.putInt("mNumber", mNumber);
}
public void guess(View v) {
int theGuess = Integer.parseInt(mTextGuess.getText().toString());
// else-if is better for you: when the first is true, you don't need to check the others and so on...
if (theGuess > rand) {
mResult.setText(textguess.getText() + " is too big" );
} else if (theGuess < rand) {
mResult.setText(textguess.getText() + " is too small" );
} else if (rand == theGuess){
mResult.setText(textguess.getText() + " is the answer" );
}
}
}

Calling Method from other Java Class

My slot machine is still in progress. I am trying to get a method from one class to another but I can't figure it out. Could anyone please help me? Here is my first code which I wanted to call the method from the other class:
GameMainActivity:
package com.ics136leeward.slotmachine;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ViewFlipper;
public class GameMainActivity extends Activity {
ViewFlipper slotOne, slotTwo, slotThree, spinStop;
Button spin, stop, bet;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_main);
this.initSpin();
this.initStop();
}
private void initSpin() { //initialize Spin Method
spin = (Button) findViewById (R.id.spinBtn);
slotOne = (ViewFlipper) findViewById (R.id.slot1);
slotTwo = (ViewFlipper) findViewById (R.id.slot2);
slotThree = (ViewFlipper) findViewById (R.id.slot3);
spinStop = (ViewFlipper) findViewById (R.id.spinstopbutton);
spin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
slotOne.setFlipInterval(40);
slotOne.startFlipping(); //slot 1 spin
slotTwo.setFlipInterval(50);
slotTwo.startFlipping(); //slot 2 spin
slotThree.setFlipInterval(60);
slotThree.startFlipping(); //slot 3 spin
spinStop.showNext(); // shows the stop button
}
});
}
private void initStop() { //initialize Stop Method
stop = (Button) findViewById (R.id.stopBtn);
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
slotOne.stopFlipping(); //stops slot 1
slotTwo.stopFlipping(); //stops slot 2
slotThree.stopFlipping(); //stops slot 3
spinStop.showNext(); //shows the spin button again
if(slotOne == slotTwo || slotTwo == slotThree) {
}
}
});
}
}
Here is the second java class which I wanted to call the method getBet1() and getBet5() to the first activity:
Bet:
package com.ics136leeward.slotmachine;
import android.app.Activity;
import android.widget.TextView;
public class Bet extends Activity {
TextView userBet, bankRoll, event;
final int BETONE = 1, BETFIVE = 5;
int uBet = 100, bet;
public void getBet1() {
userBet = (TextView) findViewById (R.id.userBet);
bankRoll = (TextView) findViewById (R.id.bankroll);
uBet -= BETONE;
bet += BETONE;
userBet.setText("Your Bet: " + bet);
bankRoll.setText("" + uBet);
return;
}
public void getBet5() {
userBet = (TextView) findViewById (R.id.userBet);
bankRoll = (TextView) findViewById (R.id.bankroll);
uBet -= BETFIVE;
bet += BETFIVE;
userBet.setText("Your Bet: " + bet);
bankRoll.setText("" + uBet);
return;
}
}
You need to make a Utility class not a Activity class
So change
public class Bet extends Activity {
to
public class Bet // Normal java class
Since its not a Activity class there is not need to initialize views
userBet = (TextView) findViewById (R.id.userBet); //remove them
// Initialize all yours views in Activity
Now in Activity class
Bet bet = new Bet();
int value =bet.getBet1();
In getBet1() do you calculations an return values.
Then in Activity you can set the value to TextView
textView.setText(String.valueOf(value));
Do also check raghav's answer #
Can i Create the object of a activity in other class?
you can define those method static and then call by its class name like
Bet.getBet1();
Bet.getBet5();
or simply you can create class object and then call it
Bet b = new Bet();
b.getBet1()
Note: You don't need to extend to Activity class as you are not using any UI. (Already suggested by Raghunandan)
Try this code in the onCreate method of your calling class i.e. GameMainActivity
Bet bet= new Bet(); // where bet is object of Bet Class
bet.getBet1();
bet.getBet5();
However, You can create the object of Bet class in any method and access the class methods provided their access modifier must be public.

NullPointerException after changing class ( Code worked before )

I'm doing basic calculator for Android in Java. My calculator worked but i had all code in one class. Then i wanted to make code more readable and i created another Calculation class and i put calculation code in there. And now for some reason my app crashes. LogCat says: NullPointerException. (My app starts fine and then when i choose desirable currency to convert and when i click on ImageButton(convert) then app crashes). Here is my code:
CroToEu class:
package com.eu.calculator;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
public class CroToEur extends Activity {
TextView resultView;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.cro_to_eur);
final ImageButton convert = (ImageButton) findViewById(R.id.converButton);
convertButton(convert);
}
private void convertButton(final ImageButton convert) {
resultView = (TextView) findViewById(R.id.resultView);
convert.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Calculate now = new Calculate();
now.croToEu();
if(event.getAction() == MotionEvent.ACTION_DOWN) {
convert.setImageResource(R.drawable.convert_button_ontouch);
checkForEmptyEntry();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
convert.setImageResource(R.drawable.convert_button);
}
return false;
}
private void checkForEmptyEntry() {
if(Calculate.HRKfield.getText() == null || "".equals(Calculate.HRKfield.getText().toString())) {
resultView.setText("You left empty field");
} else {
resultView.setText(Calculate.HRKfield.getText()+" HRK = "+Calculate.fixDecimal+" EUR");
}
}
});
}
}
And my calculation class:
package com.eu.calculator;
import java.math.BigDecimal;
import android.app.Activity;
import android.widget.EditText;
public class Calculate extends Activity {
public static EditText HRKfield; //S tem dobimo vrednost iz polja edittext
public static double EUR = 0.133;//drži vrednost
public static Double HRK; // Možnost uporabe double za parsing
public static double result; // rezultat
public static BigDecimal fixDecimal; // rezultat pretvori na decimalko
public BigDecimal croToEu() {
HRKfield = (EditText) findViewById(R.id.enterField);
try {
HRK = Double.parseDouble(HRKfield.getText().toString()); //tukaj dobimo čisto številko, ki jo uporabnik vnese v polje
result = HRK * EUR;
fixDecimal = new BigDecimal(result);
fixDecimal = fixDecimal.setScale(2, BigDecimal.ROUND_HALF_UP);
} catch (NumberFormatException e) {
}
return fixDecimal;
}
}
Don' t extend Calculate class with Activity . Remove extends Activity in Calculate class
If you are trying to just create a helper class whcih does the calculation for you then don't extend Activity on your Calculate class. Instead get your croToEu method to return a variable and call this from the other class as follows.
Calculate now = new Calculate();
BigDecimal val = now.croToEu();
Id actually have the caluclate class as follows
public abstract class Calculate {
public static final double EUR = 0.133;//drži vrednost
public static BigDecimal croToEu(double hrkValue) {
BigDecimal fixDecimal = new BigDecimal(hrkValue * EUR);
fixDecimal = fixDecimal.setScale(2, BigDecimal.ROUND_HALF_UP);
return fixDecimal;
}
}
Then in your main activity class call
BigDecimal val = Calculate.croToEu(hrkValue);
if(Calculate.HRKfield.getText() == null || "
this is wrong to get the view of other activity .........
you are in CroToEur and your acessing the HRKfield of Calculate activity which will be null
So should pass the data from CroToEur activity to Calculate activity using intent and set that in HRKfield in onCreate of CroToEur
You are missing your onCreate() method and even setContentView in Calculate.class and so it cannot find your edittext HRKfield, and so it is throwing NullpointerException

Categories

Resources