javaswingcharacterjtextareadocumentlistener

AddDocumentListener's variable scope when creating two titles (using TitledBorder) in Java Swing


Hello I am trying to display one String ("Character Count: ") and one dynamic character count on the bottom of JTextArea. When I run this code below, there is a panel that opens up without characterCountTitle. Only when I start typing, characterCountTitle displays and the number is correctly dynamic.

My goal is to show characterCountTitle (string + character count) as soon as the panel is open to users.

private void initComponents() {
    this.notePanel.getNoteDocument().addDocumentListener(new DocumentListener() {

        TitledBorder characterCountTitle;
        Border emptyBorder;

        public void insertUpdate(DocumentEvent e) {
            displayEditInfo(e);
        }

        public void removeUpdate(DocumentEvent e) {
            displayEditInfo(e);
        }

        public void changedUpdate(DocumentEvent e) {
            displayEditInfo(e);
        }

        private void displayEditInfo(DocumentEvent e) {
            Document document = e.getDocument();

            emptyBorder = BorderFactory.createEmptyBorder();

            //displays a string of "Character Count: " and another string of dynamic character count 
            characterCountTitle = BorderFactory.createTitledBorder(emptyBorder, "Character Count: " +  document.getLength());
            characterCountTitle.setTitlePosition(TitledBorder.BOTTOM);
            panel.setBorder(characterCountTitle);
        }
    });

    this.panel.add(notePanel, BorderLayout.CENTER);
    this.panel.add(navigation.buildPanel(), BorderLayout.SOUTH);
}

Due to this issue, I was trying to create two titles; one for string(outside of addDocumentListener) and one for character count (inside displayEditInfo method), but it messes up the variable scope.

I'd greatly appreciate your input!


Solution

  • You may simply create and add your border outside of the DocumentListener, and just change the title text on document events :

    private void initComponents() {
    
    
            Border emptyBorder = BorderFactory.createEmptyBorder();
            final TitledBorder characterCountTitle = BorderFactory.createTitledBorder(emptyBorder, "Character Count:");
            characterCountTitle.setTitlePosition(TitledBorder.BOTTOM);
            panel.setBorder(characterCountTitle);
    
            this.notePanel.getNoteDocument().addDocumentListener(new DocumentListener()                 {
    
            public void insertUpdate(DocumentEvent e) {
                displayEditInfo(e);
            }
    
            public void removeUpdate(DocumentEvent e) {
                displayEditInfo(e);
            }
    
            public void changedUpdate(DocumentEvent e) {
                displayEditInfo(e);
            }
    
            private void displayEditInfo(DocumentEvent e) {
                Document document = e.getDocument();
    
    
                //displays a string and dynamic character count
                characterCountTitle.setTitle("Character Count: " +  document.getLength());
                panel.repaint();
    
            }
        });
    
        this.panel.add(notePanel, BorderLayout.CENTER);
        this.panel.add(navigation.buildPanel(), BorderLayout.SOUTH);
    }