Note: I have asked this question when I was a newbie to programming in java. I have got the solution for the same; back then itself. Editing to make it clear for other readers.
Input Format: Input is in string format. In our case we assume to convert the strings that contains only digits to BigDecimal, rest of them can be ignored.
Eg: We expect 1e4 -> BigDecimal value to be passed as "10000". So, the inputs which
contains alphabets or any other special characters can be be ignored to convert.
Reason for the requirement: We need to search few columns in the DB based on the search text and retrieve rows on matching criteria. Lets say columns name(VarChar column), price(Decimal column), type (VarChar column). So, if the search text can be converted to BigDecimal we will search if text matches any of the columns else if it can't be converted to BigDecimal we will search if the text matches other two columns.
Without analysing the input further I have blindly converted the search text to BigDecimal.
Example: if the name in DB is 1e3 and price is 10000 and if search text is 1e4, then the converted BigDecimal value of 1e4 will be matched to 10000 and will fetch the row.
Initial Code of converting to BigDecimal:
BigDecimal textToBigDecimal = null;
try
{
textToBigDecimal = new BigDecimal(searchText);
}
catch (NumberFormatException ignored)
{
}
if (textToBigDecimal == null)
{
//criteria handling code.
}
else
{
//criteria handling code.
}
Skipped the criteria constructed code. Added try-catch because, the input can be a pure string also. Based on that criteria construction differs.
Modified Code:
BigDecimal textToBigDecimal = null;
try
{
if (!searchText.contains("e") && !searchText.contains("E"))
{
textToBigDecimal = new BigDecimal(searchText);
}
}
catch (NumberFormatException ignored)
{
}
if (textToBigDecimal == null)
{
//criteria handling code.
}
else
{
//criteria handling code.
}
Note: If any further doubts pls comment on the question. I have posted this question expecting to find a default java method that converts only the strings that contains digits only to BigDecimal and throws exception for rest of the strings.
If you want exception to be thrown for strings like '45e57', you can use for example Long.parseLong("43e57") before constructing BigDecimal. It will throw NumberFormatException
Related
I am loath to reinvent this bicycle and am hoping to be shown the tried and true way to handle this problem.
I'm collecting numeric values from users via some String interface (text input for instance).
I want to make sure that regardless of what type of memory space I'm using for collecting this info, I don't allow the user to enter a number that exceeds this value.
My intuition tells me that the only way to do this is to actually measure the string length of the max value... such as...
if( (userInput + "").length() > (Integer.MAX_VALUE + "").length()){
//user has entered too many digits for an Integer to hold.
}
But this looks ugly to me and I'm guessing there's a cleaner way to handle this.
When you get the userInput for the first time you should verify that what the user enters is valid and if it is, then Integer.parseInt() will work. If it's not valid, i.e. a value greater than Integer.MAX_VALUE, it will throw an exception.
The behavior you're describing leads to using the catch as flow control which is not a good design...
BAD:
try{
Integer.parseInt(max);
//do something with the integer
}catch (NumberFormatException e)
{
//user has entered too many digits for an Integer to hold.
userInput = Integer.MAX_VALUE + "";
}
The constructor of Integer would detect that for you, by throwing a NumberFormatException if the user input is either out of range or not really an integer. See the following test program example:
public class UserInputBigInteger {
public static void main(String[] args) {
String[] inputStrings = {
String.valueOf(Integer.MAX_VALUE)
, String.valueOf(Integer.MAX_VALUE)+"0" // x10
, String.valueOf(Integer.MAX_VALUE)+"a" // not an integer
};
for (String inputString : inputStrings) {
try {
Integer inputInteger = new Integer(inputString);
final int MAX = Integer.MAX_VALUE;
System.out.format("userInput %s is within range %,d%n"
, inputString, MAX);
} catch (NumberFormatException ex) {
System.out.format("userInput does not appear to be valid interger: %s%n"
, ex.getMessage()); }
}
}
}
The output would be:
userInput 2147483647 is within range 2,147,483,647
userInput does not appear to be an interger: For input string: "21474836470"
userInput does not appear to be an interger: For input string: "2147483647a"
You could also try this to get the bit information:
BigInteger userInputCheck=new BigInteger(userInput);
if(userInputCheck.bitLength()>31){
//error : cannot convert the input to primitive int type
}
EDIT
If you are using Apache Commons there is a method createNumber# in the NumberUtils utility class.
From the documentation:
...it starts trying to create successively larger types from the type specified
until one is found that can represent the value...
Source Code for the above method
I'm doing a simple insert in one form.
no_text & no_text_external were choose from drop down
I'm saving the id for no_text & no_text_external in another table which is
dbname_m_db
and would like to view it back. So i'm doing 4 test which are
test1: insert no_text
test2: insert no_text_external
test3: insert no_text & no_text_external
test4: not insert both
so the result is, only test3 is success to view it back. while the other 3 return error number format exception :For input string: "". I don't know the best way to filter it. Here the code that im working for. Any idea?
public void getDataById(Connection con){
try{
ps = con.createStatement();
rs = ps.executeQuery("SELECT * FROM "+ dbname_m_db +" WHERE id_m_db ='"+ this.getId_m_db() +"' AND status_data ='1'");
while (rs.next()) {
this.setNo_text(rs.getString("no_text"));
this.setNo_text_external(rs.getString("no_text_external"));
}
int int_no_text = Integer.valueOf(this.getNo_text());
int int_no_text_external = Integer.valueOf(this.getNo_text_external());
this.setNo_text_value(au.getTextById(con, int_no_text));
this.setNo_text_external_value(au.getTextExternalById(con, int_no_text_external));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
In order to handle the NumberFormatException error, you should validate your String before executing Integer.valueOf().
You could validate if your string is empty:
int int_no_text;
if (!this.getNo_text().isEmpty) {
int_no_text = Integer.valueOf(this.getNo_text());
}
Honestly, I'm not really fond of this approach because one is neither validating if the string is null or if it contains, in fact, an integer.
Therefore, one could make use of a really good utility class, NumberUtils, and validate if we're on a presence of a number:
int int_no_text;
if (NumberUtils.isNumber(this.getNo_text())) {
int_no_text = Integer.valueOf(this.getNo_text());
}
Basically, this way one checks whether the string is a valid Java number hence null and empty/blank strings will return false.
It looks like you're passing an empty string when you are getting the integer value from the table. I would check to make sure that you're getting he expected return from the table before converting it into an int
I'm new to Java GUI . I'm doing a project using Netbeans.There are several text fields and I need to do validations for them.
Validations should be
Want to check whether fields are empty or not.
If it's a number field it should be validated only to input numbers.
In web (Ex:contact form) validations we can validate the fields step by step when user is entering data up to down. I need to know whether it is possible or not in Java GUI programmes.
Found several methods as Documentfilter,InputVerifier and PlainDocument. Can someone please explain the differences of them and what is the best method to use for validations input data of users in Java?
depending how familiar you are with java programming in general, this helps you more or less
Retrieve the text from the JTextField (getText()) and check for emptiness
Cast the text to a number and catch a NumberFormatException in case its not a number.
for 2) its a validation after the user has entered something and not an validation during typing
You should write java method for validation .
1.Read Text from JTextField using (getText() ) and pass this string to NumberValidation Method . Sample code is shown below
String data=textFieldObject.getText().trim();
boolean validate =isValidMobile(data);//return false if the data is not a valid phone number
public boolean isValidMobile(String PhoneNumber)
{
try{
if(PhoneNumber.length()==10) //checking length.
{
for(int i=0;i<10;i++){
char c=PhoneNumber.charAt(i);
if(!Character.isDigit(c)) //return false if the character is digit
{
return false;
}
}
}else
{
return false;
}
return true;
}catch(Exception r)
{
return false;
}
}
my application will have a text box which the user will edit with numbers (hopefully)
I am using Integer.parseInt() to convert the string into a integer, however, there's always the chance the user will not pass in numbers which will throw an exception during parseInt(). I am not sure what the convention is for error handling in GWT. Does this work?
int number = -1;
try {
number = Interger.parseInt(inputFromUser);
} catch (Exception e) {
// error handling like telling user to try again
}
If you want number-only boxes, use IntegerBox, LongBox, or DoubleBox. They already support rendering and parsing of, respectively, integer, long or double values using locale-aware renderers/parsers (based on NumberFormat).
You are on the right track. Just change Exception to NumberFormatException and you should be fine.
I am currently creating this java GUI that will ask the user to input 10 entries, then use the values to execte the next action.
I want only numbers or decimal point to be inputted inside such that it can only be a float value.
If it is not number or decimal point, it should prompt the user to input that specific entry again before the next action is executed.
How should I do it?
Wong,
not sure whether you are using Swing or not...
Ages ago I had the same problem and I solved it with creating a class RestrictedTextField extending JTextField. In the constructor I added a key listener (addKeyListener(new RestrictedKeyAdapter());)
private class RestrictedKeyAdapter extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
if (getText().equals("")) {
oldString = "";
return;
} else {
// if you cannot parse the string as an int, or float,
// then change the text to the text before (means: ignore
// the user input)
try {
if (type.equals("int")) {
int i = Integer.parseInt(getText());
oldString = getText();
} else if (type.equals("float")) {
float f = Float.parseFloat(getText());
oldString = getText();
} else {
// do nothing
}
} catch (NumberFormatException el) {
setText(oldString);
}
// if the text is identical to the initial text of this
// textfield paint it yellow. If the text was changed
// paint it red.
if (initialString.equals(getText())) {
setForeground(Color.YELLOW);
} else {
setForeground(Color.RED);
}
}
}
}
The idea is, that every time the user presses a key in the textfield (and releases it then), the text in the textfield is parsed. If the component should accept only floats for example then the component tries to parse it as an float (Float.parseFloat(..)). If this parsing is successful everything is fine. If the parsing fails (an NumberFormatException is thrown) then the old text is written back into the textfield (literally ignoring the user input).
I think you can add the KeyAdapter directly to the JTextField without creating a dedicated class for that, but with this solution you can remember the initial string and the old string.
you can play around with the code.. you can change the colour of the textfield if the input is valid or not (or like in my code snippet if the text is identical to the initial string).
one additional comment: I set the 'type' of the textfield in a variable with the name 'type', which is simply a String with the values "int", "float", etc.... a better solution would be here for example an enum of course...
I hope this is helpful...
timo
There are various options for what you would like to do. You can check here for one example of doing so. Another example could be to use Formatted TextFields, as shown here.
On the other hand, upon submission, you can try to parse the value to a float or double. If you get any exceptions, then, the value is not a number.
Lastly, you can use Regular Expressions. An expression such as ^\\d+(\\.\\d+)?$ should match any integer or floating point number.