Вопрос

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;
        }
    }
....
Это было полезно?

Решение

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);
        }
      }
    });
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top