I'm using italian locale for my program so Float.parseFloat("8,00") must function well.
But I have encountered a very bad NFE in the following line:
this.cuSurfaceJTextField1.setValue(
String.format("%05.2f",info.getCuSurface()));
I note that the above code used to work well up to some changes I made to the listeners that don't look to be related to this line of the code.(Now I have a propertyChangeListener that updates the model when the value is changed.
this.cuSurfaceJTextField1.addPropertyChangeListener("value",
new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
info.setCuSurface(Float.parseFloat(
(String)cuSurfaceJTextField1.getValue()));
updateCuSurface();
}
});
The useful part of the exception:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "08,00"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1241)
at java.lang.Float.parseFloat(Float.java:452)
at View.bars.QuadrateJPanel$11.propertyChange(QuadrateJPanel.java:348)
at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:328)
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
at java.awt.Component.firePropertyChange(Component.java:8382)
at javax.swing.JFormattedTextField.setValue(JFormattedTextField.java:799)
at javax.swing.JFormattedTextField.setValue(JFormattedTextField.java:502)
I'm using italian locale for my program so Float.parseFloat("8,00") must function well.
No. Float.parseFloat is not locale dependent. So, there are two ways to fix your issue:
Format like this:
String.format(Locale.US, "%05.2f",info.getCuSurface())
Replace the comma when you parse:
info.setCuSurface(Float.parseFloat(
((String) cuSurfaceJTextField1.getValue()).replace(',','.')));
Looks like there may be some confusion over your Locale? I've seen this myself - in America and other places numbers are written as "8.00" but in parts of Europe (France was what gave me trouble) it is written as "8,00". Seems like when String.format() is called it is in a Locale that uses commas... but setting the value on the JTextField is automatically parsing the passed-in string with Float.parseFloat() which is not sensitive to Locale matters - it looks for . and that's it.
parseFloat doesn't use the default locale, it calls FloatingDecimal.readJavaFormatString(s).floatValue().
Instead use NumberFormat which will honour the Locale set
public class NFE {
public static void main(String[] args) throws Exception
{
Locale.setDefault(Locale.ITALIAN);
NumberFormat format = NumberFormat.getInstance();
//Float.parseFloat("8,00");
System.out.println(format.parse("8,00"));
}
}
Related
I want to implement a pakistan's standard format of cnic number which is like this:12345-1234567-1.
But I don't know anything about this. I found the following code for this purpose but it also giving errors in NetBeans.
private void idSearchKeyPressed(java.awt.event.KeyEvent evt) {
String cnicValidator = idSearch.getText();
if (cnicValidator.matches("^[0-9+]{5}-[0-9+]{7}-[0-9]{1}$")) {
idSearch.setEditable(true);
}
else {
idSearch.setEditable(false);
}
}
The pattern is correct. But it can be condensed to this:
^[\\d]{5}-[\\d]{7}-\\d$
Where does idSearch come from? If its not a final member of the class you can't access it in that way. So make sure idSearch is available inside idSearchKeyPressed. Also make sure that there are no trailing spaces or something like that. You can do this by calling
cnicValidator = cnicValidator.trim();
The following example returns true for both regex versions.
public static void main(String... args){
String id = "35241-7236284-4";
System.out.println(id.matches("^[\\d]{5}-[\\d]{7}-\\d$"));
System.out.println(id.matches("^[0-9+]{5}-[0-9+]{7}-[0-9]{1}$"));
}
I'm working on localization for a program I've written with a couple other guys. Most of the strings now load in the appropriate language from an ini file. I'm trying to do the same with the format of currency in the program. However, I'm getting a runtime exception as soon as I attempt to launch the application.
I'm using the Locale object as a parameter to a few NumberFormat.getCurrencyInstance()'s, like so:
private static final NumberFormat decf;
static
{
decf = NumberFormat.getCurrencyInstance(Lang.cLocale);
decf.setRoundingMode(RoundingMode.HALF_UP);
}
Lang is the class which contains all the localization stuff. The code the IDE complains about at attempted runtime is public static Locale cLocale = new Locale(GUI.DB_info[19],GUI.DB_info[20]);
GUI is the class the GUI is contained in, and where we decided to construct the DB_info array (which itself just contains information loaded from a remote database in another class). DB_info[19] is the language code (es right now) and DB_info[20] is the country code (US). The array elements are being properly filled-- or were, I can't get far enough into the program to tell right now; but nothing has changed with the code for filling DB_info.
The full exception is as follows:
Exception in thread "main" java.lang.ExceptionInInitializerError
at greetingCard.GUI.<clinit>(GUI.java:118)
Caused by: java.lang.NullPointerException
at java.util.Locale.<init>(Unknown Source)
at java.util.Locale.<init>(Unknown Source)
at greetingCard.Lang.<clinit>(Lang.java:13)
... 1 more
The line in GUI referenced is: static String welcome = Lang.L_WELCOME + ", " + empName;, and Lang.java basically looks like this:
// Set locale for currency display
public static Locale cLocale = new Locale(GUI.DB_info[19],GUI.DB_info[20]); // language, country
// Employee specific strings
public static String L_AMT_REMAIN = "";
public static String L_AMT_TEND = "";
public static String L_APPROVED = "";
public static String L_ARE_YOU_SURE = "";
[...]
public static void Main(String emp_lang)
{
String header = "";
if (emp_lang.equals("ENG"))
{
header = "ENG";
}
else if (emp_lang.equals("SPA"))
{
header = "SPA";
}
else if (emp_lang.equals("FRE"))
{
header = "FRE";
}
else if (emp_lang.equals("GER"))
{
header = "GER";
}
else
{
header = "ENG";
}
try
{
Ini ini = new Ini(new File("C:/lang.ini"));
L_AMT_REMAIN = ini.get(header, "L_AMT_REMAIN");
L_AMT_TEND = ini.get(header, "L_AMT_TEND");
L_APPROVED = ini.get(header, "L_APPROVED");
L_ARE_YOU_SURE = ini.get(header, "L_ARE_YOU_SURE");
[...]
L_WELCOME = ini.get(header, "L_WELCOME");
L_WELCOME2 = ini.get(header, "L_WELCOME2");
L_XACT_CHNG = ini.get(header, "L_XACT_CHNG");
L_YES = ini.get(header, "L_YES");
System.err.println("Employee Language: " + header);
}
catch (InvalidFileFormatException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
} // end public static void main
That's for the majority of the strings to be displayed in different languages. There is another method inside Lang that loads some other strings, independent of the first set. I don't believe it factors into this problem but I can post it if needed.
The order in which these classes/methods get launched is as follows:
GUI.Main calls the Login class, which calls a CreateLogin method. That method calls Clients.main, which gets the DB_info array from GUI passed to it. Clients fills the DB_info array. Lang.other is then called (to get language-specific strings for the login page), and the Login buttons and labels are created. Once a login is successful, the perferred language of the employee logging in (from a DB) is passed to Lang.main to load the other strings (hence the emp_lang being passed in the code above).
Up until I added the code for the Locale object, all of this worked fine. Now I get the ExceptionInInitializerError exception. Anyone know what's going on?
BTW, for loading from the ini file I'm using ini4j. Some forum posts I found while googling suggest this is a problem with that, but I don't see how it relates to the problem with Locale objects. The ini stuff works (worked) fine.
Sounds like you have a cycle in your static initializers, so something is not initialized yet.
GUI calls Lang's static initializer before getting Lang.L_WELCOME. Lang calls GUIs static initializer in line 2. Your exception trace makes it look like GUI calls Langs static initializer for some reason.
In all, cycles like this mean that someone is going to reference a statically initialized object and get null instead of what they expected to get. In this case, I suspect Lang.java, line 2, is passing two null pointers to the Locale constructor.
As Keith notes, you have a static initializer cycle. To help future readers...
To minimize these bugs, initialize (simple) constants (with no or minimal constructors) before (complex) variables, so here String before Locale – less room for cycles to cause problems.
Debugging-wise, NullPointerException on a static field and 2 <clinit> in stack trace, with the earlier class appearing in the failing line, are the clues that this is an uninitialized field caused by a static initializer cycle.
I couldn't convert a String s="45,333" into number like long or double. Can anyone help me to solve the issue.. i have added the model snippet, when i try to run that code it showing NumberFormatException..
public static void main(String args[])
{
long a=85200;
NumberFormat numberFormat=NumberFormat.getNumberInstance();
String s=numberFormat.format(a);
Long l=Long.parseLong(s.toString());
System.out.println("The value:"+s);
System.out.println("The value of long:"+l);
}
Consider NumberFormat.parse() method instead of Long.parseLong().
Long.parseLong() expects String without any formatting symbols inside.
Mixing NumberFormat and Long.parseLong() isn't a good idea.
NumberFormat can be locale-aware (in your example it uses the default locale for your computer) or you can explicitly specify format patterns, whereas the parseXXX() methods of Number subclasses only read "plain" numbers (optional minus sign+digits).
If you formatted it with NumberFormat, you should use NumberFormat.parse() to parse it back. However you shouldn't depend on the default locale, try to specify one instead (or use DecimalFormat with a pattern). Otherwise you're likely to encounter some nasty and hard to detect bugs.
If you don't care about the format, consider using Long.toString() to convert a long value into string and Long.parseLong() to convert it back. It's easier to use, thread safe (unlike NumberFormat) and works the same everywhere.
As pointed out you can use NumberFormat.parse() like this:
public static void main(String args[]) {
long a=85200;
NumberFormat numberFormat=NumberFormat.getNumberInstance();
String s=numberFormat.format(a);
Long l;
try {
l = numberFormat.parse(s.toString()).longValue();
} catch (ParseException ex) {
l = 0L;
// Handle exception
}
System.out.println("The value:"+s);
System.out.println("The value of long:"+l);
}
long l = Long.valueOf(s);
System.out.println("The value of long:"+l);
Given that this field locale have been set for norwegian bokmål and norway:
Locale locale = new Locale("nb","no");
What's missing from this code fragment inside a method to return the proper string for the language bokmål?
Assert.assertNotNull(locale);//Is asserted
MutableDateTime start = new MutableDateTime(2012,1, 10,10,0,0,0 );
start.setDayOfWeek(DateTimeConstants.SATURDAY);
System.out.println(start.dayOfWeek().getAsText(locale));
System.out.println(locale.getISO3Language().toString());
The output is "Saturday, nob"
Do I need to implement locale specific weekday name strings myself? If so is there some base object or interface to override in jodatime? I can't seem to find one.
Your code works correctly for me:
[system:/tmp]$ cat Loc.java
import org.joda.time.*;
import java.util.Locale;
class Loc {
public static void main(String[] args) {
Locale locale = new Locale("nb","no");
MutableDateTime start = new MutableDateTime(2012,1, 10,10,0,0,0 );
start.setDayOfWeek(DateTimeConstants.SATURDAY);
System.out.println(start.dayOfWeek().getAsText(locale));
System.out.println(locale.getISO3Language().toString());
}
}
[system:/tmp]$ java Loc
lørdag
nob
A few things to try:
Try using new Locale("nb", "NO") (country/region is supposed to be case-insentive, but it's worth a shot)
Try using new Locale("no", "NO") or new Locale("nn", "NO") - Nyorsk may not be what you're looking for, but does it work? From some Googling, it seems like some platforms might treat nb_NO as an alias for no_NO? It might be useful just to know if that does or doesn't work.
Make sure the nb_NO locale is available. It probably is since getISO3Language() seems to work.
In a Wicket app, I have a decimal number text field:
TextField<BigDecimal> f =
new TextField<BigDecimal>("f", new PropertyModel<BigDecimal>(model, "share"));
I want it to always accept both . (dot) and , (comma) as decimal separator (regardless of browser's locale settings).
For showing the value, session's locale is used [which in our case is forced to be "fi" (-> comma)], but here I'm interested in what the field accepts as input.
My question is, do I have to change the field to TextField<String>, and convert to domain object's type (BigDecimal) manually? Or is there some way to use TextField<BigDecimal> (which allows e.g. making use of Wicket's MinimumValidator or RangeValidator), and still have it accept both decimal separators?
Thanks to #bert's comment, and the Wicket in Action book, I found an approach that works. In the Application class specify a custom converter for BigDecimals:
#Override
protected IConverterLocator newConverterLocator() {
ConverterLocator converterLocator = new ConverterLocator();
converterLocator.set(BigDecimal.class, new CustomBigDecimalConverter());
return converterLocator;
}
And in the custom converter, convertToObject needs to be overridden. NB: this is sufficient for our needs; think about your requirements and adapt as needed!
public class CustomBigDecimalConverter extends BigDecimalConverter {
#Override
public BigDecimal convertToObject(String value, Locale locale) {
// NB: this isn't universal & your mileage problably varies!
// (Specifically, this breaks if '.' is used as thousands separator)
if ("fi".equals(locale.getLanguage())) {
value = value.replace('.', ',');
}
return super.convertToObject(value, locale);
}
}
Edit: Offtopic, but I want to document this too. We needed our app to support a scale of 4 decimal places, and our custom BigDecimal converter nicely solves that problem too.
#Override
public String convertToString(Object value, Locale locale) {
NumberFormat fmt = getNumberFormat(locale);
fmt.setMaximumFractionDigits(4); // By default this is 3.
return fmt.format(value);
}
After this customisation, a decimal number like 2.0005 will be shown as 2.0005 instead of 2.