3

JEditorPane seems to have a very interesting feature: it seems to track its parent width, and determines the preferred height accordingly, also if the parent IS NOT a JViewport.
By track i mean that the preferred width of the component is set to the one of its parent (maybe apart from some insets).
The ScrollableTracksViewportWidth is false.


This is the very simple code that demonstrates this fact (just copy and fix imports):
When the JFrame is resized, the preferred width of the JEditorPane (in my environement) is always frame.width-14 (of course 14 may be graphical-system specific).

q1) Tracking the parent (non viewport) width is good. Can I rely on it? As far as i know this is an undocumented feature.More! Just replace new JEditorPane() with new JTextPane(), a richer subclass of JEditorPane, and the feature disappear.

q2) It seems to me that this "tracking" happens through the "setting" of the JEditorPane size. This means that FIRST the size (width) must be set, then the preferred size height will be ok. Is it right?

q3) Why JTextPane has not this feature?

public class SSCE01 extends JFrame {

    public static void main(String[] a) {
        new SSCE01().setVisible(true);
    }

    public SSCE01() {
        final JEditorPane ep = new JEditorPane();
        add(ep);
        addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                Dimension ps = getSize();
                System.out.println("Frame size               : " + ps.width + " x " + ps.height);
                ps = ep.getPreferredSize();
                System.out.println("JEditorPane preferredSize: " + ps.width + " x " + ps.height);

            }
        });
        pack();
    }
}

q4) More clear question. As hypothesized in q2, setting the size allows the tracking. But just for JEditorPane, NOT for JTextPane. How can I accomplish this for the JTextPane too?

this works:

public SSCE02() {
        JEditorPane ep = new JEditorPane();
        ep.setText("this is a very very long text. veeeeery long, so long that it will never fit into one 100 pixels width row");
        ep.setSize(new Dimension(100,Integer.MAX_VALUE));
        add(ep);

        pack();

    }

this doesn't. It has been used a JTextPane in place of JEditorPane:

public SSCE02() {

    JEditorPane ep = new JTextPane();
    ep.setText("this is a very very long text. veeeeery long, so long that it will never fit into one 100 pixels width row");
    ep.setSize(new Dimension(100,Integer.MAX_VALUE));
    add(ep);

    pack();

}

UPDATE 1
Summary: the "track Size property" is observed in JEditorPane but nothing similar exists in JTextPane.
A little but significative step further: Loading an HTML document into JEditorPane lets the feature disappear from JEditorPane too.
At this point, the feature seems implemented by the Document implementation and not by the JEditorPane (or JTextPane) itself! In the case of JEditorPane, the Document is javax.swing.text.PlainDocument. When you do:

URL url = HTMLInComponents01.class.getResource("sample.html");
jEditorPane1.setPage(url);
System.out.println(jEditorPane1.getDocument().getClass().getName());

you'll get:

javax.swing.text.html.HTMLDocument

I also notice that the good javax.swing.text.PlainDocument that gives us this great service of "calculating the height" of a component when the width is given through setSize" isn't assignable to a JTextPane, that expects a StyledDocument instance!

Now I'll verify which other text components are capable of using PlainDocument.

Frakcool
  • 10,915
  • 9
  • 50
  • 89
AgostinoX
  • 7,477
  • 20
  • 77
  • 137
  • Can you provide the URL for "TextPanePerfectSize"? – AgostinoX Nov 21 '11 at 16:08
  • See also [`TextPanePerfectSize`](http://stackoverflow.com/questions/3315681/how-can-i-measure-calculate-the-size-a-document-needs-to-render-itself/3318949#3318949). – trashgod Nov 21 '11 at 21:44

1 Answers1

0

I recommend you add the component to the JFrame's content pane instead of using the add() method. Also set a layout on the content pane and it will all resize automatically.

JFrame f = new JFrame();
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(new JTextPane());

Regards

user1052080
  • 430
  • 5
  • 12