I have 8 pairs of buttons (16 total), with some terms from sqlite database. I need when user connect 8 pair (correct or wrong, it does not matter) to end the game, with some popup on the end. When I place counter<7 in my code, i need to connect 8 pairs plus to click once more on some buttons (17 clicks). If I enter counter<6, then I get my popup after 7 pair and one more click(15 click). I don't get that logic. So here's the code:
final OnClickListener clickListener = new OnClickListener() {
private Button buttonClicked;
public void onClick(View v) {
if (counter < 7) {
Button button = (Button) v;
button.getBackground()
.setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0x003333));
if (buttonClicked == null) {
// first button is clicked
buttonClicked = button;
// only do stuff if buttons are in different layouts
} else {
if (!button.getParent().equals(buttonClicked.getParent())) {
// second button is clicked
if (buttonClicked.getTag().equals(button.getTag())) {
// second button is clicked and same tag but different button
Toast.makeText(Spojnice.this, "Correct", Toast.LENGTH_SHORT).show();
button.getBackground()
.setColorFilter(new LightingColorFilter(0xFFFFFFFF, 0x66FF33));
buttonClicked.getBackground().setColorFilter(
new LightingColorFilter(0xFFFFFFFF, 0x66FF33));
buttonClicked.setEnabled(false);
button.setEnabled(false);
buttonClicked = null;
score.setText("Poeni: " + brojPoenaSpojnice);
counter++;
} else {
counter++;
//reset LightingColorFilter first
button.setEnabled(false);
Toast.makeText(Spojnice.this, "Wrong", Toast.LENGTH_SHORT).show();
buttonClicked = null;
}
} else {
//same button clicked show message or un toggle?
buttonClicked = button;
}
}
} else {
Intent i = new Intent(Spojnice.this, Popup_spojnice.class);
startActivity(i);
mHandler.postDelayed(mLaunchTask, 6500);
}
}
};
Since you first check for the counter, and just then increment it, after connecting 7 pairs your counter will be 6 (still <7). Next time you increment the counter it will be 7, and your first condition will be false, but it will only be checked again in the next round.
To solve it, you should check the condition (if (counter < 7)) after incrementing the counter, and not before.
Related
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed last year.
I would like to create an alarm where user have to play in mini game to turn off the sound. So minigame should rand 1 from 0 to 100 which should be picked from 9 buttons with numbers. And this should happen 10 times. If the user click bad button, then it should start again 10 times. In every iteration I would like to change number to select, and numbers on buttons.
To do this I created an array from buttons:
Button[] buttons = {
button1,
button2,
button3,
button4,
button5,
button6,
button7,
button8,
button9
};
private int i = 0;
And on onCreateView I am trying to assign values to this buttons:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_numbers_game, container, false);
buttons[0] = view.findViewById(R.id.button1);
buttons[1] = view.findViewById(R.id.button2);
buttons[2] = view.findViewById(R.id.button3);
buttons[3] = view.findViewById(R.id.button4);
buttons[4] = view.findViewById(R.id.button5);
buttons[5] = view.findViewById(R.id.button6);
buttons[6] = view.findViewById(R.id.button7);
buttons[7] = view.findViewById(R.id.button8);
buttons[8] = view.findViewById(R.id.button9);
randomNumber = view.findViewById(R.id.randomNumber);
displayNumbers();//assign values at the start
for (i=0;i<9;i++){
buttons[i].setOnClickListener(v -> {
if (Integer.parseInt(buttons[i].getText().toString()) == intRandomNumber) {//sometimes I get there ArrayIndexOutOfBoundsException
winIterator++;
Log.d("numbersGame", "correct " + intRandomNumber);
Toast.makeText(getActivity(), R.string.correctAnswer, Toast.LENGTH_SHORT).show();
if (winIterator == 10) {
Bundle result = new Bundle();
result.putBoolean("isFinished", true);
getParentFragmentManager().setFragmentResult("requestKey", result);
}
} else {
winIterator = 0;
Log.d("numbersGame", "incorrect " + intRandomNumber);
Toast.makeText(getActivity(), R.string.incorrectAnswer, Toast.LENGTH_SHORT).show();
}
displayNumbers();
});
}
return view;
}
randomNumber is a textView to display random number. I am trying to attach for every button listener that if the text in this button will equals random number, then counter will increase by 1. And if the counter equal 10, then it will turn off the alarm. In other case it should assign 0 to winiterator. And for every clicked at the end, display numbers to assign new values to buttons, this function is below.
public void displayNumbers() {
intRandomNumber = random.nextInt(100) + 1;//number which should be selected
randomNumberButtonIndex = random.nextInt(9);//index number in buttons
String stringRandomNumber = String.valueOf(intRandomNumber) + "";
randomNumber.setText(stringRandomNumber);
buttons[randomNumberButtonIndex].setText(stringRandomNumber);
for (int i = 0; i < 9; i++) {
if (i == randomNumberButtonIndex) {
continue;
}
do {
randomOtherNumber = random.nextInt(100) + 1;
} while (randomOtherNumber == intRandomNumber);
buttons[i].setText(Integer.toString(randomOtherNumber));//random and assign other values
}
}
Sometimes I get in the described place:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.budzikinteraktywny, PID: 9319
java.lang.ArrayIndexOutOfBoundsException: length=9; index=9
at com.example.budzikinteraktywny.NumbersGameFragment.lambda$onCreateView$0$com-example-budzikinteraktywny-NumbersGameFragment(NumbersGameFragment.java:89)
at com.example.budzikinteraktywny.NumbersGameFragment$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
at android.view.View.performClick(View.java:7870)
at android.widget.TextView.performClick(TextView.java:14970)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7839)
at android.view.View.access$3600(View.java:886)
at android.view.View$PerformClick.run(View.java:29363)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7948)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
But checked a lot of times and I cant see this place where something gone wrong.
Any help is appreciated. Thank you
Since you hold your i parameter as a class member and incrementing it in the for loop, The last value it is set to is 9 (and then the loop condition is false (i < 9).
When the onClick occurs, you are calling:
Integer.parseInt(buttons[i].getText().toString());
Then you are out of bounds, because:
buttons[9]
Is incorrect.
Try to use this:
for (i=0;i<9;i++){
final Button button = buttons[i];
button.setOnClickListener(v -> {
if (Integer.parseInt(button.getText().toString()) == intRandomNumber) {
.. The rest of your code
}
}
}
For my code, I had a really weird bug.
Everytime I press the Search Button, the result always different.
This is my dummy database.
I have 4 columns and 3 rows in the table :
001 Viagra 1 APL
002 Diane 2 SBF
003 Santibi 3 BSP
The first time I pressed the Search Button, the data inside table didn't change at all.
This is the screenshot of my program.
This is what happened if I pressed the Search Button the second time (the result is correct)
The third time I pressed the button, it shows an incorrect result
If I pressed the button continuously, the result keep changing back and fort from correct to incorrect one.
This is my code :`
public void searchPerformed() {
if (tSearch.getText().toString() == sch) { return; }
sch = tSearch.getText().toString();
int iColumn = cbSearch.getSelectedIndex();
TableRowSorter<TableModel> sorter = new TableRowSorter<>(model);
tbl.setRowSorter(sorter);
if (tSearch.getText().length() > 0) {
sorter.setRowFilter(RowFilter.regexFilter("(?i)" + tSearch.getText(), iColumn));
} else {
sorter.setRowFilter(null);
}
if (tbl.getRowCount() != 0) { tbl.setRowSelectionInterval(0, 0); }
else { clearText(); }
}
private void tSearchKeyPressed(java.awt.event.KeyEvent evt) {
if (evt.getKeyCode() != KeyEvent.VK_ENTER) { return; }
searchPerformed();
}
private void tSearchKeyPressed(java.awt.event.KeyEvent evt) {
if (evt.getKeyCode() != KeyEvent.VK_ENTER) { return; }
searchPerformed();
}
in here i had a lot of button that randomly turn to visible
bt1 = (Button)findViewById(R.id.yellow1);
bt2 = (Button)findViewById(R.id.yellow2);
bt3 = (Button)findViewById(R.id.yellow3);
bt4 = (Button)findViewById(R.id.yellow4);
bt5 = (Button)findViewById(R.id.yellow5);
bt6 = (Button)findViewById(R.id.yellow6);
bt7 = (Button)findViewById(R.id.yellow7);
bt8 = (Button)findViewById(R.id.yellow8);
bt9 = (Button)findViewById(R.id.yellow9);
bt10 = (Button)findViewById(R.id.yellow10);
bt11 = (Button)findViewById(R.id.yellow11);
bt12 = (Button)findViewById(R.id.yellow12);
bt13 = (Button)findViewById(R.id.yellow13);
bt14 = (Button)findViewById(R.id.yellow14);
bt15 = (Button)findViewById(R.id.yellow15);
bt16 = (Button)findViewById(R.id.yellow16);
Button[] buttons = new Button[]{ bt1, bt2, bt3, bt4, bt5, bt6, bt7, bt8,
bt9, bt10, bt11, bt12, bt13, bt14, bt15, bt16 };
Random generator = new Random();
number = generator.nextInt(16);
for( int i=0; i<buttons.length; i++ )
{
if( i == number )
buttons[i].setVisibility( View.VISIBLE );
else
buttons[i].setVisibility( View.INVISIBLE );
}
button is randomly visible, if one turn to visible another one will be invisible. and of course a method if button was "click" to that visible button
if(click==bt1|| click==bt2|| click==bt3|| click==bt4 || click==bt5|| click==bt6|| click==bt7 || click==bt8||
click==bt9|| click==bt10 || click==bt11|| click==bt12|| click==bt13 || click==bt14|| click==bt15|| click==bt16){
//will do something
}
}
but i want to make a method if button "not click" when it is visible, so when button not clicked he will do some code.
i mean is like this
//just example
if button not clicked(click==bt1|| click==bt2|| click==bt3|| click==bt4 || click==bt5|| click==bt6|| click==bt7 || click==bt8||
click==bt9|| click==bt10 || click==bt11|| click==bt12|| click==bt13 || click==bt14|| click==bt15|| click==bt16){
//so do something
}
}
Can anyone teach me how to do that with some code?
NOTE:
Sorry i forget to write some part of the code, it is left on my computer!
So i just can give example like this:
Every 1second the button is randomly set to visible, so every 1second there is randomly button set to visible and the button that visible 1second before will be invisible
Check out this
Handler visibilityToggler = new Handler();
Runnable visivilityRunnable = new Runnable() {
#Override
public void run() {
// isUserClickedButton is used to keep record if user has pressed button within 1 sec
// keep isUserClickedButton = true for first time as it will run
if (!isUserClickedButton) {
// user not pressed button
Toast.makeText(context,"You are not pressed the Button",Toast.LENGHT_LONG).show();
}
// toggle visibility
Random generator = new Random();
number = generator.nextInt(16);
for (int i = 0; i < buttons.length; i++) {
if (i == number)
buttons[i].setVisibility(View.VISIBLE);
else
buttons[i].setVisibility(View.INVISIBLE);
}
// again start the visibility
visibilityToggler.postDelayed(visivilityRunnable,1000);
// make it false as visibility is toggled and we want to track button pressed from start
isUserClickedButton = false;
}
};
visibilityToggler.postDelayed(visivilityRunnable,1000);
Onclick handling if user pressed button
if (click == bt1 || click == bt2 || click == bt3 || click == bt4 || click == bt5 || click == bt6 || click == bt7 || click == bt8 ||
click == bt9 || click == bt10 || click == bt11 || click == bt12 || click == bt13 || click == bt14 || click == bt15 || click == bt16) {
//will do something
// make it true as user is pressed button and we don't want to run condition of not pressed after 1 sec
isUserClickedButton = true;
}
}
b1.setOnClickListener(new View.OnClickListener()
{
Button[] s=new Button[]{bt1, bt2, bt3, bt4, bt5, bt6, bt7, bt8,
bt9, bt10, bt11, bt12, bt13, bt14, bt15, bt16};
Random generator = new Random();
int number = generator.nextInt(16);
#Override
public void onClick(View v) {
for( int i=0; i<s.length; i++ )
{
if( i == number )
s[i].setVisibility(View.VISIBLE);
else
s[i].setVisibility(View.INVISIBLE);
}
}
});
you can define a Boolean value and use onclicklistener for your button, then if user clicks the button the Boolean value will be false and he cannot write code. It's a flag.
I am using a menu option to set the time for a game. By default the time is set to 10 seconds. The user can set the time by clicking on the menu and then selecting a choice. I am using a custom view, so the method for changing the time is in a different class than the view.
When the user clicks on the menu option a dialog appears with a EditText as its view. The user enter a number between 5 and 60. I have to wait an entire game cycle for the time to change, so it should change on the next game..
but it does not..
It will only change if I try and change the time again.
Ex)
I change the time to 5 seconds the first time I play, expecting it to change to 5 seconds the next game cycle. In the next game cycle it does not change to 5. It will stay at the previous time. I change the time again to 30 seconds. Next game cycle, the timer now appears to have 5 seconds. If I change the time again to 40, it will appear 30.
This is where I am changing the time, on each newgame();
static int timeRemaining = 10;
public void newGame() {
timeLeft = timeRemaining; // start the countdown
// do other stuff
This is where I ask the user for input, and change the variable timeRemaining. Keep in mind they are in different classes.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
AlertDialog.Builder dialog;
dialog = new AlertDialog.Builder(this);
final EditText input = new EditText(this);
dialog.setTitle("Enter the time limit");
dialog.setView(input);
dialog.setPositiveButton("Done", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
getInput = input.getText().toString();
try{
result = Integer.parseInt(getInput);
}catch(InputMismatchException e){
CannonView.timeRemaining = 10;
Toast.makeText((Context) getApplicationContext(), "Enter an integer", Toast.LENGTH_SHORT).show();
}
if(result < 5){
Toast.makeText((Context) getApplicationContext(), "Invalid input", Toast.LENGTH_SHORT).show();
} else if (result > 60) {
Toast.makeText((Context) getApplicationContext(), "Invalid input", Toast.LENGTH_SHORT).show();
}
Toast.makeText((Context) getApplicationContext(), "Time set changed next game", Toast.LENGTH_SHORT).show();
}
});
AlertDialog box = dialog.create();
box.show();
if(result < 5 || result > 60){
CannonView.timeRemaining = 10;
return true;
}else{
CannonView.timeRemaining = result;
return true;
}
}
return super.onOptionsItemSelected(item);
}
I change the timeRemaining here, but it does not update until I change it again. Any suggestions?
I think the error is you do not put the follwing in the onClickListener
if(result < 5 || result > 60)
CannonView.timeRemaining = 10;
else CannonView.timeRemaining = result;
It should be like this
dialog.setPositiveButton("Done", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// your original code
if(result < 5 || result > 60)
CannonView.timeRemaining = 10;
else CannonView.timeRemaining = result;
});
I have a textview and 3 button with textview.append("1"); textview.append("2"); textview.append("3"); command,
and another button, button4, with empty command.
My question is how can I check if the first character typed in textview is 1 when button4 pressed?
For example:
public void button4 (View v)
{
if (first character in textview == 1)
{
textview.setText("xxx");
}
else if (first character in textview == 2)
{
textview.setText("yyy");
}
else
{
texteview.setText("zzz");
}
}
I'm fairly certain this will work:
textview.getText().charAt(0)