本文介绍了使JSpinner只读取数字,但也检测退格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个只接受数字的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 to JSpinner, you have implements DocumentFilter for filtering of un_wanted Chars typed from keyboad or pasted from ClipBoard, (thanks to @StanislavL)

      您已自行解决 selectAll()上的 focusGained()包裹在<$ c $中c> invokeLater(),

      you have solve by yourself issues with selectAll() on focusGained() wrapped into invokeLater(),

      示例

      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只读取数字,但也检测退格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 14:29