java - 向 JFrame 上图形中的字符串添加下标和字体

标签 java swing graphics fonts subscript

我想在我的 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 时不会合并这些属性,但是这个 answer @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);

这就是它的样子:)

enter image description here


另外请务必关注Java naming conventions这样您和我们的代码就变得更容易阅读:

  • firstWordLowerCaseVariable
  • firstWordLowerCaseMethod(...)
  • FirstWordUpperCaseClass
  • ALL_WORDS_UPPER_CASE_CONSTANT

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

我的 main(...) 方法对你来说也可能看起来很奇怪,因为 Method Reference在 Java 8 和 Event Dispatch Thread (EDT) 中您应该始终开始您的 Swing 程序。


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

是的,有(如 thrashgod 答案的链接所示)

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

例如:

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

关于java - 向 JFrame 上图形中的字符串添加下标和字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44764890/

相关文章:

java - 如何解析来自计时器(android)的值?

java - 将 paintComponent 传递给另一个类错误

java - 设置jar文件中dll的库路径

Java 和 MySQL PreparedStatement : storing 5000 numbers in a table. 什么是正确的方法?

java - 获取 "?"的 ASCII 值

java - 在 PaintComponent 之外使用 Graphics

graphics - 对 Vulkan API 中的渲染 channel 感到困惑

qt - 关于游戏引擎的 SDL + Qt + OpenGL 的一些想法

java - 为什么我的 SmartEnemy 没有跟随 Java 游戏中的玩家,而是转到屏幕顶部?

java - Android - eclipse 中的<终止>