将下标和字体添加到 JFrame 上图形中的字符串

add subscripts and a font to a String in graphics on a JFrame

我想在我的 JFrame 上绘制一个带有下标和字体的字符串,我试图使用 AttributedString 但我似乎出于某种原因不想工作。它要么只显示字体,要么只显示下标,但不会同时显示两者。

private class DrawFormulas extends JComponent
{
    public void paint(Graphics g)
    {

        Graphics2D G2D = (Graphics2D)g;

        G2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        g.setFont(F);

        AttributedString Trig = new AttributedString("a2 + b2 = c2");
        Trig.addAttribute(TextAttribute.FONT, F);
        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);
        Trig.addAttribute(TextAttribute.SIZE, F.getSize());
        G2D.drawString(Trig.getIterator(), 170, 75);

    }
}

如果有人能告诉我为什么这不起作用或有更好的方法来做到这一点,我们将不胜感激。谢谢

我不确定为什么同时使用 TextAttribute.FONTTextAttribute.SUPERSCRIPT 时不合并这些属性,但是 @thrashgod 的这个 给出了你的解决方案。

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

您的代码的另一个改进是:尝试不要分别扩展和覆盖 JComponentpaint() 方法,而是扩展 JPanel 或任何其他组件并覆盖它的 paintComponent(Graphics g)方法并确保调用 super.paintComponent(g) 作为其中的第一行,这样你就不会破坏油漆链。

我的 main(...) 方法对您来说可能也很奇怪,因为 Method Reference in Java 8 and the Event Dispatch Thread (EDT) 您应该总是 启动您的 Swing 程序。


is there a way I can do that with the style of a font?

是的,有(如 link 对 thrashgod 的回答所示)

您可以阅读 TextAttribute 文档找到更多样式

例如:

trig.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
trig.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);

If somebody can tell me why this doesn't work

I'm not sure why when using both TextAttribute.FONT and TextAttribute.SUPERSCRIPT doesn't merge those attributes

这是因为 FONT TextAttribute 以特殊方式处理。来自 javadoc:

... Normally, all the attributes are examined and used to select and configure a Font instance. If a FONT attribute is present, though, its associated Font will be used. ... Typically, there will be no other attributes in the Map except the FONT attribute.

Javadoc 还解释了其他属性可以与 FONT 属性一起使用,但不能与 FONT 属性一起使用:FAMILY、WEIGHT、WIDTH、POSTURE、SIZE、TRANSFORM、SUPERSCRIPT 和 TRACKING。

这就是忽略 SUPERSCRIPT 属性的原因。