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;
                @mKorbel In that case, you can use what ever meets the requirements...I don't JFormattedText, takes to much effort to configure :P
– MadProgrammer
                Jun 26, 2015 at 7:36
                @MadProgrammer Thanks for your answer. Is there any way to control the display of the editor? I need to display the exact value when the user inputs as a free text.
– MRavindran
                Jun 26, 2015 at 9:02
                The question there is, how would you know?  Basically how it works is the underlying Document of the text field is updated, this triggers a series of events which allow the value to be (eventually) formatted, when the user leaves the field or press [Enter], the field is validated and the final value is formatted.  The problem is, if you use setValue, you get the same result
– MadProgrammer
                Jun 26, 2015 at 9:22
                Is there any way to stop formatting when the user manually enters the value and press enter.
– MRavindran
                Jun 30, 2015 at 5:37

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 your reply! But a small question. if I apply this model to my spinner, even if I click on spinner arrow button, it will not be rounded rite?
– MRavindran
                Jun 26, 2015 at 6:25
                I didn't try it, but it should not, if it is considered the values as Text class. If it did not work maybe you have to create it from 0.  Creating a JtextFields on a JPanel with 2 JButtons, and with this you can generate your own Spinner, having total control on the content shown and edition.
– Bepo
                Jun 26, 2015 at 6:35
        

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.