Я думаю, что ответ "ты не можешь", но я многое не знаю о Swing. Итак:
Мне нужно отобразить многострочный текст только для чтения, символ для персонажа без магической интерпретации, в прямоугольнике, достаточно большом, чтобы его вместить. Возможность выбора региона (и копирования из него) является плюсом.
Неудачные подходы до сих пор:
JLabel("a\nb");
просто не работает, и я не могу представить, почему, потому что это должен быть единственный правильный ответ. JLabel задокументирован для отображения текста, который ему вручают . Но, очевидно, не перевод строки.
У JLabel есть еще одна отвратительная проблема: если текст начинается с <html>
, он снова не отображает текст, который ему вручается, - он переосмысливает его как HTML. Мало того, что документация не упоминает об этом, но теперь у меня есть проблема, что, если пользователям разрешено вводить текст, который появляется в JLabel (и они есть), они могут придерживаться форматирования тегов и вызывать всякие хитрости (и они будут).
Я не вижу способа отключить это; поэтому, чтобы получить точное отображение заданного текста, мне нужно предварительно подготовить текст, чтобы сделать полное цитирование HTML, плюс изменить \ n на <br>
, а затем обернуть все в <html>...</html>
. Я не могу найти ничего в ядре Java, которое бы цитировало - очевидно, вам приходится писать самостоятельно или полагаться на другие библиотеки, такие как apache? Рекомендуемый метод экранирования HTML в Java дает множество причин не полагаться на сторонние библиотеки здесь. И теперь мой код java будет содержать механизм размещения HTML, чтобы я мог надежно отображать текст? Я очень хотел бы избежать этого недокументированного хака. Fr agile.
JTextArea будет обрабатывать многострочный текст, и его можно установить только для чтения. Но я не понимаю, как сказать, чтобы он уменьшился до размера, необходимого для размещения только текста. (JLabel по крайней мере сделал это правильно. [Редактировать: или нет - я вернулся к JLabel, и теперь метки центрируются в своем ряду или расширяются до полного размера - я явно где-то пропускаю настройку]) Я думаю, что должно быть способ сказать ему, чтобы остановить расширение для заполнения строк, но как мне это сделать? setSize(1,1)
не делает этого. Я чувствую, что правильный путь лежит по этому пути, но мне нужен указатель, чтобы он автоматически изменял размеры до минимальных размеров.
Или есть какой-то лучший компонент для этого? Есть ли способ визуализировать текстовую строку как изображение минимального размера? Я мог бы отобразить это в JLabel ...
Я также стараюсь не сканировать весь текст и составлять вертикальную рамку с выравниванием по левому краю JLabels, по одному на строку - вероятно, возможно, но определенно более сложно, чем я хочу когда есть (может быть?) более простое решение.
Обратите внимание, что я не могу жестко указать размер любого компонента. Описания компонентов генерируются сервером и отправляются в приложение, которое генерирует виджеты на основе описаний на лету и добавляет их в контейнеры Box. Сервер не может выполнять вычисления в пикселях; Мне нужно полагаться на Swing, чтобы сделать макет просто на основе порядка вещей в коробках. И в большинстве случаев это означает, что виджеты должны занимать минимально возможный размер.
Как мне?
По указанию я попробовал это. Появилась только одна панель, и у нее не было границы, поэтому я не вижу, сколько места она бы заняла.
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.BorderFactory;
import javax.swing.border.Border;
public class MainTextPane {
public static void main(final String[] args) {
Border loweredbevel = BorderFactory.createLoweredBevelBorder();
final JTextPane pane = new JTextPane();
pane.setText("Hello, this is a\ntwo lined string!");
final JTextPane pane2 = new JTextPane();
pane2.setText("Next!");
pane.setBorder(loweredbevel); //no effect
pane2.setBorder(loweredbevel); //no effect
final JFrame frame = new JFrame("TextPane with new lines.");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(pane);
frame.getContentPane().add(pane2); //clobbered previous pane
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}