i'm doing a calculator app and i'm using Decimal Format to format my number.
My problem is i want it to show number like 0,003. But 2 zero after the comma didn't show up until I typing 3. Please help me fix this
Here my code
DecimalFormatSymbols formatSymbolsGermany = DecimalFormatSymbols.getInstance(Locale.GERMANY);
DecimalFormat decimalFormat = new DecimalFormat("#,###,###.########", formatSymbolsGermany);
My code to add "0"
private void zeroOnClick() {
if (tvNumber.getText().toString().length() < 11) {
convertNumber("0");
}
}
private void convertNumber(String number) {
number1 += number;
try {
double a = Double.parseDouble(number1.replace(',', '.'));
tvNumber.setText(decimalFormat.format(a));
delete = true;
} catch (Exception e) {
e.printStackTrace();
}
}
private void addComma(){
if (comma) {
//do nothing
} else {
number1 += ",";
tvNumber.setText(number1);
comma = true;
}
}
The simplest solution would be to just tvNumber.setText(number1); directly without the back-and-forth conversion while editing and display it in the proper format only after the editing is done.
Another possibility would be to artificially append a digit before the conversion if the number contains a decimal point and then remove it afterwards.
String res = number1.replace(',', '.'); // shouldn't this be decimalFormat dependent ?
if( number1.contains(".") ) {
res = decimalFormat.format( Double.parseDouble(res+"5"));
res = res.substring(0,res.length()-1);
} else {
res = decimalFormat.format( Double.parseDouble(res) );
}
Related
I am trying to format string in TextField which includes: remove all characters that are not numbers, format numbers using DecimalFormatter and limit number of character in the TextField:
private void IntegerInputChecker() {
ChangeListener<String> integerChecker = new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue,
String newValue) {
String pureValue = newValue;
String formatedText = newValue;
if (pureValue.length() <= 15) {
// Limit the characters in TextField
if (!newValue.matches("\\d*")) {
// Replace everything excepts number
pureValue = newValue.replaceAll("[^\\d]", "");
formatedText = pureValue;
}
if (pureValue.length() > 3) {
// Format number
DecimalFormat formatter = new DecimalFormat( "#,###" );
formatedText = formatter.format(Double.parseDouble(pureValue));
}
else if(pureValue.length() == 3) {
formatedText = pureValue.replaceAll(",", "");
}
}
else {
// Limit the characters in TextField
formatedText = formatedText.substring(0, formatedText.length() - 1);
}
fieldPrice.setText(formatedText);
}
};
fieldPrice.textProperty().addListener(integerChecker);
}
Everything works fine when I type in number but when I try to delete them in order, JavaFX throws an exception (the program still works fine):
java.lang.IllegalArgumentException: The start must be <= the end
For example, If I have 123,456,789 when I delete the number to 123,456 then it throws the above exception.
Thanks in advance.
Input can be given both way in my software, when I give 2.5 , it return 2.5. but whem I given 2,5 it give me, 2.0 . This is my code ;
public PrescriptionNotationParser()
{
final NumberFormat numberFormat = NumberFormat.getInstance();
if (numberFormat instanceof DecimalFormat)
{
doseValueFormat = (DecimalFormat) numberFormat;
doseValueFormat.applyPattern("##.########");
decimalFormatSymbols = doseValueFormat.getDecimalFormatSymbols();
}
}
private double parse(final String valueStr)
{
try
{
return doseValueFormat.parse(valueStr).doubleValue();
}
catch (ParseException e)
{
return 0;
}
}
Expect some expertise help to resolve this issue ?
2.5 is a float, but 2,5 isn't float format, so 2,5 will only get the previous value 2.
If you want support 2,5 to 2.5
private double parse(String valueStr)//remove final
{
try
{
//replace valueStr "," to "."
return doseValueFormat.parse(valueStr.replace(",", ".")).doubleValue();
}
catch (ParseException e)
{
return 0;
}
}
If you want 23,000 .50 to 23000.5, only remove , and space.
a float . only one at most.
private double parse(String valueStr)//remove final
{
try
{
//valueStr remove all "," and " "
return doseValueFormat.parse(valueStr.replaceAll(",| ", "")).doubleValue();
}
catch (ParseException e)
{
return 0;
}
}
If you want to display your input always in english format (with a point . )
You can use the placeholder %s-String for any primitive type.
float x = 3.15f, y = 1.2345f;
System.out.printf("%.4s and %.5s", x, y);
Output: 3.15 and 1.234
%s is always english formatting regardless of localization.
If you want a specif local formatting, you could also do:
import java.util.Locale;
float x = 3.15f, y = 1.2345f;
System.out.printf(Locale.GERMAN, "%.2f and %.4f", x, y);
Output: 3,15 and 1,2345
And of course you can use an if condition like if Locale.GERMAN then display Locale.GERMAN
I have the following problem:
I have big values stored in the String, and I can only display number that is 7 digit long. Here are the examples after converting from string to float -
I have String 300 which should be 300, but it is 300.0
Everything that's bigger than 7 digits should be written in scientific notation (700000000 should be 7E+8)
It also could be 7.0E8, but I prefer 7E+8.
I have tried formatting the string but when I wasn't able to get rid of .0 without getting rid of scientific notation. Is this even possible ?
The class DecimalFormat from the package java.text handles this almost effortlessly. A tad bit of business logic for your specific case seals the deal.
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class NumberFormatter
{
public static void main(String args[])
{
String stringInput = "1234.5678";
String outputString = null;
if (stringInput.length() < 8)
{
outputString = stringInput;
}
else
{
outputString = scientificOutput(stringInput);
}
System.out.println(outputString);
}
private String scientificOutput(String input)
{
NumberFormat formatter = new DecimalFormat("0.###E0");
Double d = Double.parseDouble(input);
if (d % 1 == 0)
{
// is int
return formatter.format(d.intValue());
}
else
{
// is a double
return formatter.format(d);
}
}
}
Try this:
String inputValue = "700000000";
String result;
DecimalFormat df1 = new DecimalFormat("#######");
df1.setMinimumFractionDigits(0);
DecimalFormat df2 = new DecimalFormat("######E0");
df2.setMinimumFractionDigits(1);
if (inputValue.length() <= 7) {
result = df1.format(Double.parseDouble(inputValue));
} else {
result = df2.format(Double.parseDouble(inputValue));
}
I am creating a budget program in java and need to check to see if the user inputs a valid dollar amount, specifically 2 decimal places. There is no specification on how this should be done.
This is my current attempt but the logic is wrong
aExpense5.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String desc = aExpense3.getText();
String value = aExpense4.getText();
double fValue = 0;
try
{
fValue = Double.valueOf(value);
}
catch (NumberFormatException d)
{
JOptionPane.showMessageDialog(null, "Invalid Number1");
}
double dValue = (fValue * 10) % 10;
if (dValue <= 0)
{
updateExpenseList(desc, fValue);
}
else
{
JOptionPane.showMessageDialog(null,"invalid Number");
}
}
});
You can use regex:
if (value.matches("\\d*\\.\\d\\d")) {
// the number string has two decimal places
}
This regex allows for optional whole number part, ".05" would match.
Try something like:
if (fValue*100 == (int)(fValue*100)) {
//fValue had 2 decimal places or less
}
If fValue = 0.11 then fValue*100 = 11. So you'd have 11 == (int)11 which is true.
If fValue = 0.111 then fValue*100 = 11.1. So you'd have 11.1 == (int)11.1 which is false.
I am getting a value named amount in an object through its getter as shown below.
Let's say the object is h then
h.getAmount()
Now I need to develop a validator that will validate that amount should be of type integer and if it is not then it will throw the exception, I have developed that also as shown below
private boolean isint (String amount){
boolean isValid = true;
try {
Integer.parseInt(amount);
}
catch(NumberFormatException e){
isValid = false;
}
return isValid;
}
Now the issue is that amount coming from h is an integer such as 1234, but it can also be a float such as 1258.26. So in the case of float it throws a NumberFormatException.
How could I make it perfect for both the values whether it is integer or whether it is float?
You could use a regex like this:-
if (str.matches("[-+]?[0-9]*\\.?[0-9]+")) { // You can use the `\\d` instead of `0-9` too!
// Is a number - int, float, double
}
[-+]? - For the sign.
[0-9]*\.?[0-9]+ - For the numbers and the decimal point between them.
Update:-
In case exponential needs to be handled too, then the below regex can be used.
String regex = "[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?";
First of all, if you have a function called isInt it should do exactly that -- check if it's an integer. No more and no less.
You could try something like that
enum VarType {
INTEGER, FLOAT, STRING, EMPTY
}
private VarType getVarType(String amount){
if (amount.length() ==0) {
return VarType.EMPTY;
}
if (amount.contains(".")) {
try {
Float.parseFloat(amount);
}
catch(NumberFormatException e){
return ValType.STRING;
}
return ValType.FLOAT;
} else {
try {
Integer.parseInt(amount);
}
catch(NumberFormatException e){
return ValType.STRING;
}
return ValType.INTEGER;
}
}
I would not recommend it though, because using exceptions in this way is really expensive. Exceptions should be used as their name suggests, to handle special cases, exceptions, and not as a standard flow.
I would do it like this:
public class ParseVarTest {
static enum VarType {
INTEGER, FLOAT, STRING, EMPTY
}
private static VarType getVarType(String amount){
boolean onlyDigits = true;
int dotCount = 0;
if (amount == null) {
return VarType.EMPTY;
}
String trimmed = amount.trim();
if (trimmed.length() == 0) {
return VarType.EMPTY;
}
int a=0;
if (trimmed.charAt(0) == '-') {
a++;
}
for (int max=trimmed.length(); a<max; a++) {
if ( trimmed.charAt(a) == '.' ) {
dotCount++;
if (dotCount>1) break;
} else if ( !Character.isDigit(trimmed.charAt(a)) ) {
onlyDigits = false;
break;
}
}
if (onlyDigits) {
if (dotCount ==0) {
return VarType.INTEGER;
} else if (dotCount ==1) {
return VarType.FLOAT;
} else {
return VarType.STRING;
}
}
return VarType.STRING;
}
public static void main(String[] args) {
String[] vars = {"", " ", "123", "-5123", "1234.41", "-1234.41", "-1234..41","a12312", "523sdf234sdf.123"};
for (String var: vars) {
System.out.print(var);
System.out.print(": \t");
System.out.println(getVarType(var));
}
}
}
It's quite long for such a simple task, but:
no regexes
at most a single scan of the string
readable (IMO)
fast
However, this solution does not validate the range of the value. String 10000000000 would still be recognized as a VarType.INTEGER even though the value could not fit into an int variable in Java.
Use Double.parseDouble ... (method name changed to isNumber to better reflect the meaning of the method) ...
private boolean isNumber (String amount){
boolean isValid = true;
try {
Double.parseDouble(amount);
}
catch(NumberFormatException e){
isValid = false;
}
return isValid;
}
... and could simplify to ...
private boolean isNumber (String amount){
try {
Double.parseDouble(amount);
}
catch(NumberFormatException e){
return false;
}
return true;
}
As suggested, it would be better to use long and double instead of int and float.
By the way, can't you simply check for a float ? If it is an int, than it can always be a float, potentially rounded with loss of precision.
public static boolean isFloat(String number){
try {
return !new Float(number).isNaN();
} catch (NumberFormatException e){
return false;
}
}
Running demo: https://ideone.com/UpGPsK
Output:
> 1234 IS a valid Integer or Float
> 1234.56 IS a valid Integer or Float
> 1234.56.78 IS NOT a valid Integer or Float
> abc IS NOT a valid Integer or Float
> 2147483647 IS a valid Integer or Float
> 3.4028235E38 IS a valid Integer or Float
> -2147483648 IS a valid Integer or Float
> 1.4E-45 IS a valid Integer or Float
If you're talking about integers or a few decimals, you're probably talking about money or quantities, for which BigDecimal is ideal; and floating-point not really so good (due to rounding errors).
Otherwise, you're talking about a double floating-point value.
new BigDecimal( str) will parse an integer or decimal for you, but it will also accept exponents; eg 1.4E2 means 140.
Perhaps you want to use a regex pattern to validate it first;
if (! str.matches( "[-+]?(\\d+)|(\\d*\\.\\d+)"))
throw new NumberFormatException();
This pattern accepts decimals without any leading digits, such as .14159 -- which should be allowable.