JEditorPane, предпочтительна ли ширина родительского элемента для отслеживания размера?

У JEditorPane есть очень интересная особенность: кажется, что он отслеживает ширину своего родителя и соответственно определяет предпочтительную высоту, даже если родитель НЕ ЯВЛЯЕТСЯ JViewport.
Под отслеживанием я подразумеваю, что предпочтительная ширина компонента установлена ​​на один из его родителей (возможно, за исключением некоторых вставок).
ScrollableTracksViewportWidth неверно.


Это очень простой код, демонстрирующий этот факт (просто скопируйте и исправьте импорт):
При изменении размера JFrame предпочтительная ширина JEditorPane (в моей среде) всегда равна frame.width-14 (конечно, 14 может быть зависит от графической системы).

q1) Отслеживание ширины родителя (не окна просмотра) — это хорошо. Могу ли я на это положиться? Насколько я знаю, это недокументированная функция. Подробнее! Просто замените new JEditorPane() на new JTextPane(), более богатый подкласс JEditorPane, и функция исчезнет.

q2) Мне кажется, что это "отслеживание" происходит через "настройку" размера JEditorPane. Это означает, что СНАЧАЛА должен быть установлен размер (ширина), а затем высота предпочтительного размера будет в порядке. Это правильно?

q3) Почему JTextPane не имеет этой функции?

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) Более четкий вопрос. Как предполагалось в q2, установка размера позволяет отслеживать. Но только для JEditorPane, НЕ для JTextPane. Как я могу сделать это и для JTextPane?

это работает:

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();

    }

это не так. Вместо JEditorPane используется JTextPane:

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();

}

ОБНОВЛЕНИЕ 1
Резюме: "свойство размера дорожки" наблюдается в JEditorPane, но ничего похожего не существует в JTextPane.
Небольшой, но важный шаг вперед: загрузка HTML-документа в JEditorPane позволяет этой функции исчезнуть и из JEditorPane.
На данный момент эта функция кажется реализованной реализацией Document, а не самой JEditorPane (или JTextPane)! В случае JEditorPane документ имеет значение javax.swing.text.PlainDocument. Когда вы делаете:

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

ты получишь:

javax.swing.text.html.HTMLDocument

Я также заметил, что хороший javax.swing.text.PlainDocument, который дает нам эту замечательную услугу «вычисления высоты» компонента, когда ширина задается через setSize», не может быть назначен JTextPane, который ожидает экземпляр StyledDocument!

Теперь я проверю, какие другие текстовые компоненты могут использовать PlainDocument.


person AgostinoX    schedule 20.11.2011    source источник
comment
Можете ли вы предоставить URL для TextPanePerfectSize?   -  person AgostinoX    schedule 21.11.2011


Ответы (1)


Я рекомендую вам добавить компонент на панель содержимого JFrame вместо использования метода add(). Также установите макет на панели содержимого, и все размеры будут автоматически изменены.

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

С Уважением

person user1052080    schedule 15.12.2011