问题描述
我正在尝试创建一个只接受数字的JSpinner,但我也想让它读取/响应退格。
I'm trying to make a JSpinner that will only accepts numbers but I also want it to read/respond to backspace.
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语言编写的。
The code above works to make only numbers but this doesn't allow me to backspace. I found some examples on this site but they were written for C.
推荐答案
-
你是正确的
JFormattedTextField
没有正确实现到JSpinner
,你有实现DocumentFilter
用于过滤不需要的Chars
从keyboad键入或从ClipBoard粘贴,(感谢@StanislavL)you are right
JFormattedTextField
isn't correctly implemented toJSpinner
, you have implementsDocumentFilter
for filtering of un_wantedChars
typed from keyboad or pasted from ClipBoard, (thanks to @StanislavL)您已自行解决
selectAll()
上的focusGained()
包裹在<$ c $中c> invokeLater(),you have solve by yourself issues with
selectAll()
onfocusGained()
wrapped intoinvokeLater()
,示例
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() { } }
这篇关于使JSpinner只读取数字,但也检测退格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!