1

It appears in java there is no way to limit the length. I looked at other examples, and people have created separate classes etc.

I am curious if we can do this using the action event without using other classes.

Here is what I have so far.

   txtTest.addKeyListener(new KeyAdapter()
   public void keyPressed(KeyEvent e)
        {
            int MAX_LEN = 5;
            char c = e.getKeyChar();
            int len = txtTest.getText().length();
            if(len < MAX_LEN)
            {
                return;
            }else
            {
                Logging.info("TOOO LONG");
            }

        }
    });

So i got to the point where if I type in text longer then 5 char. Is there any event that I could trigger off so if they type in the 6 char, it will just be deleted? E.g mimic the backspace or delete key?

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
user1158745
  • 2,402
  • 9
  • 41
  • 60

2 Answers2

2

Sorry but this is a very brittle solution and you should avoid using a KeyListener on a text component as much as possible. For instance what would happen when the user tried to copy and paste text? I'm afraid that in that situation, your code would fail. There are other deeper reasons to avoid use of KeyListeners, but the bottom line is much better would be for you to use a DocumentFilter.

For example

import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;
import javax.swing.text.PlainDocument;


@SuppressWarnings("serial")
public class TextTestGui extends JPanel  {
   private JTextField limitedField = new JTextField(10);

   public TextTestGui() {
      add(limitedField);
      PlainDocument doc = (PlainDocument) limitedField.getDocument();
      doc.setDocumentFilter(new MyDocFilter(5));;
   }

   private class MyDocFilter extends DocumentFilter {

      private int limit;

      public MyDocFilter(int limit) {
         this.limit = limit;
      }

      @Override
      public void insertString(FilterBypass fb, int offset, String string,
            AttributeSet attr) throws BadLocationException {
         Document innerDoc = fb.getDocument();
         StringBuilder sb = new StringBuilder(innerDoc.getText(0, innerDoc.getLength()));
         sb.insert(offset, string);
         if (textOK(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 innerDoc = fb.getDocument();
         StringBuilder sb = new StringBuilder(innerDoc.getText(0, innerDoc.getLength()));
         int start = offset; 
         int end = offset + length;
         sb.replace(start, end, text);
         if (textOK(sb.toString())) {
            super.replace(fb, offset, length, text, attrs);
         }
      }

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

      private boolean textOK(String text) {
         if (text.length() <= limit) {
            return true;
         }
         return false;
      }
   }

   private static void createAndShowGui() {
      TextTestGui mainPanel = new TextTestGui();

      JFrame frame = new JFrame("TextTestGui");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_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();
         }
      });
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
-1

This is one way with the keyListener:

txtTest.addKeyListener(new KeyAdapter(){
    public void keyPressed(KeyEvent e)
    {
        char[] letters = txtTest.getText().toCharArray();
        if(txtTest.getText().length() < 5)
        {
            return;
        }else
        {
            txtTest.setText(""+letters[0]+letters[1]+letters[2]+letters[3]+letters[4]);
        }
    }
});

However you could do it with a while loop:

public void Update(){
    while(true){
        if(txtTest.getText() != null){
            if(!(txtTest.getText().length() < 5))
            {
                char[] letters = txtTest.getText().toCharArray();
                txtTest.setText(""+letters[0]+letters[1]+letters[2]+letters[3]+letters[4]);
            }
        }
    }
}

Unfortunately this is a bit too fast for it to handle so you would need to regulate the update speed, which gets complicated.

  • Again, 1) what will happen when someone uses copy and paste to add text to a JTextField that uses your solution? 2) Have you tested your second solution? And you're doing this `while (true)` loop on the Swing event thread? And the GUI still functions? – Hovercraft Full Of Eels Nov 05 '14 at 20:47