Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I limit the amount of characters in JTextPane as the user types (Java)

I need to not allow any characters to be entered after X have been typed. I need to send a beep after X characters have been typed. I know how to do this after the user presses enter, but I need to do it before the user presses enter. The approach I found from Oracle's site is to add a DocumentSizeFilter to the JTextPane. I can't get this to notify the user when they have gone over (it doesn't work until they press enter). This is a sample of what I have.

public class EndCycleTextAreaRenderer extends JTextPane
implements TableCellRenderer {

private final int maxNumberOfCharacters = 200;

public EndCycleTextAreaRenderer() {
    StyledDocument styledDoc = this.getStyledDocument();
    AbstractDocument doc;
    doc = (AbstractDocument)styledDoc;
    doc.setDocumentFilter(new DocumentSizeFilter(maxNumberOfCharacters ));

}
like image 969
Boundless Avatar asked Feb 22 '23 19:02

Boundless


2 Answers

Override the insertString method of the document in the JTextPane so that it doesn't insert any more characters once the maximum has been reached.

For example:

JTextPane textPane = new JTextPane(new DefaultStyledDocument() {
    @Override
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
        if ((getLength() + str.length()) <= maxNumberOfCharacters) {
            super.insertString(offs, str, a);
        }
        else {
            Toolkit.getDefaultToolkit().beep();
        }
    }
});

Update:

You can change your class as follows:

public class EndCycleTextAreaRenderer extends JTextPane implements TableCellRenderer {

    private final int maxNumberOfCharacters = 200;

    public EndCycleTextAreaRenderer() {
        setStyledDocument(new DefaultStyledDocument() {
            @Override
            public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
                if ((getLength() + str.length()) <= maxNumberOfCharacters) {
                    super.insertString(offs, str, a);
                } else {
                    Toolkit.getDefaultToolkit().beep();
                }
            }
        });
    }
}
like image 154
dogbane Avatar answered Feb 24 '23 09:02

dogbane


Here is a sample program, for you where, as you enter the fourth time into the TextPane it will beep, without even you pressing the Enter key:

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

import java.awt.Toolkit;

public class TextPaneLimit extends JFrame
{
    private JPanel panel;
    private JTextPane tpane;
    private AbstractDocument abDoc;

    public TextPaneLimit()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        panel = new JPanel();
        tpane = new JTextPane();

        Document doc = tpane.getStyledDocument();
        if (doc instanceof AbstractDocument) 
        {    
            abDoc = (AbstractDocument)doc;
            abDoc.setDocumentFilter(new DocumentSizeFilter(3));
        }

        panel.add(tpane);

        add(panel);
        pack();
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    new TextPaneLimit().setVisible(true);
                }
            });
    }
}

class DocumentSizeFilter extends DocumentFilter {

   private int max_Characters;
   private boolean DEBUG;

   public DocumentSizeFilter(int max_Chars) {

      max_Characters = max_Chars;
      DEBUG = false;
   }

   public void insertString(FilterBypass fb
                            , int offset
                              , String str
                                , AttributeSet a) 
   throws BadLocationException {

      if (DEBUG) {

         System.out.println("In DocumentSizeFilter's insertString method");
      }

      if ((fb.getDocument().getLength() + str.length()) <= max_Characters) 
         super.insertString(fb, offset, str, a);
      else 
         Toolkit.getDefaultToolkit().beep();
   }

   public void replace(FilterBypass fb
                       , int offset, int length
                       , String str, AttributeSet a)
   throws BadLocationException {

      if (DEBUG) {
         System.out.println("In DocumentSizeFilter's replace method");
      }
      if ((fb.getDocument().getLength() + str.length()
           - length) <= max_Characters) 
         super.replace(fb, offset, length, str, a);
      else
         Toolkit.getDefaultToolkit().beep();
   }
}

Hope this might help.

like image 23
nIcE cOw Avatar answered Feb 24 '23 09:02

nIcE cOw