JEditorPane, является предпочтительным размер отслеживания родительской ширины? - PullRequest
3 голосов
/ 20 ноября 2011

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

    }

это не так. Он был использован JTextPane вместо 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();

}

ОБНОВЛЕНИЕ 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.

1 Ответ

0 голосов
/ 15 декабря 2011

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

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

Привет

...