Reputation: 1738
I have a simple application that limits the number of rows of the user. Calculation of the number of rows successfully performed. I use documentListener to capture the event from the user.
But when the input from the user exceeds the specified number of rows, so I want to disable the user to input again. However, users still can remove the characters they enter.
I've tried using setEditable (false), but this method resulted in JTextArea is not editable again permanently.
This is my code.
....
public Demo2() {
initComponents();
textArea.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
System.out.println("Current Line when method call : "+getLineCountAsSeen(textArea));
if (getLineCountAsSeen(textArea) > maxLine){
JOptionPane.showMessageDialog(null, "Max line : "+maxLine);
try {
textArea.getDocument().remove(textArea.getDocument().getLength()-2, 2);
} catch (BadLocationException ex) {
Logger.getLogger(Demo2.class.getName()).log(Level.SEVERE, null, ex.getMessage());
}
} else {
lblLineCount.setText(String.valueOf(currentLine));
}
}
@Override
public void removeUpdate(DocumentEvent e) {
System.out.println("Current Line when method call : "+getLineCountAsSeen(textArea));
if (getLineCountAsSeen(textArea) > maxLine){
JOptionPane.showMessageDialog(null, "Max line : "+maxLine);
try {
textArea.getDocument().remove(textArea.getDocument().getLength()-2, 2);
} catch (BadLocationException ex) {
Logger.getLogger(Demo2.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
textArea.setEditable(true);
lblLineCount.setText(String.valueOf(getLineCountAsSeen(textArea)));
}
}
@Override
public void changedUpdate(DocumentEvent e) {
System.out.println("Current Line when method call : "+getLineCountAsSeen(textArea));
if (getLineCountAsSeen(textArea) > maxLine){
JOptionPane.showMessageDialog(null, "Max line : "+maxLine);
try {
textArea.getDocument().remove(textArea.getDocument().getLength()-2, 2);
} catch (BadLocationException ex) {
Logger.getLogger(Demo2.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
textArea.setEditable(true);
lblLineCount.setText(String.valueOf(getLineCountAsSeen(textArea)));
}
}
});
}
public static int getLineCountAsSeen(JTextComponent txtComp) {
Font font = txtComp.getFont();
FontMetrics fontMetrics = txtComp.getFontMetrics(font);
int fontHeight = fontMetrics.getHeight();
int lineCount;
try {
int height = txtComp.modelToView(txtComp.getDocument().getEndPosition().getOffset() - 1).y;
lineCount = height / fontHeight + 1;
} catch (Exception e) {
lineCount = 0;
}
if (lineCount == 0) {
System.out.println("Not Set!");
return lineCount;
} else {
currentLine = lineCount;
System.out.println("currentLine : "+currentLine);
return currentLine;
}
}
....
Upvotes: 0
Views: 714
Reputation: 723
try to put DocumentFilter instead of DocumentListener something like
final AbstractDocument abstractDocument = (AbstractDocument) textArea.getDocument();
abstractDocument.setDocumentFilter(new DocumentFilter()
{
@Override
public void remove(final FilterBypass fb, final int offset, final int length) throws BadLocationException
{
super.remove(fb, offset, length);
}
@Override
public void insertString(final FilterBypass fb,
final int offset,
final String string,
final AttributeSet attr) throws BadLocationException
{
if (getLineCountAsSeen(textArea) < 4)
{
super.insertString(fb, offset, string, attr);
}
}
@Override
public void replace(final FilterBypass fb,
final int offset,
final int length,
final String text,
final AttributeSet attrs) throws BadLocationException
{
if (getLineCountAsSeen(textArea) < 4)
{
super.replace(fb, offset, length, text, attrs);
}
}
});
Upvotes: 2