Question

I'm trying to limit the char input on multiple jtextfield. The two fields has different char limit and at the same time they cannot accept white space as their 1st char... for example the 1st field has only 5 char limit then the 2nd field has 10char limit.. I'm stuck on this problem here is the code that I am using:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

 public class Restriction {

    public Restriction() {
        initComponents();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Restriction();
            }
        });
    }

    private void initComponents() {
        GridBagConstraints Cons = new GridBagConstraints();
        JFrame frame = new JFrame();
        JPanel panel = new JPanel(new GridBagLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JTextField jtf = new JTextField(20);
        JTextField jtf2 = new JTextField(20);
        //add filter to document
        ((AbstractDocument) jtf.getDocument()).setDocumentFilter(new MyDocumentFilter());
        MyDocumentFilter.charLimit(5);
        ((AbstractDocument) jtf2.getDocument()).setDocumentFilter(new MyDocumentFilter());
        MyDocumentFilter.charLimit(10);
        Cons.gridy = 0;
        panel.add(jtf, Cons);
        Cons.gridy = 1;
        panel.add(jtf2,Cons);  
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }
}

class MyDocumentFilter extends DocumentFilter {

    static int Limit;

    public static void charLimit(int Limitation){
        Limit = Limitation;
    }

    @Override
    public void replace(FilterBypass fb, int i, int i1, String string, AttributeSet as) throws BadLocationException {
        //we want standard behavior if we are not placing space at start of JTextField
        //or if we are placing text at start of JTextField but first character is not whitespace
        if ( i!=0 && i< Limit || ( i==0 && !Character.isWhitespace(string.charAt(0)) ) ){
            super.replace(fb, i, i1, string, as);
        }else{
            System.out.println("no spaces allowed");
        }
    }

    @Override
    public void remove(FilterBypass fb, int i, int i1) throws BadLocationException {
        super.remove(fb, i, i1);
    }

    @Override
    public void insertString(FilterBypass fb, int i, String string, AttributeSet as) throws BadLocationException {
        super.insertString(fb, i, string, as);

    }
}
Was it helpful?

Solution

I would use javax.swing.text.Document

You can initiate it like:

 public static Document createTextDocument(int maxLength){
        return new TextDocument(maxLength);
    }

...

Document document = createTextDocument(5); // limit to 5 chars
textField1.setDocument(document);

document = createTextDocument(10); // limit to 10 chars
textField2.setDocument(document);

Here is custom TextDocument class:

public class TextDocument extends PlainDocument{


    private static final long serialVersionUID = 1L;
    private int maxLength = Integer.MAX_VALUE;

    TextDocument(){}
    TextDocument(int maxlength){this.maxLength=maxlength;}

     public void setMaxLength(int maxLength) {
            if (maxLength < 0)
                throw new IllegalArgumentException("maxLength<0");
            this.maxLength = maxLength;
        }

     public void insertString(int offset, String str, AttributeSet attr)
     throws BadLocationException {
         if (validateLength(offset, str) == false)
                return;

            super.insertString(offset, str, attr);
     }

     private boolean validateLength(int offset, String toAdd) {
            String str_temp;
            //String str_text = "";
            String str1 = "";
            String str2 = "";
            try {
                str1 = getText(0, offset);
                str2 = getText(offset, getLength() - offset);
            } catch (Exception e) {
                e.printStackTrace();
            }

            str_temp = str1 + toAdd + str2;
            if (maxLength < str_temp.length()) {
                beep();
                return false;
            } else
                return true;

        }

        private void beep() {
            java.awt.Toolkit.getDefaultToolkit().beep();
        }
}

Hope it will help

OTHER TIPS

You can avoid the complication of using a Document by overriding the keyTyped event for each JTextField:

txtGuess = new JTextField();
txtGuess.addKeyListener(new KeyAdapter() {
    public void keyTyped(KeyEvent e) { 
        if (txtGuess.getText().length() >= 3 ) // limit textfield to 3 characters
            e.consume(); 
    }  
});

This limits the number of characters in a guessing game text field to 3 characters, by overriding the keyTyped event and checking to see if the textfield already has 3 characters - if so, you're "consuming" the key event (e) so that it doesn't get processed like normal.

Hope it's of help.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top