使JSpinner只读取数字,但也检测退格

我正在尝试创建一个只接受数字的JSpinner,但我也想让它读取/响应退格。

public class test { JFrame frame; JPanel panel; JSpinner spinner; public test() { frame = new JFrame("test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setPreferredSize(new Dimension(200,200)); panel = new JPanel(); SpinnerNumberModel numSpin = new SpinnerNumberModel(10, 0,1000,1); spinner = new JSpinner(numSpin); JFormattedTextField txt = ((JSpinner.NumberEditor) spinner.getEditor()).getTextField(); ((NumberFormatter) txt.getFormatter()).setAllowsInvalid(false); panel.add(spinner); frame.setContentPane(panel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { test test = new test(); } } 

上面的代码只能编号,但这不允许我退格。 我在这个网站上找到了一些例子,但是他们是为C写的。

  • 你说得对JFormattedTextField没有正确实现到JSpinner ,你实现了DocumentFilter来过滤从keyboad键入的或者从ClipBoard中粘贴的不需要的Chars ,(感谢@StanislavL)

  • 你自己解决了包含在invokeLater() focusGained()上的selectAll()问题,

 import java.awt.BorderLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; import javax.swing.SwingUtilities; import javax.swing.text.*; public class TestDigitsOnlySpinner { public static void main(String... args) { SwingUtilities.invokeLater((Runnable) new Runnable() { @Override public void run() { JFrame frame = new JFrame("enter digit"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JSpinner jspinner = makeDigitsOnlySpinnerUsingDocumentFilter(); frame.getContentPane().add(jspinner, BorderLayout.CENTER); frame.getContentPane().add(new JButton("just another widget"), BorderLayout.SOUTH); frame.pack(); frame.setVisible(true); } private JSpinner makeDigitsOnlySpinner_BasicAttempt() { JSpinner spinner = new JSpinner(new SpinnerNumberModel()); return spinner; } private JSpinner makeDigitsOnlySpinnerUsingDocumentFilter() { JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, 20, 1)); JSpinner.NumberEditor jsEditor = (JSpinner.NumberEditor) spinner.getEditor(); final Document jsDoc = jsEditor.getTextField().getDocument(); if (jsDoc instanceof PlainDocument) { AbstractDocument doc = new PlainDocument() { private static final long serialVersionUID = 1L; @Override public void setDocumentFilter(DocumentFilter filter) { if (filter instanceof MyDocumentFilter) { super.setDocumentFilter(filter); } } }; doc.setDocumentFilter(new MyDocumentFilter()); jsEditor.getTextField().setDocument(doc); } return spinner; } }); } private static class MyDocumentFilter extends DocumentFilter { @Override public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { if (stringContainsOnlyDigits(string)) { super.insertString(fb, offset, string, attr); } } @Override public void remove(FilterBypass fb, int offset, int length) throws BadLocationException { super.remove(fb, offset, length); } @Override public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { if (stringContainsOnlyDigits(text)) { super.replace(fb, offset, length, text, attrs); } } private boolean stringContainsOnlyDigits(String text) { for (int i = 0; i < text.length(); i++) { if (!Character.isDigit(text.charAt(i))) { return false; } } return true; } } private TestDigitsOnlySpinner() { } }