How do you add zero padding to a JSpinner?
Since the spinner creates the JFormattedTextField itself, I can't just pass the format into the JFormattedTextField constructor.
Isn't there a way to set the formatting on an existing JFormattedTextField?
What I want: value = 37, editor = "0037"
UPDATE:
I have tried this as suggested:
JSpinner mySpinner = new JSpinner();
mySpinner.setEditor(
new JSpinner.NumberEditor(mySpinner, "####"));
and the result is no change at all to the presentation of the spinner's data. It seems like a reasonable solution; has anyone tried this successfully so I can be sure it's just something flaky in my own application?
You can set the editor yourself, like this:
// minimum of four digits
mySpinner.setEditor(new JSpinner.NumberEditor(mySpinner, "0000"));
"0000" is a DecimalFormat string specifying four digits, zero-padded as necessary; "####" specifies four digits but does not zero-pad.
The DecimalFormat API documentation covers formatting strings in more detail.
Referring to the javadocs, JSpinner has a setEditor(JComponent) method. Use that to set your custom JFormattedTextField, with its custom Format.
Related
I've used the following line of code to only allow users to enter digits inside a JFormattedTextField which collects information on time
final JFormattedTextField periodTextField = new JFormattedTextField();
periodTextField.setFormatterFactory(new DefaultFormatterFactory(createFormatter("##:## - ##:##")));
When running my application the text field will appear as ": - :" by default, but I would like it to appear as "00:00 - 00:00" as default, and editing the text field will only change the values of the 0's nothing else. I've looked at this guide for help on using formatters in java, but it doesn't mention how you can set default values. Is there a simple way to achieve what I need.
As the title suggests, I have the following listener on a JFormattedTextField:
myFormattedTextField.addPropertyChangeListener("value", new PropertyChangeListener()
{
#Override
public void propertyChange(PropertyChangeEvent evt)
{
System.out.println("Old value: " + evt.getOldValue());
System.out.println("New value: " + evt.getNewValue());
}
});
This always prints out null for both getOldValue() and getNewValue().
If I remove "value" string as a parameter, I get even weirder results, like the JPanel the textField is residing in or true/false values.
What exactly am I missing here?
What exactly am I missing here?
It's hard to tell exactly what is the problem based on your snippet. However be aware that JFormattedTextField component works along with both an AbstractFormatterFactory and an AbstractFormatter to be able to convert from a String representation to an Object value and the other way around.
If you initialize the formatted text field as follows, then both formatter and formatter factory will be null and no value could be ever converted: thus it will always be null:
JFormattedTextField textField = new JFormattedTextField(); // default empty constructor
If this is the case then you have an explanation about what is happening. If you take a look JFormattedTextfield class' constructors all of them take parameters that will help the component to initialize both formatter and formatter factory, except for empty constructor.
For a better understanding please have a look to How to Use Formatted Text Fields tutorial.
Side note
You say in a comment:
I am not using a NumberFormatter. Since the text fields can be blank to start with.
It's irrelevant if you want the text field be blank at the start: just don't set any value to the text field and leave the user change it (of course initial value will be null). But you definitely need to set a formatter.
if you are using NumberFormatter this may solve your problem:
numberFormatter.setCommitsOnValidEdit(true);
Is it possible to set MaskFormatter of a JFormatterTextField to ##,## and the value type of the JFormatterTextField to Float? I tried it using the following mask for a default formatter factory but it does not work and the getValue().getClass() gives me java.lang.String.
DefaultFormatterFactory dff = new DefaultFormatterFactory();
mf = new MaskFormatter("##,##);
mf.setValueClass(Float.TYPE);
dff.setDefaultFormatter(mf);
field.setFormatterFactory(dff);
And the problem with number formatting is that it doesn't mask the field for me.
PS. My default system configuration uses "," as "." in the English one. So it's not the problem and I brought it just for precision.
You are running into a bit of a limitation of JFormattedTextField here.
If you use DecimalFormat http://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html you can set up the display to look however you like but it does not rigidly enforce what the user types. The returned result will be a number.
If you use MaskFormatter then you get the rigid enforcement, but the value returned is a string.
You could use the MaskFormatter and simply pass it to Float.valueOf(str) when you need the result. The alternative is to either implement your own format object or to listen on some of the events provided by the text field and/or its backing document and directly do your own control of the users entry.
I'm trying to create a JSpinner to enable the user to pick a Date. I want there to be a lower date limit and an upper date limit. I also want the initial value to be the lower date limit. Unfortunately, My problem is that it won't let me use the lower limit as the initial value (the JSpinner simply becomes unresponsive). Here is my code:
SpinnerDateModel model = new SpinnerDateModel();
model.setStart(minTime); //lower limit
model.setEnd(maxTime); //upper limit
model.setValue(minTime); //doesn't like this!
model.setCalendarField(Calendar.MINUTE);
JSpinner timePicker = new JSpinner(model);
timePicker.setEditor(new JSpinner.DateEditor(timePicker, "HH:mm dd/MM/yy"));
If I set the initial value to be one minute before or after the lower limit, it works fine. But for my requirements, I do not want that.
Help?
Looks like a bug to me. I messed around with some code and it appears that whatever you pass to setValue, I'll call it value, must be at least one calendarField unit greater than minTime.
i.e. if you had used model.setCalendarField(Calendar.YEAR), value would have to be any date in 2011, assuming you used a date in 2010 for minTime.
According to Sun, the invariant enforced by the SpinnerDateModel constructors is minimum <= value <= maximum, so this problem shouldn't be happening.
The first workaround that comes to mind is creating a custom SpinnerDateModel which overrides the getPreviousValue() and setValue() methods to manually check against your desired minTime.
I'm using BigDecimal to represent product prices in a Java SE application.
What swing component(s) should I use in order to allow the user to input numbers with only two decimal places and bound it to a BigDecimal variable/Object's property. (Checking that as the user types)?
I've been playing with JTextField, JFormattedTextField, NumberFormatter, MaskFormatter but I can't work it out.
Is there any combination and configuration of those components to do that? or should I extend the MaskFormatter, the JTextField, ...?
I hate to necro these really old threads on stuff, but my understanding is StackOverflow cries inside every day an answer remains unsolved.
so you can checkout the code here: http://www.java2s.com/Code/Java/Swing-JFC/ABigDecimalobjectcustomformatter.htm
basically set-up to a JFormattedTextField to use a DecimalFormat
I'm not quite sure what you are trying to do, but there is a BigDecimal constructor which takes Strings as parameter (similar to e.g. Double.parseDouble(String s)):
try
{
BigDecimal decimal = new BigDecimal(yourJTextField.getText());
}
catch (NumberFormatException nfe)
{ /* error handling */}
See JavaDoc for BigDecimal for more information.
Edit: If checking/validating the user's input into the textfield, either check it manually or use a Validator (see Google results for "JTextField Validator")