java 字体绘制

一、前提

1、如下图是组件的继承关系

可以看到所有的组件都继承Component

2、绘制函数

界面显示或者窗口大小改变的时候,都会调用protected void paintComponent(Graphics graphics)函数进行绘制对应的每个组件,并且参数只有一个是Graphics

3、当要强制界面重新绘制的时候,可以通过调用repaint函数,repaint可以指定区域,如果有指定区域则只重绘指定的区域部分;所有组件的paintComponent都会被调用(在对应的重绘区域内)

4、当要绘制2D图形的时候,直接将paintComponent的Graphics强转为Graphics2D即可

    @Override
    protected void paintComponent(Graphics graphics) {
        Graphics2D g2 = (Graphics2D)graphics;
。。。。。。
    }

5、关于文字的排版

如上图所示字符分为上坡度、下坡度和行间距;

文字的bounds是以基线的位置为原点,从左到右为X轴的正向,从上到下为Y轴的正向

所以上坡度的线的位置为负数

6、获取文字的上坡度、下坡度和行间距相关信息

复制代码
Graphics2D g2 = (Graphics2D)graphics;

Font f = new Font("Serif", Font.BOLD, 36);
g2.setFont(f);

String message = "Hello, Worldp";
FontRenderContext context = g2.getFontRenderContext();
Rectangle2D bounds = f.getStringBounds(message, context); // 获取message文字区域的大小,需要通过message跟context进行计算
// 由于bounds获取的是左上角的位置和整个文字区域的宽高,即:getX返回的是基线的X的原点位置为0,getY返回的是上坡度的线的Y的位置即为负数(因为是以基线为原点)
复制代码

如果只是获取上坡度、下坡度和行间距的大小而不关心文字的整体宽度则可以用如下的方式

LineMetrics metrics = f.getLineMetrics(message, context);
System.out.println("总高度:" + metrics.getHeight() + "上坡度:" + metrics.getAscent() + " 下坡度:" + metrics.getDescent() + " 行间距:" + metrics.getLeading());
复制代码
class FontComponent extends JComponent {
    private static final int Default_Width = 300;
    private static final int Default_Height = 200;

    @Override
    protected void paintComponent(Graphics graphics) {
        Graphics2D g2 = (Graphics2D)graphics;
        String message = "Hello, Worldp";

        Font f = new Font("Serif", Font.BOLD, 36);
        g2.setFont(f);

        FontRenderContext context = g2.getFontRenderContext();
        Rectangle2D bounds = f.getStringBounds(message, context);

        System.out.println("" + bounds.getX() + " " + bounds.getY() + " " + bounds.getWidth() + " " + bounds.getHeight());
        System.out.println(getWidth() + " " + getHeight());

        double x = (getWidth() - bounds.getWidth()) / 2;
        double y = (getHeight() - bounds.getHeight()) / 2;

        double ascent = -bounds.getY();
        double baseY = y + ascent;

        g2.drawString(message, (int)x, (int)baseY);
        g2.setPaint(Color.LIGHT_GRAY);

        g2.draw(new Line2D.Double(x, baseY, x + bounds.getWidth(), baseY));

        Rectangle2D rect = new Rectangle2D.Double(x, y, bounds.getWidth(), bounds.getHeight());
        g2.draw(rect);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(Default_Width, Default_Height);
    }
}
View Code
复制代码

如上是自体类的绘制过程,绘制的结果如下图所示:文字、文字对应的基线还有文字的外框

 

posted @   LCAC  阅读(290)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
历史上的今天:
2021-10-12 git reset
点击右上角即可分享
微信分享提示