Search code examples
javahtmlswinguser-interfacejeditorpane

How to append to a JEditorPane without refreshing the whole pane?


Here's my current method for appending text to my JEditorPane editorPane. hmtl is a String which stores the HTML text in the JEditorPane and line is a String which stores the HTML text I want to add to the end of the <body>.

// Edit the HTML to include the new String:
html = html.substring(0, html.length()-18);
html += "<br>"+line+"</p></body></html>";

editorPane.setText(html); // Add the HTML to the editor pane.

This basically just edits the HTML code and resets the JEditorPane, which is a problem because this means the whole JEditorPane refreshes, making images re-load, text flash, etc. I'd like to stop this if possible.

So my question is, how do I append to a JEditorPane without refreshing the whole pane?

I'm using a JEditorPane purely because it can display HTML, any alternatives are welcome.


Solution

  • Another option is to use a HTMLDocument#insertBeforeEnd(...) (Java Platform SE 8).

    Inserts the HTML specified as a string at the end of the element.

    import java.awt.*;
    import java.io.IOException;
    import java.time.LocalTime;
    import javax.swing.*;
    import javax.swing.text.*;
    import javax.swing.text.html.*;
    
    public class EditorPaneInsertTest {
      private Component makeUI() {
        HTMLEditorKit htmlEditorKit = new HTMLEditorKit();
        JEditorPane editor = new JEditorPane();
        editor.setEditorKit(htmlEditorKit);
        editor.setText("<html><body id='body'>image</body></html>");
        editor.setEditable(false);
    
        JButton insertBeforeEnd = new JButton("insertBeforeEnd");
        insertBeforeEnd.addActionListener(e -> {
          HTMLDocument doc = (HTMLDocument) editor.getDocument();
          Element elem = doc.getElement("body");
          String line = LocalTime.now().toString();
          String htmlText = String.format("<p>%s</p>", line);
          try {
            doc.insertBeforeEnd(elem, htmlText);
          } catch (BadLocationException | IOException ex) {
            ex.printStackTrace();
          }
        });
    
        Box box = Box.createHorizontalBox();
        box.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        box.add(Box.createHorizontalGlue());
        box.add(insertBeforeEnd);
    
        JPanel p = new JPanel(new BorderLayout());
        p.add(new JScrollPane(editor));
        p.add(box, BorderLayout.SOUTH);
        return p;
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
          JFrame f = new JFrame();
          f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
          f.getContentPane().add(new EditorPaneInsertTest().makeUI());
          f.setSize(320, 240);
          f.setLocationRelativeTo(null);
          f.setVisible(true);
        });
      }
    }