【问题标题】:Common method for the JTextFields to accept only numbersJTextFields 只接受数字的常用方法
【发布时间】:2013-06-22 02:00:55
【问题描述】:

我限制我的JTextFields 只接受数字。我为此使用了以下代码。

  // my textboxes
  t1=new JTextField(10);
  t2=new JTextField(10);
  t3=new JTextField(10);

  // for the first one
  t1.addKeyListener(new KeyAdapter() {
        public void keyTyped(KeyEvent e) {
          char c = e.getKeyChar();
          if (!((c >= '0') && (c <= '9') ||
             (c == KeyEvent.VK_BACK_SPACE) ||
             (c == KeyEvent.VK_DELETE))) {
            getToolkit().beep();
            e.consume();
          }
        }
      });

假设我有 20 个 texboxes 需要相同的验证检查。那么我们需要将这段代码写 20 次吗?我可以写一个通用的方法来实现这个吗?我是Swing 的新手。

【问题讨论】:

  • 无论做什么都不要使用 KeyListener,因为这对复制/粘贴没有影响,并且会以其他方式弄乱 JTextField。使用文档过滤器。您可以在本网站和教程中找到这方面的示例。例如:here.
  • 看看这个问题,它应该可以解决你的问题:stackoverflow.com/questions/14215847/… 更准确地说,我的回答。那是一个只接受数字的定制组件。
  • 你得到了很多错误的答案。可怜。
  • 是的,我们知道了。使用 DOcumentFilter 过滤 JTextfield 有更好的方法。但这不是他问题的重点。他的问题是关于再利用
  • 使用JSpinner,如here所示。

标签: java swing jtextfield keylistener documentfilter


【解决方案1】:

//看事件按键被按下 . : 私人无效 montoingresoKeyPressed(java.awt.event.KeyEvent evt) {

    if(Character.isLetter(evt.getKeyChar()))
    {
        //do what you want on this event, when key is pressed named evt
    }

}

【讨论】:

    【解决方案2】:

    如果它在其他地方也需要,我会创建一个私有布尔方法(如果它只在这个类中使用)或公共的。使用正则表达式:

    public boolean checkToBeNumberInput(char c, KeyEvent e){
     if(!char c.matches("[0-9]")||
       (c == KeyEvent.VK_BACK_SPACE) ||
       (c == KeyEvent.VK_DELETE))) {
       getToolkit().beep();
       e.consume();
       return false;
    
     }
    return true;
    }
    

    然后调用这个布尔方法,如果它返回true:

    if(checkToBeNumberInput()==false){
    System.out.println("only numbers are allowed!");
    }
    

    这是一个快速的草稿,但我希望它可以帮助某人

    【讨论】:

      【解决方案3】:

      再次,使用 DocumentFilter,因为这将处理复制和粘贴,这将允许在文档接受文本之前进行过滤

      import javax.swing.*;
      import javax.swing.text.*;
      
      public class DocListenerEg extends JPanel {
         private static final int FIELD_COUNT = 5;
         private JTextField[] fields = new JTextField[FIELD_COUNT];
      
         public DocListenerEg() {
            MyDocFilter myFilter = new MyDocFilter();
            for (int i = 0; i < fields.length; i++) {
               fields[i] = new JTextField(5);
               ((PlainDocument) fields[i].getDocument()).setDocumentFilter(myFilter);
               add(fields[i]);
            }
         }
      
         private class MyDocFilter extends DocumentFilter {
            public void insertString(DocumentFilter.FilterBypass fb, int offset,
                  String text, AttributeSet attr) throws BadLocationException {
               for (char c : text.toCharArray()) {
                  if (!Character.isDigit(c)) {
                     return;
                  }
               }
               fb.insertString(offset, text.toUpperCase(), attr);
            }
      
            public void replace(DocumentFilter.FilterBypass fb, int offset,
                  int length, String text, AttributeSet attrs)
                  throws BadLocationException {
               for (char c : text.toCharArray()) {
                  if (!Character.isDigit(c)) {
                     return;
                  }
               }
               fb.replace(offset, length, text.toUpperCase(), attrs);
            }
         }
      
         private static void createAndShowGui() {
            DocListenerEg mainPanel = new DocListenerEg();
      
            JFrame frame = new JFrame("DocListenerEg");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(mainPanel);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
         }
      
         public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
               public void run() {
                  createAndShowGui();
               }
            });
         }
      }
      

      【讨论】:

      • +1.. @log_in 也见 this(显示其他方式,如 InputVerfierJFormattedTextField
      【解决方案4】:

      按照http://www.jroller.com/dpmihai/entry/documentfilter 中的说明尝试 DocumentFilter

      【讨论】:

        【解决方案5】:

        创建一个名为:

        的类

        NumberOnlyTextField

        使其扩展JTextField,并在构造函数中添加addKeyListener(..) 代码。在那里你有你自己的号码验证文本字段。

        【讨论】:

        • 再一次,永远不要为此使用 KeyListener。请不要推荐这个。不要误导新手。
        • 可能有更好的方法来过滤文本字段。但这不是他问题的重点。他想知道如何在他的代码中应用重用。
        • 尽管如此,这是一种不好的做法。
        • 这不是另一种方法。这是一种错误的方法。请把这个剪掉。
        • 尝试使用“完美无缺”的技术进行复制和粘贴。然后用我的试试。
        【解决方案6】:

        将您的匿名类保存到变量中:

        KeyListener keyListener= new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
              char c = e.getKeyChar();
              if (!((c >= '0') && (c <= '9') ||
                 (c == KeyEvent.VK_BACK_SPACE) ||
                 (c == KeyEvent.VK_DELETE))) {
                getToolkit().beep();
                e.consume();
              }
            }
          }
        

        然后

        t1.addKeyListener(keyListener);
        t2.addKeyListener(keyListener);
        t3.addKeyListener(keyListener);
        ...
        

        【讨论】:

        • 再一次,永远不要为此使用 KeyListener。
        • @HovercraftFullOfEels 为什么不使用 KeyListener?它有效。
        • @SriHarshaChilakapati:它不能用于复制和粘贴!再说一次,请把这个关掉。
        • @OliverWatkins:所以你是说最好阻碍 JTextFields 的能力,这样你就可以使用错误的技术?关键是使用最佳工具来完成这项工作。
        • “它在哪里说他需要能够从文本字段复制和粘贴?” - 将是 OP 提出的下一个问题,因为他们得到了错误的建议。您不能保证通知KeyListener 的顺序,根据它到达您的处理程序的类型,该字段可能已经更新。
        猜你喜欢
        • 2015-03-09
        • 1970-01-01
        • 2021-12-15
        • 2011-04-17
        • 1970-01-01
        • 1970-01-01
        • 2013-10-16
        • 1970-01-01
        相关资源
        最近更新 更多