Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I have a
JSpinner
with maximum number of fraction digits as 6. So when I enter
1.1234567
it is getting rounded off to
1.123457
.
But my requirement is when the user enters the value as a free text I want to disable the rounding and set the value to spinner as such (
1.1234567
). However if the user clicks on the spinner arrow button, it can be rounded.
The value is typically formatted by the
JSpinner
's editor. You change how the editor formats the display value, which will leave the actual model value unchanged
The editor is usually backed by a
JFormattedTextField
, it'd be nice just to be able to grab it a configure it...
There's probably a few ways to do this, but I choose to use a
NumberFormat
as I know how to control the number of fraction digits and the rounding mode
First, we need a implementation of a
JFormattedTextField.AbstractFormatter
public class NumberFormatFormatter extends DefaultFormatter {
private NumberFormat format;
public NumberFormatFormatter(NumberFormat format) {
this.format = format;
@Override
public Object stringToValue(String string) throws ParseException {
System.out.println("stringToValue: " + string);
return format.parse(string);
@Override
public String valueToString(Object value) throws ParseException {
String text = format.format(value);
System.out.println("valueToString: " + value + "; " + text);
return text;
This is then wrapped in a AbstractFormatterFactory
NumberFormat numberInstance = NumberFormat.getNumberInstance();
numberInstance.setMaximumFractionDigits(6);
numberInstance.setMinimumFractionDigits(0);
numberInstance.setRoundingMode(RoundingMode.DOWN);
JFormattedTextField.AbstractFormatter format = new NumberFormatFormatter(numberInstance);
DefaultFormatterFactory dff = new DefaultFormatterFactory(format);
We then configure the JSpinner
and it's create a new NumberEditor
to suit our needs
JSpinner spinner = new JSpinner(new SpinnerNumberModel());
JSpinner.NumberEditor editor = new JSpinner.NumberEditor(spinner, "0.0#####");
JFormattedTextField textField = editor.getTextField();
textField.setFormatterFactory(dff);
textField.setColumns(10);
spinner.setEditor(editor);
Don't forget to apply the editor to the JSpinner
;).
This might seem like a lot (I certainly think so), but it wouldn't take much to wrap it into your own implementation of a editor class which simply took a NumberFormat
as parameter, as an idea.
This approach leaves the "display" to the editor, but won't affect the underlying value in the model, so, if you enter 1.123456789
, the model will still return 1.123456789
, but it will display 1.123456
Take a look at How to Use Formatted Text Fields and How to Use Spinners for more details
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.text.ParseException;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.DefaultFormatter;
import javax.swing.text.DefaultFormatterFactory;
public class Test {
public static void main(String[] args) {
new Test();
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
public class TestPane extends JPanel {
public TestPane() {
NumberFormat numberInstance = NumberFormat.getNumberInstance();
numberInstance.setMaximumFractionDigits(6);
numberInstance.setMinimumFractionDigits(0);
numberInstance.setRoundingMode(RoundingMode.DOWN);
JFormattedTextField.AbstractFormatter format = new NumberFormatFormatter(numberInstance);
DefaultFormatterFactory dff = new DefaultFormatterFactory(format);
JSpinner spinner = new JSpinner(new SpinnerNumberModel());
JSpinner.NumberEditor editor = new JSpinner.NumberEditor(spinner, "#0.######");
JFormattedTextField textField = editor.getTextField();
textField.setFormatterFactory(dff);
textField.setColumns(10);
spinner.setEditor(editor);
setLayout(new GridBagLayout());
spinner.setValue(1.1234567d);
add(spinner);
public class NumberFormatFormatter extends DefaultFormatter {
private NumberFormat format;
public NumberFormatFormatter(NumberFormat format) {
this.format = format;
@Override
public Object stringToValue(String string) throws ParseException {
System.out.println("stringToValue: " + string);
return format.parse(string);
@Override
public String valueToString(Object value) throws ParseException {
String text = format.format(value);
System.out.println("valueToString: " + value + "; " + text);
return text;
–
–
–
–
I think that what you can do is to create your own JSpinner Model, something similar to:
public class CustomSpinnerModel extends AbstractSpinnerModel {
private Double value;
public CustomSpinnerModel(Double value){
this.value=value;
@Override
public Object getNextValue() {
value+=0.0000001;
return value+"";//return as string to avoid round
@Override
public Object getPreviousValue() {
value-=0.0000001;
return value+"";//return as string to avoid round
@Override
public Object getValue() {
return value+"";//return as string to avoid round
@Override
public void setValue(Object object) {
value=Double.parseDouble(object);
} catch(Exception e){
e.printStackTrace();
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.