I was wondering if it would be possible to make the code below any smaller, basically its if else statement and each time only 3 things are changing and I was think I am just repeating my self, so I though if there is any way to make it any smaller.
if (text1.getText == "1" && text2.text == "2"){
text3.setText("3");
}
else if(text3.getText == "1" && text4.text == "2"){
text7.setText("3");
}
else if(text5.getText == "1" && text6.text == "2"){
text4.setText("3");
}
else if(text7.getText == "1" && text8.text == "2"){
text5.setText("3");
}
else if(text9.getText == "1" && text10.text == "2"){
text6.setText("3");
}
else if(text11.getText == "1" && text12.text == "2"){
text2.setText("3");
}
else if(text13.getText == "1" && text14.text == "2"){
text14.setText("3");
}
......
else{
Statement here
}
boolean didIt = false;
ArrayList<JTextField[]> listOfStuff = new ArrayList<JTextField[]>();
listOfStuff.add({ text1, text2, text3 });
listOfStuff.add({ text3, text4, text7 });
....
listOfStuff.add({ text13, text44, text14 });
for (JTextField[] fields : listOfStuff) {
didIt = didIt || setToThree(fields[2], fields[0], fields[1]);
}
if (!didIt) {
Statement here
}
Function:
boolean setToThree(JTextField target, JTextField first, JTextField second) {
if ("1".equals(first.getText()) && "2".equals(second.getText()) {
target.setText("3");
return true;
}
return false;
}
The pattern looks like for every pair of textN and textN+1, you set some other textM to 3 if the two aforementioned are labelled 1 and 2 respectively. I don't see the pattern connecting pairs to their target texts, so I suggest this:
Assuming these text variables are of the type Text, store them using one of the following:
Text[] texts = new Text[N];
ArrayList<Text> texts = new ArrayList<Text>();
Put all of your Text instances in the array or ArrayList
Set up a map or method that takes the odd number of some pair of consecutive Texts and returns the target Text to modify (look up HashMap)
Use a for loop to iterate through every other Text instance
Here's an example, if you're using an array and some method findTarget:
for (int i = 0; i+1 < texts.length; i+=2) {
if texts[i].getText().equals("1") && texts[i+1].getText().equals("2") {
texts[findTarget(i)].setText("3");
break;
}
}
You can create a function to do that.
function CheckValues (a, b, c){
if (a.getText().equals("1") && (b.getText().equals("2")){
c.setText("3");
}
}
And then run it with:
CheckValues(text1,text2,text3);
CheckValues(text3,text4,text7);
CheckValues(text5,text6,text11);
Related
Could you please help me find a solution for my code? I'm making a new Android app in which I need to make some calculations and the scenario is the following:
There are four fields to be calculated. Two EditText (number decimal) field are obligatory and the other two are optional, BUT, if the optional fields are filled, then it needs to be in the calculation, otherwise only the obligatory fields will be used.
Right now I'm totally OK with calculating the obligatory fields but when I try some if-else clause to include the optional fields in the calculation, the app goes bananas.
I'm not sure where I should make this two-step option, if I should use boolean to check the option field condition, if I just keep using if-else...
The problem is not the calculatin itself, but having two ways for the code to follow: One using only the obligatory fields if nothing else is inserted and the other one using all four fields.
Thanks everyone!
Code below is only using the two obligatory fields.
public void calcularResultado(View view) {
//check for blank values in obligatory fields
if (editGasolina.length() == 0) {
editGasolina.setError("Insira o valor");
}
if (editEtanol.length() == 0) {
editEtanol.setError("Insira o valor");
//runs the code
} else {
double valorGasolina = Double.parseDouble(editGasolina.getText().toString());
double valorEtanol = Double.parseDouble(editEtanol.getText().toString());
double valorResultado = valorEtanol / valorGasolina;
double porcentagem = (valorResultado) * 100;
String valorResultadoTexto = Double.toString(porcentagem);
valorResultadoTexto = String.format("%.2f", porcentagem);
if (valorResultado >= 0.7) {
textResultado.setText("GASOLINA");
textRendimento.setText(valorResultadoTexto + "%");
} else {
textResultado.setText("ETANOL");
textRendimento.setText(valorResultadoTexto + "%");
}
You almost got it. What happens now, since you have an if-if-elseconstruction, it considers the first if statement to be seperate from the if-else block below. That is to say, if editEtanol.length() == 0 evaluates to false, it will execute the else block below, even if editGasolina.length() == 0 evaluates to true.
Changing the line if (editEtanol.length() == 0) { to else if (editEtanol.length() == 0) { should already help alot. Hope that helps!
public void calcularResultado(View view) {
//check for blank values in obligatory fields
if (editGasolina.length() == 0) {
editGasolina.setError("Insira o valor");
}
if (editEtanol.length() == 0) {
editEtanol.setError("Insira o valor");
//runs the code
} else {
double valorGasolina = Double.parseDouble(editGasolina.getText().toString());
double valorEtanol = Double.parseDouble(editEtanol.getText().toString());
boolean optionalField1Used = optionalEditText1.length() != 0;
boolean optionalField2Used = optionalEditText2.length() != 0;
double valorResultado = 0;
if (!optionalField1Used && !optionalField2Used) {
valorResultado = valorEtanol / valorGasolina;
} else if (optionalField1Used && !optionalField2Used) {
valorResultado = //some other calculation
} else if (!optionalField1Used && optionalField2Used) {
valorResultado = //yet another calculation
} else {
valorResultado = //calculation if both optional fields used
}
double porcentagem = (valorResultado) * 100;
String valorResultadoTexto = Double.toString(porcentagem);
valorResultadoTexto = String.format("%.2f", porcentagem);
if (valorResultado >= 0.7) {
textResultado.setText("GASOLINA");
textRendimento.setText(valorResultadoTexto + "%");
} else {
textResultado.setText("ETANOL");
textRendimento.setText(valorResultadoTexto + "%");
}
Let us assume that the optional fields are called edit1 and edit2. I also assume that in order to use the alternative computation, both optional values must be present.
To enhance code clarity, I would define two Boolean variables to explicitly indicate whether the mandatory and optional fields have values. Something like the following.
public void calcularResultado(View view) {
var mandatoryValues = true;
var optionalValues = false;
if (editGasolina.length() == 0 {
editGasolina.setError("Insira o valor");
mandatoryValues = false;
}
if (editEtanol.length() == 0 {
editEtanol.setError("Insira o valor");
mandatoryValues = false;
}
if (edit1.length() > 0 && edit2.length() > 0) {
optionalValues = true;
}
if (mandatoryValues) {
if (optionalValues) {
// do alternative computation
} else {
// do computation for mandatory values only
}
}
}
Note that if either mandatory value is absent, no computation is performed.
Hope it helps - Carlos
I'm trying to program a bug to move around an array attached to a custom Room object, whilst keeping count of how many times each tile has been stepped on.
The Room object is working properly, as are the movement and the counting. However, the bug's coordinates, bugX and bugY, are somehow reverting to 0 after exiting the nextMove method. Their values only revert when exiting the method; even the last line of code in the nextMove method itself uses their new values.
Relevant portion of the method is attached, but other sections can be added upon request.
if (dirNum == 0 && bugY < length-1) //Move up
bugY++;
else if (dirNum == 1 && bugX < width-1) //Move right
bugX++;
else if (dirNum == 2 && bugY > 0) //Move down
bugY--;
else if (dirNum == 3 && bugX > 0) //Move left
bugX--;
else {
System.out.println("Error: Cannot move " + direction + ".");
canMove = false;
dirNum = generator.nextInt(4);
continue;
}
This is the context for the command itself.
while (endSim == false) {
nextMove(bugX, bugY);
System.out.print(room.printRoom() + "\n\nNext move? (y/n) ");
simSentinel = in.next();
if (simSentinel.charAt(0) == 'n')
endSim = true;
}
The declarations where the starting coordinates are assigned aren't inside any loops, let alone where the variable itself is called.
The problem is the one described by #T.J.Crowder in his answer though applied to java.
Variables passed as parameters in java are passed by value. If the value is changed by the method receiving the parameter, the change only affects the value inside that method. The "outside" value doesn't change.
What you can do is to encapsulate the coords in an object and pass the encapsulating object as a parameter.
Then the method will receive the object by value, and change it's state (instead of the value of the object).
For a deeper understanding see this question
EDIT I:
I cleand up the code a bit. Though it is is missing the declaration of room and simSentinel, if you add that you should have a running example.
public class Bug{
public int x=0;
public int y=0;
}
public class SimpleSim {
private int dirNum = 0;
private int length = 20;
private int width = 20;
private boolean canMove = true;
private Random generator = new Random();
private boolean endSim = false;
public static void main(String [] args) {
SimpleSim simpleSim = new SimpleSim();
simpleSim.start();
}
private void start() {
Bug myBug = new Bug();
// Give the bug some initial x, y values.
myBug.x = 0;
myBug.y = 0;
while (endSim == false) {
nextMove(myBug);
System.out.print(room.printRoom() + "\n\nNext move? (y/n) ");
simSentinel = in.next();
if (simSentinel.charAt(0) == 'n')
endSim = true;
}
}
}
public void nextMove(Bug bug){
if (dirNum == 0 && bug.y < length-1) //Move up
bug.y++;
else if (dirNum == 1 && bug.x < width-1) //Move right
bug.x++;
else if (dirNum == 2 && bug.y > 0) //Move down
bug.y--;
else if (dirNum == 3 && bug.x > 0) //Move left
bug.x--;
else {
System.out.println("Error: Cannot move " + "?" + ".");
canMove = false;
dirNum = generator.nextInt(4);
}
}
}
It seems that you are passing your bugX and bugY parameters by value. In this case, changing their value inside the method won't affect their values outside the method.
You may want to make your nextMove method return the new values for bugX and bugY after they are computed so that you can gather them back into your actual bugX and bugY variables
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm making a terrible 2D remake of Minecraft as a class project in java, and I have a crafting bench thing (or whatever it's called) and I have an if statement that checks if you have one piece of wood in the top left and nothing in the other 3, or if you have one piece of wood in the top right and nothing in the other 3, and so on...
The following if statement which I'm using seems to let you have a "wood" block in multiple slots at the same time and still lets you get the "plank" block. (id1 - id4 represent the crafting bench slots) 2x2 crafting bench Tile.wood is a wood block, Tile.blank is basically a null block or nothing.
//this if statement is what I need to change maybe?
if ((id1.id == Tile.wood && id2.id == Tile.blank
&& id3.id == Tile.blank && id4.id == Tile.blank) ||
(id1.id == Tile.blank && id2.id == Tile.wood
&& id3.id == Tile.blank && id4.id == Tile.blank) ||
(id1.id == Tile.blank && id2.id == Tile.blank
&& id3.id == Tile.wood && id4.id == Tile.blank) ||
(id1.id == Tile.blank && id2.id == Tile.blank
&& id3.id == Tile.blank && id4.id == Tile.wood)) {
//this code I don't need to change, it works fine
Inventory.inv_result.id = Tile.plank;
Inventory.inv_result.blockNum += 4;
System.out.println("You can have 4 planks");
}
So once again you should only be allowed to have one block in one place at one time, otherwise it will do nothing.
How can I fix it so I only get the "plank" block if there is only a single "wood" block in one of the four slots?
The if-condition looks untidy but will work perfectly fine. However, you can modularize it for better understanding & debugging.
Create few utility methods to do jobs for you, as below:
boolean isWood(<id object>) {
if(Tile.wood.equals(<id object>))
return true;
else
return false;
}
boolean isBlank(<id object>) {
if(Tile.blank.equals(<id object>))
return true;
else
return false;
}
void doProcess(){
Inventory.inv_result.id = Tile.plank;
Inventory.inv_result.blockNum += 4;
System.out.println("You can have 4 planks");
}
Then re-write your if-condition like below
if(isWood(id1.id) && isBlank(id2.id) && isBlank(id3.id) && isBlank(id4.id))
doProcess();
else if(isWood(id2.id) && isBlank(id1.id) && isBlank(id3.id) && isBlank(id4.id))
doProcess();
else if(isWood(id3.id) && isBlank(id2.id) && isBlank(id1.id) && isBlank(id4.id))
doProcess();
else if(isWood(id4.id) && isBlank(id2.id) && isBlank(id3.id) && isBlank(id1.id))
doProcess();
Shishir
i think if statement is ok even though it is so long. Try to use .equal() instead of == in the if statement.
The problem you have with your if-condition has nothing to do with the if-condition but some other part of your crafting bench code. You should post your crafting bench code for us to find the actual problem.
Besides about the untidiness and stuff...
This may not be the answer to your question but this will definitely make it easier for you to do many recipes:
// These are your function calls. One line per recipe. Way better than multiple if functions
// example for shaped crafting using minecraft's crafting bench recipe.
shapedCrafting(new int[]{Tile.plank, Tile.plank, Tile.plank, Tile.plank}, 4, Tile.plank);
// example for shapeless crafting using your recipe
shapelessCrafting(new int[]{Tile.plank}, 4, Tile.plank);
This would be an example of your crafting bench with an array instead of variables:
// This array resembles your crafting bench grid (2x2) in this case.
public static int[] arrayCraftingSlots = {Tile.plank, 0, 0, Tile.wood};
The function for shaped crafting:
/* int elements[] - takes in the crafting layout (this should equal your crafting bench grid)
* int amount - the amount of the item or tile you get as a result
* int result - the id of the result you get
*/
public static void shapedCrafting(int elements[], int amount, int result)
{
for(int i = 0; i < elements.length; i++)
{
if(arrayCraftingSlots[i] != elements[i])
{
return;
}
}
Inventory.inv_result.id = result;
Inventory.inv_result.blockNum += amount;
System.out.println("You can have " + amount + " " + result);
}
And the function for shapeless crafting:
I've restricted this one to 1 instance of an item per recipe just like in Minecraft. So using 2 planks in one shapeless recipe would not be possible. Of course you can change that if you want to. Keep in mind you have to change a bit of the algorithm as well.
/* int elements[] - list of elements that need to be anywhere in the crafting bench
* int amount - the amount of the item or tile you get as a result
* int result - the id of the result you get
*/
public static void shapelessCrafting(int elements[], int amount, int result)
{
for(int element : arrayCraftingSlots)
{
boolean in = false;
for(int i = 0; i < elements.length; i++)
{
if(element == elements[i] || element == 0)
{
in = true;
}
}
if(!in)
{
return;
}
}
for(int element : elements)
{
int occassions = 0;
for(int i = 0; i < arrayCraftingSlots.length; i++)
{
if(element == arrayCraftingSlots[i])
{
occassions++;
}
}
if(occassions > 1 || occassions == 0)
{
return;
}
}
Inventory.inv_result.id = result;
Inventory.inv_result.blockNum += amount;
System.out.println("You can have " + amount + " " + result);
}
Like the title says. I want to find out if a given java String contains an emoticon.
I can't use Character.UnicodeBlock.of(char) == Character.UnicodeBlock.EMOTICONS since that requires API level 19.
I found this code for iOS but it isn't really applicable since it looks like java and objective-c handle surrogate pairs in different manners.
The documentations I've looked through tell me that:
A char value, therefore, represents Basic Multilingual Plane (BMP) code points, including the surrogate code points, or code units of the UTF-16 encoding
I'm not quite sure what that means. Does that simply mean that they also include the BMP point as their first number?
According to Wikipedia the emoticon set lies between 0x1f600 and 0x1f64f but I don't know how to check if the char is in that range.
I had hoped that something like this would work but it didn't
if (0x1f600 <= a && a <= 0x1f64f)
{
Print.d("Unicode", "groovy!");
}
So how do I go about this?
Four years later...
At this time, it might make more sense to take advantage of EmojiCompat. This code presumes you initialized EmojiCompat when your app was starting up. The basic idea here is to have EmojiCompat process your CharSequence, inserting instances of EmojiSpan wherever any emoji appear, and then examine the results.
public static boolean containsEmoji(CharSequence charSequence) {
boolean result = false;
CharSequence processed = EmojiCompat.get().process(charSequence, 0, charSequence.length() -1, Integer.MAX_VALUE, EmojiCompat.REPLACE_STRATEGY_ALL);
if (processed instanceof Spannable) {
Spannable spannable = (Spannable) processed;
result = spannable.getSpans(0, spannable.length() - 1, EmojiSpan.class).length > 0;
}
return result;
}
If you want to collect a list of the unique emoji that appear within a given CharSequence, you could do something like this, iterating over the results of getSpans() and finding the start and end of each span to capture the emoji discovered by EmojiCompat:
#NonNull
public static List<String> getUniqueEmoji(CharSequence charSequence) {
Set<String> emojiList = new HashSet<>();
CharSequence processed = EmojiCompat.get().process(charSequence, 0, charSequence.length() -1, Integer.MAX_VALUE, EmojiCompat.REPLACE_STRATEGY_ALL);
if (processed instanceof Spannable) {
Spannable spannable = (Spannable) processed;
EmojiSpan[] emojiSpans = spannable.getSpans(0, spannable.length() - 1, EmojiSpan.class);
for (EmojiSpan emojiSpan : emojiSpans) {
int spanStart = spannable.getSpanStart(emojiSpan);
int spanEnd = spannable.getSpanEnd(emojiSpan);
CharSequence emojiCharSequence = spannable.subSequence(spanStart, spanEnd);
emojiList.add(String.valueOf(emojiCharSequence));
}
}
return emojiList.size() > 0 ? new ArrayList<>(emojiList) : new ArrayList<String>();
}
UPDATE: Here's an example of EmojiCompat initialization. This static method can be called from your Application onCreate() method, passing in the Application itself as the Context param.
#JvmStatic
fun initEmojiCompat(context: Context) {
if (emojiCompatConfig != null) {
// alternatively, EmojiCompat.reset() could be called here
logger().w(LOGTAG, "EmojiCompat already initialized.")
return
}
// "Noto Color Emoji Compat" doesn't have graphics for the following emojis:
// U+1F5E3 "speaking head" (required)
// U+1F441 "eye" (required)
// U+1F575 "detective" (nice to have)
val fontRequest = FontRequest(
"com.google.android.gms.fonts",
"com.google.android.gms",
"Noto Color Emoji Compat",
R.array.com_google_android_gms_fonts_certs
)
emojiCompatConfig = FontRequestEmojiCompatConfig(context, fontRequest)
.setReplaceAll(false)
.setEmojiSpanIndicatorEnabled(false)
.registerInitCallback(initCallback)
.also {
EmojiCompat.init(it)
}
}
I was in fact able to use the linked iOS code to create the following function. I didn't realize that a String that contains, for example, a single emoticon will have a length of 2. So you can check if a character is in fact a surrogate.
I'm not entirely sure how to handle else if (substring.length > 1) from the iOS code but I think Character.isHighSurrogate(myChar) does the same job in that instance.
private boolean containsIllegalCharacters(String displayName)
{
final int nameLength = displayName.length();
for (int i = 0; i < nameLength; i++)
{
final char hs = displayName.charAt(i);
if (0xd800 <= hs && hs <= 0xdbff)
{
final char ls = displayName.charAt(i + 1);
final int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
if (0x1d000 <= uc && uc <= 0x1f77f)
{
return true;
}
}
else if (Character.isHighSurrogate(hs))
{
final char ls = displayName.charAt(i + 1);
if (ls == 0x20e3)
{
return true;
}
}
else
{
// non surrogate
if (0x2100 <= hs && hs <= 0x27ff)
{
return true;
}
else if (0x2B05 <= hs && hs <= 0x2b07)
{
return true;
}
else if (0x2934 <= hs && hs <= 0x2935)
{
return true;
}
else if (0x3297 <= hs && hs <= 0x3299)
{
return true;
}
else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50)
{
return true;
}
}
}
return false;
}
This is how Telegram does it:
private static boolean isEmoji(String message){
return message.matches("(?:[\uD83C\uDF00-\uD83D\uDDFF]|[\uD83E\uDD00-\uD83E\uDDFF]|" +
"[\uD83D\uDE00-\uD83D\uDE4F]|[\uD83D\uDE80-\uD83D\uDEFF]|" +
"[\u2600-\u26FF]\uFE0F?|[\u2700-\u27BF]\uFE0F?|\u24C2\uFE0F?|" +
"[\uD83C\uDDE6-\uD83C\uDDFF]{1,2}|" +
"[\uD83C\uDD70\uD83C\uDD71\uD83C\uDD7E\uD83C\uDD7F\uD83C\uDD8E\uD83C\uDD91-\uD83C\uDD9A]\uFE0F?|" +
"[\u0023\u002A\u0030-\u0039]\uFE0F?\u20E3|[\u2194-\u2199\u21A9-\u21AA]\uFE0F?|[\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55]\uFE0F?|" +
"[\u2934\u2935]\uFE0F?|[\u3030\u303D]\uFE0F?|[\u3297\u3299]\uFE0F?|" +
"[\uD83C\uDE01\uD83C\uDE02\uD83C\uDE1A\uD83C\uDE2F\uD83C\uDE32-\uD83C\uDE3A\uD83C\uDE50\uD83C\uDE51]\uFE0F?|" +
"[\u203C\u2049]\uFE0F?|[\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE]\uFE0F?|" +
"[\u00A9\u00AE]\uFE0F?|[\u2122\u2139]\uFE0F?|\uD83C\uDC04\uFE0F?|\uD83C\uDCCF\uFE0F?|" +
"[\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA]\uFE0F?)+");
}
It is Line 21,026.
Try this...
if (Integer.parseInt("1f600", 16) <= (int)'☺' && (int)'☺' <= Integer.parseInt("1f64f", 16)) {
Print.d("Unicode", "groovy!");
}
This might work because the hexidecimal value and the char value are both being converted to ints.
Here's some Kotlin that relies on java.lang.Character api (granted the original poster can't use this). I have found it pretty reliably tells apart an emoji from 'special characters' and non-latin alphabets etc. Try it.
import java.lang.Character.*
import java.lang.Character.UnicodeBlock.MISCELLANEOUS_TECHNICAL
import java.lang.Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS
import java.lang.Character.UnicodeBlock.VARIATION_SELECTORS
fun isStringEmoji(someString: String): Boolean {
if (someString.isNotEmpty() && someString.length < 5) {
val firstCodePoint = codePointAt(someString, 0)
val lastCodePoint = codePointBefore(someString, someString.length)
if (isValidCodePoint(firstCodePoint) && isValidCodePoint(lastCodePoint)) {
if (isSupplementaryCodePoint(firstCodePoint) ||
isSupplementaryCodePoint(lastCodePoint) ||
UnicodeBlock.of(firstCodePoint) == MISCELLANEOUS_SYMBOLS ||
UnicodeBlock.of(firstCodePoint) == MISCELLANEOUS_TECHNICAL ||
UnicodeBlock.of(lastCodePoint) == VARIATION_SELECTORS
) {
return true
}
}
}
return false
}
I am writing a simple SRMS, and I need to validate the input from the user if it matches some criteria depending on the field, e.g. an email field or a phone field. The app is to run in a featured phone and so I am using the Java ME SDK with a virtual machine for testing.
What is the best way to do so, what would be the best way to validate the input and if the input does not meet some criteria, should the user be notified or the value she has entered to be set to null again.
public void name() {
boolean nameValid = false;
display = Display.getDisplay(this);
nameForm = new Form("Student Record Management (1/4");
TextField firstName = new TextField("First Name(s)", "", 20, TextField.ANY);
TextField lastName = new TextField("Last Name", "", 20, TextField.ANY);
TextField personNumber = new TextField("Person Number", "", 10, TextField.NUMERIC);
back = new Command("BACK", Command.BACK, 1);
next = new Command("Continue", Command.ITEM, 2);
nameForm.append(firstName);
nameForm.append(lastName);
nameForm.append(personNumber);
nameForm.addCommand(back);
nameForm.addCommand(next);
nameForm.setItemStateListener(this);
nameForm.setCommandListener(this);
display.setCurrent(nameForm);
if (firstName.toString().length() > 0) {
nameValid = true;
}
}
The person who started the code has implemented the CommandListener and ItestStateListener.
I am not sure what is the second one does and it has an abstract method to be filled which is called itemStateChanged(Item item) am I supposed to check for changes and validate in here ?
The ItemStateListener notifies the application of changes in Form items. The item itemStateChanged(Item item) method is called when an item in your form is changed by the user or when Item.notifyStateChanged() is called in an Item. The argument is the Item (Textfield, DateField, ect) that changed value.
I would recommend that you call your validation method inside both the CommandAction and ItemStateListener. In the itemStateChanged only the current Item (the one received in the argument) should be checked. In the CommandAction every field should be checked. This way every Item is validated in every situation.
public static boolean validateEmailID(String email) {
email = email.trim();
String reverse = new StringBuffer(email).reverse().toString();
if (email == null || email.length() == 0 || email.indexOf("#") == -1) {
return false;
}
int emailLength = email.length();
int atPosition = email.indexOf("#");
int atDot = reverse.indexOf(".");
String beforeAt = email.substring(0, atPosition);
String afterAt = email.substring(atPosition + 1, emailLength);
if (beforeAt.length() == 0 || afterAt.length() == 0) {
return false;
}
for (int i = 0; email.length() - 1 > i; i++) {
char i1 = email.charAt(i);
char i2 = email.charAt(i + 1);
if (i1 == '.' && i2 == '.') {
return false;
}
}
if (email.charAt(atPosition - 1) == '.' || email.charAt(0) == '.' || email.charAt(atPosition + 1) == '.' || afterAt.indexOf("#") != -1 || atDot < 2) {
return false;
}
return true;
}