我不确定为什么同时使用 TextAttribute.FONT 和 TextAttribute.SUPERSCRIPT 时不会合并这些属性,但 @thrashgod 的 answer 给出了您的解决方案的想法。
将Font对象分离成:
- 字体大小 = 60
- 字体系列 =
Font.SANS_SERIF
- 字体样式=
Font.PLAIN
由于样式很简单,我们只需要字体大小和字体系列,所以我以这样的方式结束:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class FormulaDrawer {
private JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new FormulaDrawer()::createAndShowGui);
}
private void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
Drawer drawer = new Drawer();
frame.add(drawer);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
@SuppressWarnings("serial")
class Drawer extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
AttributedString trig = new AttributedString("a2 + b2 = c2");
trig.addAttribute(TextAttribute.FAMILY, "Comic Sans MS"); //Change to Font.SANS_SERIF constant
trig.addAttribute(TextAttribute.SIZE, 20);
trig.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 1, 2);
trig.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 6, 7);
trig.addAttribute(TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 11, 12);
g2d.drawString(trig.getIterator(), 50, 50);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
但是你可能已经注意到我使用了 20 而不是 60 的字体大小,那是因为它对我来说似乎太大了,只需更改它就可以了,而且我使用了另一种字体,所以你可以看到你可以使用您想要的任何字体(只需确保已安装该字体或将其导出到您的 JAR 文件中)
一般的想法是单独使用字体属性,如上面代码中的这些行:
trig.addAttribute(TextAttribute.FAMILY, "Comic Sans MS");
trig.addAttribute(TextAttribute.SIZE, 20);
这就是它的样子:)
请务必关注Java naming conventions,以便您和我们更容易阅读您的代码:
firstWordLowerCaseVariable
firstWordLowerCaseMethod(...)
FirstWordUpperCaseClass
ALL_WORDS_UPPER_CASE_CONSTANT
对您的代码的另一个改进是:尽量不要分别扩展和覆盖 JComponent 和 paint() 方法,而是扩展 JPanel 或任何其他组件并覆盖它的 paintComponent(Graphics g) 方法并确保调用 super.paintComponent(g) 为它里面的第一行,这样你就不会破坏油漆链。
我的 main(...) 方法对您来说可能也很奇怪,因为 Java 8 中的 Method Reference 和您应该始终启动 Swing 程序的 Event Dispatch Thread (EDT)。
有没有办法用字体的样式来做到这一点?
是的,有(如 thrashgod 答案的链接所示)
您可以阅读TextAttribute 文档找到更多样式
例如:
trig.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
trig.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);