0

I'm trying to load a published Google Doc into a JEditorPane.

Here's the document: link.

Here's how a JEditorPane renders it:

rendered

My observations from the image:

  1. The HTML is being fetched properly.
  2. JEditorPane supports at least some CSS (note the shaded bar at top).
  3. JEditorPane gets really confused at the second <style type="text/css"> block in the HTML source. Is it because the <style> is inside a <div> and not the <head>?
  4. There are odd artifacts (U+00C2, decimal 194; Latin capital letter A with circumflex) at certain spaces in the code, which are actually vanilla U+0020 spaces. Could this be something to do with the byte order? (I've verified that the characters are actually fetched this way by printlning each line.)

I've read this StackOverflow post on the subject and implemented it, but it's not fixing the problem.

I've also noticed that the CSS support is sparse overall (e.g., rendering http://www.stackoverflow.com produces an undesirable result with lots of blue boxes) but no actual HTML code or artifacts are exposed.

Using a JTextPane instead of a JEditorPane produces identical results.

Adding a DTD to the top of the document (tried both XHTML 4.1 Transitional and HTML5's <!DOCTYPE html>) doesn't work either.

Any thoughts on why this happens and how I can fix it?

For better help sooner, here's my SSCCE:

public class GoogleDocSSCCE extends JPanel {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        GoogleDocSSCCE gdv = new GoogleDocSSCCE();
        gdv.docId = "1jG_rNCfVSD8yhHB9ZgA5YicXK_yDOl9T-fItIgmKa-o";
        gdv.refreshDocument();
        frame.setContentPane(gdv);
        frame.setSize(400, 400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private final JEditorPane docPane;
    private String docId;
    private static final String PREFIX = "https://docs.google.com/document/d/";
    private static final String SUFFIX = "/pub";

    public GoogleDocSSCCE() {
        super(new BorderLayout());
        docPane = new JEditorPane();
        docPane.setEditable(false);
        docPane.setContentType("text/html");
        add(new JScrollPane(docPane), BorderLayout.CENTER);
        JButton btnRefresh = new JButton("Refresh Document");
        btnRefresh.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                refreshDocument();
            }
        });
        add(btnRefresh, BorderLayout.NORTH);
    }

    public void refreshDocument() {
        if (docId == null || docId.isEmpty()) {
            docPane.setText(new String());
            return;
        }
        docPane.setText("<html><body>Loading...</body></html>");

        new Thread(new Runnable() {
            @Override
            public void run() {
                boolean success = false;
                try {
                    URL u = new URL(PREFIX + docId + SUFFIX);
                    InputStream stream = u.openStream();
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(stream));
                    StringBuilder sbDocument = new StringBuilder();
                    String line = null;
                    while ((line = br.readLine()) != null) {
                        sbDocument.append(line);
                        sbDocument.append('\n');
                    }
                    docPane.setText(sbDocument.toString());
                    success = true;
                } catch (MalformedURLException e) {
                    JOptionPane.showMessageDialog(GoogleDocSSCCE.this,
                            "The given URL is malformed.",
                            "Error Reading Google Document",
                            JOptionPane.ERROR_MESSAGE);
                    e.printStackTrace();
                } catch (IOException e) {
                    JOptionPane.showMessageDialog(GoogleDocSSCCE.this,
                            "Unable to read the document.",
                            "Error Reading Google Document",
                            JOptionPane.ERROR_MESSAGE);
                    e.printStackTrace();
                } finally {
                    if (!success) {
                        // We failed.
                        docPane.setText(new String());
                    }
                }
            }
        }).start();
    }
}
Community
  • 1
  • 1
wchargin
  • 15,589
  • 12
  • 71
  • 110

1 Answers1

0

See the LoboBrowser api.

Example.

import org.lobobrowser.gui.*;
import org.lobobrowser.main.*;
import javax.swing.*;

public class Browser extends JFrame {

    public Browser(string docid)
    {
        FramePanel browser = new FramePanel();
        add(browser);
        browser.navigate("https://docs.google.com/document/d/" + docid + "/pub/");
    }

    public static void main(String[] args)
    {
        Browser b = new Browser("1jG_rNCfVSD8yhHB9ZgA5YicXK_yDOl9T-fItIgmKa-o");
        b.setSize(400, 400);
        b.setVisible(true);            
    }

}
Sri Harsha Chilakapati
  • 11,744
  • 6
  • 50
  • 91
  • Thanks, but I don't really want a full browser; rather, I just want to render one page. Can I accomplish this? Also I don't want to include a giant (16MB is pretty big for my project) dependency. – wchargin Apr 23 '13 at 13:53
  • Could I use the underlying Cobra library for this purpose? Also, would it be possible to streamline the Cobra library from 3.7MB to just a renderer (no JS, etc. needed)? (even if not, 3.7MB is much better than 16MB) – wchargin Apr 23 '13 at 19:23
  • Apparently [Cobra and LoboBrowser are dead](http://stackoverflow.com/a/9904090/732016) and already generating errors for me (and others). Do you have another suggestion? – wchargin Apr 24 '13 at 00:26