Как я могу создать текстовый компонент Java / Swing, который стилизован и имеет собственный шрифт? Я хочу выделить небольшую часть текста красным цветом, но в то же время использовать собственный (встроенный через Font.createFont) шрифт. JLabel принимает текст HTML, что позволяет мне выделить часть текста, но игнорирует настройки шрифта при рендеринге HTML. Другие текстовые компоненты, такие как JTextArea, будут использовать настраиваемый шрифт, но не будут отображать HTML. Как проще всего сделать и то, и другое?
Вот пример безуспешного использования JTextPane:
JTextPane textPane = new JTextPane();
textPane.setFont(myCustomFont);
textPane.setText(text);
MutableAttributeSet attributes = new SimpleAttributeSet();
StyleConstants.setForeground(attributes, Color.RED);
textPane.getStyledDocument().setCharacterAttributes(
text.indexOf(toHighlight),
toHighlight.length(),
attributes, true
);
Это успешно отображает текст с частью «toHighlight», выделенной красным, но не использует myCustomFont. Обратите внимание, что я могу установить шрифт String с помощью StyleConstants.setFontFamily(), но не пользовательский шрифт.




Вместо этого вам следует попробовать использовать JEditorPane или JTextPane.
Они позволяют использовать богатый стиль в содержании за счет более сложного API. К сожалению, если вы ищете пользовательский интерфейс с префектом пикселей, у них также есть дополнительная проблема: они не поддерживают базовое выравнивание (функция Java 6).
Не могли бы вы показать фрагмент, который показывает, что вы сделали с StyledDocument, и это не работает?
Я добавил к вопросу более подробный пример. Надеюсь, это поможет прояснить то, что я пытаюсь сделать.
Хорошо, теперь я лучше понимаю проблему.
После проверки исходного кода Swing становится ясно, что вы не можете использовать DefaultStyledDocument и заставить его использовать физический шрифт (тот, который вы создали сами с помощью createFont) из коробки.
Однако я думаю, что вы могли бы реализовать свой собственный StyleContext следующим образом:
public class MyStyleContext extends javax.swing.text.StyleContext
{
@Override public Font getFont(AttributeSet attr)
{
Font font = attr.getAttribute("MyFont");
if (font != null)
return font;
else
return super.getFont(attr);
}
}
Тогда вам необходимо:
DefaultStyledDocument с
new MyStyleContext()JTextPaneattributes.addAttribute("MyFont", myCustomFont); в приведенном выше фрагментеЯ не пробовал, но думаю, что это должно сработать, или это может быть хорошим способом исследования.
Сработало отлично. Пример кода ниже. Еще раз спасибо. :)
Решение jfpoilpret сработало отлично! Ради потомков вот рабочий фрагмент кода:
JTextPane textPane = new JTextPane();
textPane.setStyledDocument(new DefaultStyledDocument(new StyleContext() {
@Override
public Font getFont(AttributeSet attr) {
return myCustomFont;
}
}));
textPane.setText(text);
MutableAttributeSet attributes = new SimpleAttributeSet();
StyleConstants.setForeground(attributes, Color.RED);
textPane.getStyledDocument().setCharacterAttributes(
text.indexOf(toHighlight),
toHighlight.length(),
attributes, true
);
Спасибо, jfpoilpret!
У меня была такая же проблема при написании программы на Clojure, т.е. используя шрифты, загруженные из TTF в JEditorPane, отображающие текст HTML. Решение здесь сработало - я скопирую интересную часть здесь для использования в будущем:
(def font1 (with-open [s (FileInputStream. "SomeFont.ttf")]
(.deriveFont (Font/createFont Font/TRUETYPE_FONT s) (float 14))))
(def font2 (Font. "SansSerif") Font/PLAIN 14)
(let [editor (JEditorPane. "text/html" "")]
(.setDocument editor
(proxy [HTMLDocument] []
(getFont [attr]
(if (= (.getAttribute attr StyleConstants/FontFamily)
"MyFont")
font1
font2)))))
Это предполагает, что HTML-документ ссылается на семейство шрифтов MyFont, например с помощью фрагмента CSS, например
p { font-family: "MyFont" }
Обратите внимание, что при этом вы должны обрабатывать запросы шрифта все. Это связано с тем, что доверенное лицо не может вызывать функции-члены суперкласса. Кроме того, если вы хотите обрабатывать шрифты разных размеров, вы должны сделать это «вручную», проверив атрибут StyleConstants / FontSize и соответственно создав шрифт с помощью deriveFont.
Надеюсь, это кому-нибудь поможет :)
Я пробовал оба из них, но все еще с той же проблемой. Если я использую StyledDocument, он игнорирует любые настройки шрифта, которые у меня есть, и настаивает на том, чтобы я устанавливал шрифты с помощью «FontFamily», который допускает только строку, а не пользовательский шрифт.