如何创建既具有样式又具有自定义字体的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。请注意,我可以使用StyleConstants.setFontFamily()
设置字符串字体,但不能设置自定义字体。
答案 0 :(得分:2)
好的,我现在看到问题了。
在检查了一些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()
JTextPane
attributes.addAttribute("MyFont", myCustomFont);
我没有尝试,但我认为它应该有用,或者它可能是一条很好的研究途径。
答案 1 :(得分:2)
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!
答案 2 :(得分:0)
您应该尝试使用JEditorPane或JTextPane。
它们允许内容丰富的风格,代价是更复杂的API。 不幸的是,如果你正在寻找一个像素完美的UI,它们还有一个额外的问题:它们不支持基线对齐(Java 6功能)。
答案 3 :(得分:0)
在Clojure中编写程序时遇到了同样的问题,即。在JEditorPane中使用从TTF加载的字体显示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" }
请注意,您必须处理所有字体请求。这是因为 proxy 的限制无法调用超类的成员函数。此外,如果要处理不同的字体大小,则必须“手动”执行此操作,检查StyleConstants / FontSize属性并相应地使用deriveFont创建字体。
我希望这会对某人有所帮助:)。