Question

I am using a jtextarea and a document filter. I want as soon as the user presses "b" in it, the whole text to be deleted, except, let's say the first letter. How can I accomplish this. Some ideas would be useful.

public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
        if ("b".equalsIgnoreCase(text)) {
            //what here???
        }
        super.replace(fb, offset, length, text, attrs); 
    }

Thanks a lot

Was it helpful?

Solution

You want to use the offset and set to 0 (the beginning of the document), and use the document length to pass the length, and the text to replace is nothing ""

@Override
public void replace(FilterBypass fb, int offset, int length, String str, AttributeSet attr)
        throws BadLocationException {
    if ("b".equalsIgnoreCase(str)) {
        super.replace(fb, 0, fb.getDocument().getLength(), "", attr);
        return;
    } else {
        super.replace(fb, offset,length, str, attr);
    }  
}

Complete Example

import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;

public class TestBFilter {

    public TestBFilter() {
        JTextArea field = createTextArea();
        JFrame frame = new JFrame();
        frame.setLayout(new GridBagLayout());
        frame.add(new JScrollPane(field));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JTextArea createTextArea() {
        JTextArea field = new JTextArea(10, 20);
        field.setLineWrap(true);
        field.setWrapStyleWord(true);
        ((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentFilter() {
            @Override
            public void replace(FilterBypass fb, int offset, int length, String str, AttributeSet attr)
                    throws BadLocationException {
                if ("b".equalsIgnoreCase(str)) {
                    super.replace(fb, 0, fb.getDocument().getLength(), "", attr);
                    return;
                } else {
                    super.replace(fb, offset, length, str, attr);
                }
            }
        });
        return field;
    }

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

EDIT

"testing this however and pressing b makes the whole text to be erased, including first letter"

Just get the first letter of the document, and replace the text with that, if you want to first letter to remain.

    if ("b".equalsIgnoreCase(str)) {
        String text = fb.getDocument().getText(0, 1);
        super.replace(fb, 0, fb.getDocument().getLength(), text, attr);
    } else {
        super.replace(fb, offset, length, str, attr);
    }

OTHER TIPS

Using a DocumentListener I got this to work:

    public void insertUpdate(DocumentEvent e) {
        if (area.getText().charAt(e.getOffset()) == 'b') {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                     area.setText("" + area.getText().charAt(0));
                }
            });
        }
    }

On insertUpdate, if the char at the offset is b, the text is set to the char at index 0.

Here's my full test case if you want to run it/see how it works:

import javax.swing.*;
import java.awt.*;
import javax.swing.event.*;
import javax.swing.text.*;

public class Testgui extends JFrame
{
    JTextArea area;

    public Testgui()
    {
        super("Test Frame");
        setVisible(true);
        setSize(500,500);

        area = new JTextArea();
        area.getDocument().addDocumentListener(new DListener());
        add(area);
    }

    public class DListener implements DocumentListener {     
        public void insertUpdate(DocumentEvent e) {
            if (area.getText().charAt(e.getOffset()) == 'b') {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                         area.setText("" + area.getText().charAt(0));
                    }
                });
            }
        }
        public void removeUpdate(DocumentEvent e) {
            //
        }
        public void changedUpdate(DocumentEvent e) {
            //
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top