How do I switch between two views being visible? - java

I am making an application that helps score a table tennis game. I am at the final stages but I am having trouble with switching the server around every two points. I have given it a lot of thought but I can only get it to switch once. I know it is probably an easy solution but it's just not coming to me.
Here's how I am switching it once. I am using a count each time the button is pressed and when it reaches a number divisible by 2 it switches to the right.. However, using this logic is making it difficult to switch back! Thanks in advance.
public void serveSwitch() {
TextView leftServe = findViewById(R.id.leftServe);
TextView rightServe = findViewById(R.id.rightServe);
serverCount++;
if (server.serve=="left") {
if (serverCount % 2 == 0) {
rightServe.setVisibility(View.VISIBLE);
leftServe.setVisibility(View.GONE);
}
}

The part I'm struggling with is the logic on how to switch visibility every two points
If I get your point right, you want to toggle the visibility from off to on every two points and vice versa
You can do something like:
...
if (server.serve=="left") {
if (serverCount % 2 == 0) {
switch (rightServe.getVisibility()) {
case View.GONE:
rightServe.setVisibility(View.VISIBLE);
break;
case View.VISIBLE:
rightServe.setVisibility(View.GONE);
break;
}
switch (leftServe.getVisibility()) {
case View.GONE:
leftServe.setVisibility(View.VISIBLE);
break;
case View.VISIBLE:
leftServe.setVisibility(View.GONE);
break;
}
}
}
Note: I left the equality as-is as you say there is no problem with it. but in general you should use .equals() when it comes to compare strings in java.

Related

Switch-case uses same case repeatedly after first choice, how do I reset or flush it before use to work correctly?

Switch-case runs properly the first time but continues using the same initial choice over and over again. I need it to reset before this block of code runs so it chooses a different (or same) case when needed.
This is for a school project where a fox chases a rabbit. I must code the rabbit. I have the switch-case developed so as to use it's proximity to a bush as the argument that is switched on. This determines what the rabbit will do. It works properly the first time but continues with the same case after it moves and the previous case runs again on the rabbits next turn. After some research I found that I should wrap it up in a do-while statment with some flags to exit the loop and I did but the same problem continues.
if (noMansLand == false) {
needDirection = true;
do{
switch (directionToBush) {
//N-------------------------------------------------------
case 0:
if (look(7) == Model.BUSH) {
if (distance(7) == 1) {
currentDirection = 6;
if (look(6) == Model.BUSH) {
if (distance(6) == 1) {
currentDirection = 5;
}
}
}
} else {
//WANTED DIRECTION
currentDirection = 7;
}
//FOX ESCAPE PLAN
//code...
needDirection = false;
return currentDirection;
//E-------------------------------------------------------
case 2:
//similar code...
//S--------------------------------------------------------
case 4:
//similar code...
//W--------------------------------------------------------
case 6:
//similar code...
}while(needDirection == true);
}
There is ALOT more code and will happily show whole thing for help. The game works on an grid interface where the fox and rabbit take turns "looking" and moving by one grid in 1 of 6 directions (I only show 4 cardinal in my snip of the switch code). I have my rabbit look for the nearest bush to get fox to chase it around until max turns elapses. The rabbit gets to closest bush fine and upon reaching 1 distance from bush turns "noMansLand" to false and initiates switch-case block. The first turn of this works exactly as written and rabbit moves in correct direction but on the rabbits next turn it continues with the same case as if the bush is in the same direction it was last turn before moving. I'm assuming it is storing the old direction with the switch case but I do not know how to reset or flush this data.
switch (directionToBush) {
directionToBush is 0?
where is it changed? Not in your snippet!
If it is not changed it stays 0 in all loop iterations.
It would help if you can show where the switch case variable 'directionToBush' is being initialized and how it is being changed in the switch case. As long as you keep changing this variable basing on the cases, you should be fine. There no need to reset anything. Good luck!

Android Studio if statement with OR (||) Function

I am creating a mobile application that updates users with the current score and final score in a football match. I want the textview displaying the score to show only the current or final score.
I am having trouble with the if statement. I need one of the fields to contains something in order for a record to be created so I have:
if (!(et_currentgoals.getText().toString().isEmpty()) || !(et_finalgoals.getText().toString().isEmpty()){
}
Inside this if statement I was another that updates the textview with the correct values. So if the final number of goals was entered, the current goals are discarded. Would the best way be something like this:
if(!(et_finalgoals.getText().toString.isEmpty()){
tv_goals.setText(et_finalgoals.getText().toString();
}else{
tv_goals.setText(et_currentgoals.getText().toString();
}
Does this cover both scenarios or am I missing something?
Having that second if block inside the first will work, but there's a simpler way.
This single if will work.
if (!et_finalgoals.getText().toString.isEmpty()) {
tv_goals.setText(et_finalgoals.getText().toString();
} else if (!et_currentgoals.getText().toString.isEmpty()) {
tv_goals.setText(et_currentgoals.getText().toString();
}
In other words, these two blocks are equivalent
if (a || b) {
if (a) {
// a
} else {
// b
}
}
if (a) {
// a
} else if (b) {
// b
}
If I'm understanding correctly, you are executing additional code inside of that first if statement, after setting the tv_goals text. To do that now, you can just check the text of tv_goals.
if (!tv_goals.getText().toString.isEmpty()) {
// Do additional code
}
If this is the case, it ends up being the same amount of code as your original solution. You should just pick whichever way is more clear to you.

Multiple classes with Mouse.next()

As the title already shows I have an issue with the function "Mouse.next()".
I'm programming my own buttons at the moment and for that I have to check, if the left mouse-button was pressed. I thought, that I can do it so:
while(Mouse.next()) {
if(Mouse.getEventButtonState() && Mouse.getEventButton() == 0) {
// some code..
}
}
This also works, if I only have one instance of my button. But if I add another instance the while loop never gets called for the second (last created) button...
Does somebody have any idea, why this could happen?...
And also what do these functions (found them on the internet) Mouse.getEventButtonState(), Mouse.getEventButton() == 0 and Mouse.isButtonDown(0)
Mouse is from org.lwjgl.input.Mouse
With another instance I mean something like: MyButton button = new MyButton();
EDIT:
My Question is: How can I get Mouse.next() to work with multiple instances of the surrounding class...
Because Mouse is a Singleton . As long as it is Singleton calling next will consume the Event. You can not consume the same event two times! When first object calls next() it consumes it and when the second calls next() the is no second click to consume.
The issue is that getEventButton() returns a different number depending on which button was pressed. What you should do instead is something like:
while (Mouse.next()) {
if (Mouse.getEventButtonState()) {
int buttonId = Mouse.getEventButton();
switch (buttonId) {
case -1: break; // no button was clicked
case 0:
// code for first button
break;
case 1:
// code for second button
break;
}
}
}

How to execute code based on integer value

I have an int, int minion1Hp, which can be a value of 0 -> 20. Depending on the value it is, a certain image resource will be set for an ImageView, using bar1.setImageResource(R.drawable.hpa);. However, my code currently looks like this:
if (minion1Hp == 0) {
bar1.setImageResource(R.drawable.hp);
}
if (minion1Hp == 1) {
bar1.setImageResource(R.drawable.hpa);
}
if (minion1Hp == 2) {
bar1.setImageResource(R.drawable.hpb);
}
if (minion1Hp == 3) {
bar1.setImageResource(R.drawable.hpc);
}
if (minion1Hp == 4) {
bar1.setImageResource(R.drawable.hpd);
}
if (minion1Hp == 5) {
bar1.setImageResource(R.drawable.hpe);
}
... and so on. Is there a more efficient way of doing this, rather than a long list of if statements?
Suggestion: initialize a map at startup (say in onCreate()). Like this:
mDrawables = new HashMap<Integer, Integer>();
mDrawables.put(0, R.drawable.hp);
mDrawables.put(1, R.drawable.hpa);
...
then just do:
bar1.setImageResource(mDrawables.get(minion1Hp));
You can use a switch statement with a separate case for each instance. On a side note, you shouldn't be using just if statements up there, your code will run slowly, you should be using else if to make it run faster (since your hp can never be 1 and 2 at the same time.
Ex for switch statements:
switch (minion1Hp){
case 1:
bar1.setImageResource(R.drawable.hp);
break;
case 2:
bar1.setImageResource(R.drawable.hpa);
break;
etc.
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
An improvement here would be to change each if after the first one to an else if as minion1Hp can't be multiple values at the same time, but you might find it slightly neater to have the whole thing in a switch-case block instead.

Why switch is faster than if

Lots of Java books describe the switch statement as being faster than the if else statement. But I did not find out anywhere why switch is faster than if.
Example
I have a situation I have to choose any one item out of two. I can use either use
switch (item) {
case BREAD:
//eat Bread
break;
default:
//leave the restaurant
}
or
if (item == BREAD) {
//eat Bread
} else {
//leave the restaurant
}
considering item and BREAD is a constant int value.
In the above example which is faster in action and why?
Because there are special bytecodes that allow efficient switch statement evaluation when there are a lot of cases.
If implemented with IF-statements you would have a check, a jump to the next clause, a check, a jump to the next clause and so on. With switch the JVM loads the value to compare and iterates through the value table to find a match, which is faster in most cases.
A switch statement is not always faster than an if statement. It scales better than a long list of if-else statements as switch can perform a lookup based on all the values. However, for a short condition it won't be any faster and could be slower.
The current JVM has two kinds of switch byte codes: LookupSwitch and TableSwitch.
Each case in a switch statement has an integer offset, if these offsets are contiguous (or mostly contiguous with no large gaps) (case 0: case 1: case 2, etc.), then TableSwitch is used.
If the offsets are spread out with large gaps (case 0: case 400: case 93748:, etc.), then LookupSwitch is used.
The difference, in short, is that TableSwitch is done in constant time because each value within the range of possible values is given a specific byte-code offset. Thus, when you give the statement an offset of 3, it knows to jump ahead 3 to find the correct branch.
Lookup switch uses a binary search to find the correct code branch. This runs in O(log n) time, which is still good, but not the best.
For more information on this, see here: Difference between JVM's LookupSwitch and TableSwitch?
So as far as which one is fastest, use this approach:
If you have 3 or more cases whose values are consecutive or nearly consecutive, always use a switch.
If you have 2 cases, use an if statement.
For any other situation, switch is most likely faster, but it's not guaranteed, since the binary-search in LookupSwitch could hit a bad scenario.
Also, keep in mind that the JVM will run JIT optimizations on if statements that will try to place the hottest branch first in the code. This is called "Branch Prediction". For more information on this, see here: https://dzone.com/articles/branch-prediction-in-java
Your experiences may vary. I don't know that the JVM doesn't run a similar optimization on LookupSwitch, but I've learned to trust the JIT optimizations and not try to outsmart the compiler.
So if you plan to have loads of packets memory isn't really a large cost these days and arrays are pretty fast. You also cannot rely on a switch statement to auto generate a jump table and as such it's easier to generate the jump table scenario yourself. As you can see in below example we assume a maximum of 255
packets.
To get the below result your need abstraction.. i'm not going to explain how that works so hopefully you have an understanding of that.
I updated this to set the packet size to 255 if you need more then that you'll have to do a bounds check for (id < 0) || (id > length).
Packets[] packets = new Packets[255];
static {
packets[0] = new Login(6);
packets[2] = new Logout(8);
packets[4] = new GetMessage(1);
packets[8] = new AddFriend(0);
packets[11] = new JoinGroupChat(7); // etc... not going to finish.
}
public void handlePacket(IncomingData data)
{
int id = data.readByte() & 0xFF; //Secure value to 0-255.
if (packet[id] == null)
return; //Leave if packet is unhandled.
packets[id].execute(data);
}
Edit since I use a Jump Table in C++ a lot now i'll show an example of a function pointer jump table. This is a very generic example, but I did run it and it works correctly. Keep in mind you must set the pointer to NULL, C++ will not do this automatically like in Java.
#include <iostream>
struct Packet
{
void(*execute)() = NULL;
};
Packet incoming_packet[255];
uint8_t test_value = 0;
void A()
{
std::cout << "I'm the 1st test.\n";
}
void B()
{
std::cout << "I'm the 2nd test.\n";
}
void Empty()
{
}
void Update()
{
if (incoming_packet[test_value].execute == NULL)
return;
incoming_packet[test_value].execute();
}
void InitializePackets()
{
incoming_packet[0].execute = A;
incoming_packet[2].execute = B;
incoming_packet[6].execute = A;
incoming_packet[9].execute = Empty;
}
int main()
{
InitializePackets();
for (int i = 0; i < 512; ++i)
{
Update();
++test_value;
}
system("pause");
return 0;
}
Also another point i'd like to bring up is the famous Divide and Conquer. So my above 255 array idea could be reduced to no more then 8 if statements as a worst case scenario.
I.e. but keep in mind it get's messy and hard to manage fast and my other approach is generally better, but this is utilize in cases where arrays just won't cut it. You have to figure out your use case and when each situation works best. Just as you wouldn't want to use either of these approaches if you only have a few checks.
If (Value >= 128)
{
if (Value >= 192)
{
if (Value >= 224)
{
if (Value >= 240)
{
if (Value >= 248)
{
if (Value >= 252)
{
if (Value >= 254)
{
if (value == 255)
{
} else {
}
}
}
}
}
}
}
}
At the bytecode level, subject variable is loaded only once into processor register from a memory address in the structured .class file loaded by Runtime,and this is in a switch statement; whereas in an if-statement, a different jvm instruction is produced by your code-compiling DE, and this requires that each variable be loaded in to registers although same variable is used as in next preceeding if-statement. If you know of coding in assembly language then this would be commonplace; although java compiled coxes are not bytecode, or direct machine code, the conditional concept hereof is still consistent.
Well, I tried to avoid deeper technicality upon explaining. I hope I had made the concept clear and demystified. Thank you.

Categories