У меня есть a JEditorPane
то, которое отображено во всплывающем окне, инициировало через кнопку. Область содержит длинный текст, поэтому это вложило внутри a JScrollPane
, и всплывающее окно ограничивается к максимальному размеру 300 x 100:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String text = "Potentially looooooong text. " +
"Lorem ipsum dolor sit amet, consectetuer" +
"adipiscing elit, sed diam nonummy nibh euismod " +
"tincidunt ut laoreet dolore magna aliquam" +
"adipiscing elit, sed diam nonummy nibh euismod" +
"erat volutpat. Ut wisi enim ad minim veniam, " +
"quis nostrud exerci tation.";
final JEditorPane editorPane = new JEditorPane("text/html", text);
editorPane.setEditable(false);
final JButton button = new JButton("Trigger Popup");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JPopupMenu popup = new JPopupMenu();
popup.setLayout(new BorderLayout());
popup.add(new JScrollPane(editorPane));
Dimension d = popup.getPreferredSize();
int w = Math.min(300, d.width);
int h = Math.min(100, d.height);
popup.setPopupSize(w, h);
Dimension s = button.getSize();
popup.show(button, s.width / 2, s.height / 2);
}
});
JFrame f = new JFrame("Layout Demo");
f.setSize(200, 200);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
f.getContentPane().add(button);
f.setVisible(true);
}
});
}
Когда JEditorPane
экземпляр показывают впервые (т.е. когда кнопка нажата однажды), это так или иначе, кажется, сообщает о предпочтительной высоте, которая является слишком маленькая (1):
После последующих нажатий кнопок расположение состоит в том, как можно было бы ожидать это (2):
Как я могу осуществить/наложить надлежащий предпочтительный размер, таким образом, он всегда инициализировал бы как (2)?
JEditorPane
не может вычислить свою окончательную предпочтительную ширину и высоту одновременно, она должна знать одну, прежде чем сможет вычислить другое.
На первом проходе JEditorPane
вычисляет свою предпочтительную высоту, исходя из предположения, что ее ширина будет неограниченной, поэтому она возвращает высоту одной строки (поскольку текст не содержит разрывов строк).
На втором проходе ширина уже была установлена (ограничена размером первого JPopupMenu
), и теперь, когда он знает максимальную ширину, он может вычислить, какой высоты он должен быть.
Таким образом, самое простое решение - просто установить максимальную ширину всякий раз, когда вы устанавливаете текст.
String text = "Potentially looooooong text. " +
"Lorem ipsum dolor sit amet, consectetuer" +
"adipiscing elit, sed diam nonummy nibh euismod " +
"tincidunt ut laoreet dolore magna aliquam" +
"adipiscing elit, sed diam nonummy nibh euismod" +
"erat volutpat. Ut wisi enim ad minim veniam, " +
"quis nostrud exerci tation.";
final JEditorPane editorPane = new JEditorPane("text/html", text);
editorPane.setSize(300, Integer.MAX_VALUE);
editorPane.setEditable(false);
Не беспокойтесь о том, чтобы сделать его слишком большим, он все равно сожмется, чтобы соответствовать содержимому (это вы увидите, если измените текст на «Hello, World!»
.