[英]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.