簡體   English   中英

如何在JSpinner中禁用值舍入

[英]How to disable rounding of values in JSpinner

我有一個JSpinner ,最大小數位數為6。因此,當我輸入1.1234567它會四舍五入為1.123457

但是我的要求是,當用戶以自由文本形式輸入值時,我想禁用舍入並將值設置為spinner這樣( 1.1234567 )。 但是,如果用戶單擊微調器箭頭按鈕,則可以四舍五入。

該值通常由JSpinner的編輯器格式化。 您可以更改編輯器格式化顯示值的方式,這將使實際模型值保持不變

該編輯器通常由JFormattedTextField支持,只需要能夠對其進行配置就可以了。

可能有幾種方法可以執行此操作,但是我選擇使用NumberFormat因為我知道如何控制小數位數和舍入模式

首先,我們需要一個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;
    }

}

然后將其包裝在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);

然后,我們配置JSpinner並創建一個新的NumberEditor以適應我們的需求

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);

不要忘記將編輯器應用於JSpinner ;)。

這看起來可能很多(我當然是這么認為的),但是將其包裝到您自己的編輯器類的實現中並不需要很多,該實現僅將NumberFormat作為參數。

這種方法將“顯示”留給編輯器,但不會影響模型中的基礎值,因此,如果輸入1.123456789 ,則模型仍將返回1.123456789 ,但它將顯示1.123456

看一看如何使用帶格式的文本字段如何使用微調框,以了解更多詳細信息

微調

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;
            }

        }

    }

}

我認為您可以做的是創建自己的JSpinner模型,類似於:

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) {
        try{
           value=Double.parseDouble(object);
        } catch(Exception e){
           e.printStackTrace();
        }
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM