Why textPane.getDocument().getText() Returns Empty String?

642 views Asked by At

What am I doing wrong here in an attempt to get text (with newline characters at their places) from a JTextPane component with content-type "text/html"?

textPane.getText() returns HTML but with empty head and body. textPane.getDocument().getText() returns an empty string.

P.S.: I am also having no line-wrap and other issues in the same code, should I be asking them as independent questions, with the same code?

Code:

package test;

import java.io.IOException;
import java.io.StringReader;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JScrollPane;
import javax.swing.text.BadLocationException;
//import javax.swing.text.StyledEditorKit;

public class TextPaneTester extends javax.swing.JFrame {

    public TextPaneTester() {
        initComponents();
        myInitComponents();
    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {
        contentScrollPane = new javax.swing.JScrollPane();
        content = new javax.swing.JTextPane();
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        contentScrollPane.setViewportView(content);

        // layout code by NetBeans
    }// </editor-fold>                        

    private void myInitComponents(){
        //content.setEditorKit(new StyledEditorKit());
        contentScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        contentScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    }

    private void fetchURL(String url){
        try{
            // URL(URL baseURL[, String relativeURL])
            URL helpURL = new URL(url);
            System.out.println(helpURL);
            this.content.setPage(helpURL);

            try {
                System.out.println("This far!");
                //System.out.println(this.content.getDocument());
                System.out.println("getDocument() on JTextPane gives " + this.content.getDocument());
                System.out.println("getText() on JTextPane gives " + this.content.getText());

                // Why this line retuens an empty string?
                String text = this.content.getDocument().getText(0, this.content.getDocument().getLength());
                System.out.println("getDocument.getText() on JTextPane gives " + text);

                System.out.println("This far 2!");
                // this.translation.setPage(helpURL);
            } catch (BadLocationException ex) {
                System.out.println("Why this far!");
                Logger.getLogger(TextPaneTester.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
        catch (IOException e) {
            System.err.println("Attempted to read a bad URL: " + url);
        }
        // return this.content;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(TextPaneTester.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(TextPaneTester.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(TextPaneTester.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(TextPaneTester.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                String url = "https://en.wikipedia.org/wiki/Virtaal";
                TextPaneTester reader = new TextPaneTester();
                reader.fetchURL(url);
                reader.setVisible(true);
            }
        });
    }

    private javax.swing.JTextPane content;
    private javax.swing.JScrollPane contentScrollPane;
    // End of variables declaration                   
}

Output:

run:
https://en.wikipedia.org/wiki/Virtaal
This far!
getDocument() on JTextPane gives javax.swing.text.html.HTMLDocument@1767743f
getText() on JTextPane gives <html>
  <head>

  </head>
  <body>
    <p style="margin-top: 0">

    </p>
  </body>
</html>

getDocument.getText() on JTextPane gives 
This far 2!
<html>
  <head>

  </head>
  <body>
    <p style="margin-top: 0">

    </p>
  </body>
</html>

Let's see what the parser gives: 
BUILD SUCCESSFUL (total time: 55 seconds)
1

There are 1 answers

4
VGR On BEST ANSWER

As usual, the documentation is the first place you should look:

If the document is loaded asynchronously, the document will be installed into the editor immediately using a call to setDocument which will fire a document property change event, then a thread will be created which will begin doing the actual loading. In this case, the page property change event will not be fired by the call to this method directly, but rather will be fired when the thread doing the loading has finished. It will also be fired on the event-dispatch thread.

You are reading the Document before the page has finished loading. Wait for it to load by monitoring the page property:

this.content.addPropertyChangeListener("page",
    new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent event) {
            System.out.println("getText() on JTextPane gives "
                + content.getText());
        }
    });

this.content.setPage(helpURL);