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
.