5

I have a code here that i got form MDP's weblog. the sizefilter and the number filter. how do i make a textfield set its filter for two document filters.

Here isthe numberfilter

import javax.swing.text.BadLocationException;
import javax.swing.text.AttributeSet;
import javax.swing.text.DocumentFilter;

public class IntFilter extends DocumentFilter {

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

    StringBuffer buffer = new StringBuffer(string);
    for (int i = buffer.length() - 1; i >= 0; i--) {
        char ch = buffer.charAt(i);
        if (!Character.isDigit(ch)) {
            buffer.deleteCharAt(i);
        }
    }
    super.insertString(fb, offset, buffer.toString(), attr);
}

public void replace(DocumentFilter.FilterBypass fb,
                    int offset, int length, String string, AttributeSet attr) throws BadLocationException {
    if (length > 0) fb.remove(offset, length);
    insertString(fb, offset, string, attr);
}
}

this code is for the sizefilter

import java.awt.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class SizeFilter extends DocumentFilter {

private int maxCharacters;    

public SizeFilter(int maxChars) {
    maxCharacters = maxChars;
}

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

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

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

    if ((fb.getDocument().getLength() + str.length()
            - length) <= maxCharacters)
        super.replace(fb, offs, length, str, a);
    else
        Toolkit.getDefaultToolkit().beep();
}
}
Coral Doe
  • 1,809
  • 2
  • 18
  • 34
Red Dunham
  • 51
  • 2

1 Answers1

3

You've got two options as far as I can see. Either create a composite filter which iterates over each filter:

public class CompositeFilter extends DocumentFilter {
    private final DocumentFilter[] filters;

    public CompositeFilter(DocumentFilter... filters) {
        this.filters = filters;
    }

    public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
        throws BadLocationException {
        for (DocumentFilter filter : filters) {
            filter.insertString(fb, offs, str, a);
        }
    }

    public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a)
        throws BadLocationException {
        for (DocumentFilter filter : filters) {
            filter.replace(fb, offs, length, a);
        }
    }
}

You'd probably want to instantiate the composite with the more restrictive filter first, so you'd construct it like so:

new CompositeFilter(new SizeFilter(10), new IntFilter());

If order is critically important, you might consider rewriting your filters as decorators, e.g. pass the second filter into the first and then call it.

public class SizeFilter extends DocumentFilter {
    private int maxCharacters;    
    private final DocumentFilter delegate;

    public SizeFilter(int maxChars, DocumentFilter delegate) {
        maxCharacters = maxChars;
        this.delegate = delegate;
    }

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

        if ((fb.getDocument().getLength() + str.length()) <= maxCharacters)
            delegate.insertString(fb, offs, str, a);
        else
            Toolkit.getDefaultToolkit().beep();
    }

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

        if ((fb.getDocument().getLength() + str.length() - length) <= maxCharacters)
            delegate.replace(fb, offs, length, str, a);
        else
            Toolkit.getDefaultToolkit().beep();
        }
    }
}
David Grant
  • 13,235
  • 3
  • 52
  • 62
  • 2
    i tried the first code and fixed some errors imports. and theres this one error at this part: `filter.replace(fb, offs, length, a);` this is the error: **method replace in class javax.swing.text.DocumentFilter cannot be applied to given types required: javax.swing.text.DocumentFilter.FilterBypass,int,int,java.lang.String,javax.swing.text.AttributeSet found: javax.swing.text.DocumentFilter.FilterBypass,int,int,javax.print.attribute.AttributeSet** – Red Dunham Oct 12 '12 at 16:00
  • 1
    now that i combined the two filters it just doesnt work right i dunno why. but it somehow limit the textfield only to characters and past the limit i can only type numbers – Red Dunham Oct 13 '12 at 13:44