如何限制TextField只接受小于10的数字?

时间:2014-01-18 15:16:24

标签: java swing jtextfield restrictions

如何限制文本字段只接受小于10的数字,没有单词,没有空格或任何其他特殊字符?

4 个答案:

答案 0 :(得分:4)

最简单的方法是使用专为此设计的组件:

JSpinner spinner = new JSpinner();
spinner.setModel(new SpinnerNumberModel(0, null, 10, 1));

技术上JSpinner不是从JTextField派生的,它在内部使用一个用于编辑器部分,因此看起来像一个(加上它有额外的按钮来通过鼠标点击更改数字)。

答案 1 :(得分:3)

同样,DocumentFilter是解决这个问题的一种方法:

import javax.swing.*;
import javax.swing.text.*;

@SuppressWarnings("serial")
public class DocFilterExample extends JPanel{
   JTextField textfield = new JTextField(5);

   public DocFilterExample() {
      PlainDocument doc = (PlainDocument) textfield.getDocument();
      doc.setDocumentFilter(new MaxNumberDocFilter(10));

      add(textfield);
   }

   private class MaxNumberDocFilter extends DocumentFilter {
      private int maxNumber;

      public MaxNumberDocFilter(int maxnumber) {
         this.maxNumber = maxnumber;
      }

      private boolean verifyText(String text) {
         if (text.isEmpty()) {
            return true; // allow for a blank text field
         }
         int value = 0;
         try {
            value = Integer.parseInt(text);
            if (value >= 0 && value < maxNumber) {
               return true; // if it's a number in range, it passes
            }
         } catch (NumberFormatException e) {
            return false;  // if it's not a number, it fails.
         }
         return false;
      }

      @Override
      public void insertString(FilterBypass fb, int offset, String string,
               AttributeSet attr) throws BadLocationException {

         Document doc = fb.getDocument();
         String oldText = doc.getText(0, doc.getLength());
         StringBuilder sb = new StringBuilder(oldText);
         sb.insert(offset, string);

         if (verifyText(sb.toString())) {
            super.insertString(fb, offset, string, attr);
         }

      }

      @Override
      public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
               throws BadLocationException {
         Document doc = fb.getDocument();
         String oldText = doc.getText(0, doc.getLength());
         StringBuilder sb = new StringBuilder(oldText);

         sb.replace(offset, offset + length, text);
         if (verifyText(sb.toString())) {
            super.replace(fb, offset, length, text, attrs);
         }
      }

      @Override
      public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
         Document doc = fb.getDocument();
         String oldText = doc.getText(0, doc.getLength());
         StringBuilder sb = new StringBuilder(oldText);

         sb.replace(offset, offset + length, "");

         if (verifyText(sb.toString())) {
            super.remove(fb, offset, length);            
         }
      }
   }

   private static void createAndShowUI() {
      JFrame frame = new JFrame("Eg");
      frame.getContentPane().add(new DocFilterExample());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}
  • 优点:
    • 不需要任何错误消息。相反,它只是阻止输入错误输入。
    • 适用于剪切和粘贴。
  • 缺点:
    • 没有给出错误消息,因此用户不知道为什么他的文本不被接受。
    • 它有点长而且笨重。
    • 不容易“链接” - 一次使用多个过滤器,Rob Camick做了一些工作。

答案 2 :(得分:0)

试试这个: -

JTextField textField = new JTextField();

textField.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
         //do stuff here when enter pressed
        String text = textField.getText();
        if(text!=null && !text.equals("")){
            char c = evt.getKeyChar();
            int val=Integer.parseInt(c);
            if(val>=48 && val<=57){
                if(Integer.parseInt(text)<=10){
                    //Its valid and allowed
                }else{
                    //Its invalid, show error message here
                }
            }else{
                //Show message only numbers are allowed
                return false;
            }           
        }

    }
});

希望它会对你有所帮助。

答案 3 :(得分:-1)

使用Swing Javabuilders,您可以在YML(下面)中定义GUI,包括文本字段验证。

你在你的gui中用yaml文件声明,这是Person.java的一个例子,名为Person.Yaml:

JFrame(name=frame, title=frame.title, size=packed, defaultCloseOperation=exitOnClose):
        - JButton(name=save, text=button.save, onAction=[$validate,save,done])
        - JButton(name=cancel, text=button.cancel, onAction=[$confirm,cancel])
        - MigLayout: |
              [pref]              [grow,100]     [pref]             [grow,100]
              "label.firstName"   txtFirstName   "label.lastName"   txtLastName
              "label.email"       txtEmail+*
              >save+*=1,cancel=1
    bind:
        - txtFirstName.text: person.firstName
        - txtLastName.text: person.lastName
        - txtEmail.text: person.emailAddress
    validate:
        - txtFirstName.text: {mandatory: true, label: label.firstName}
        - txtLastName.text: {mandatory: true, label: label.lastName}
        - txtEmail.text: {mandatory: true, emailAddress: true, label: label.email}

以上三个街区如下:

Swing Classes(JFrame和JButton)以及布局管理器,嵌入式 JLabels(label.firstNamelabel.lastName)被'标签'识别他们的声明的一部分和JTextFields(txtLastNametxtFirstNametxtEmail),这些都是由其名称的txt部分识别的。

数据绑定:这会将JTextArea.text绑定到class.fieldName,以便在将数据输入JTextField时将其映射到字段。

验证:这是验证文本的位置。请注意,JButton部分中名为Save的onAction具有运行内置验证方法的条目$validate。这将从validate块中读取验证类型:

 txtFirstName.text: {mandatory: true, label: label.firstName}

其中声明字段必须填入mandatory: true),而txtEmail必须填写有效的电子邮件地址(emailAddress: true)。更多验证概述如下。

一旦宣布了GUI,就可以在java文件中运行它。

    private BuildResult result;
    .....
    public methodName(){
        .....
    result = SwingJavaBuilder.build(this).setVisible(true);
    }

此方法(build(this))引用同名的.yml文件(因此您的gui位于person.yml中,并与person.java配对)。

文档中提供了更多验证:

validate:
      - mandatory.text: {label: Mandatory Field, mandatory: true}
      - date.text: {label: Date Field, dateFormat: "yyyy/mm/dd"}
      - email.text: {label: E-Mail, email: true}
      - minmax.text: {label: Min/Max Length, minLength: 5, maxLength: 10}
      - regex.text: {label: Regex, regex: "[a-zA-Z0-9]+"}
      - regex2.text: {label: Regex, regex: "[a-zA-Z0-9]+", 
               regexMessage: "''{0}'' must be a number or letter"}
      - long.text: {label: Min/Max Long, minValue: 5, maxValue: 50, mandatory: true}

因此,您希望将最后一个long.text用于此规范:

myValidNumberField{label: Number less than ten, maxValue: 10, mandatory: true}`

有关github页面的更多信息,关于如此设置您的GUI。