У 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
.
TextPanePerfectSize
а>. - person trashgod   schedule 22.11.2011