首页 > 编程语言 >java 字体绘制

java 字体绘制

时间:2022-10-12 07:22:05浏览次数:51  
标签:Graphics2D java g2 坡度 getHeight bounds 字体 message 绘制

一、前提

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

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

 

标签:Graphics2D,java,g2,坡度,getHeight,bounds,字体,message,绘制
From: https://www.cnblogs.com/czwlinux/p/16783212.html

相关文章

  • 《Effective Java》
    《EffectiveJava》  第1章引言 第2章创建和销毁对象 第1条:考虑用静态工厂方法代替构造器 第2条:遇到多个构造器参数时要考虑用构建器 第3条:用私有构造器或者枚举......
  • JavaScript works behind the scenes -- Engine and Runtime
    whatisaJavaScriptengine?programthatexecutesJavaScriptcode.JavaScript引擎是运行JavaScript代码的程序。howengineworks?JavaScriptcontainsacallsta......
  • Java中equals和==区别
    “==”和equals的区别......
  • 【Java8新特性】- Optional应用
    Java8新特性-Optional应用......
  • 阿里云Java上传文件(含解压zip)
    1、maven<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.1.0</ver......
  • java二维数组
    java二维数组数组一经定义就不能改变长度packagearray;​publicclassArrayDemo04{  publicstaticvoidmain(String[]args){    int[][]num={{1......
  • java数组进阶
    java数组进阶数组一经定义就不能改变长度packagearray;​publicclassArrayDemo03{  publicstaticvoidmain(String[]args){    int[]numbers={1,2......
  • 最长公共前缀(Java)
    编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串""。示例1:输入:strs=["flower","flow","flight"]输出:"fl"示例2:输入:strs=["d......
  • 2022 最新 Java 基础 面试题(二)
    2022最新Java基础面试题(二)​​下面列出这份Java面试问题列表包含的主题​​​​1、Java中能创建volatile数组吗?​​​​2、volatile能使得一个非原子操作变成原......
  • 使用 Stream API 高逼格 优化 Java 代码
    Java8的新特性主要是Lambda表达式和流,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读放大招,流如何简化代码如果有一个需求,需......