首页 > 编程语言 >《Java核心技术 卷I》图形用户界面使用字体

《Java核心技术 卷I》图形用户界面使用字体

时间:2024-11-12 16:19:36浏览次数:3  
标签:Java String java 核心技术 awt 字体 import Font 图形用户界面

使用字体

字体名(font face name)指定一种字体,字体名由字体族名(font family name)和一个可选的后缀(如果"Bold")组成,例如,“Helvetica”和"Helvetica Bold"都属于名为“Helvetica”字体族的字体。

要想知道某台特定计算机上可用的字体,可以调用GraphicsEnvironment类的getAvailableFontFamilyNames方法,这个方法返回一个字符串数组,其中包含了所有可用的字体名,GraphicsEnvironment类描述了用户系统的图像上下文,为了得到这个类的对象,需要调用静态的getLocalGraphicsEnvironment方法。

打印系统上的所有字体名

package font;

import java.awt.GraphicsEnvironment;

public class ListFonts {

    public static void main(String[] args) {
        String[] fontNames = GraphicsEnvironment
                .getLocalGraphicsEnvironment()
                .getAvailableFontFamilyNames();
        for (String fontName : fontNames) {
            System.out.println(fontName);
        }
    }

}

结果:

这些字体名总是被映射到客户机上的某些实际字体,例如,在Windows系统重,SansSerif将被映射到Arial。

另外,Oracle JDK总是包含3个字体族,名为Lucida Sans,Lucida Bright,Lucida Sans Typewriter。

要想使用某种字体绘制字符,首先创建一个Font类的对象,需要指定字体名、字体风格和字体大小,下面是构造一个Font对象的例子:

var sansbold14 = new Font("SansSerif",Font.BOLD,14);

第三个参数是以点数目计算的字体大小,排版中普遍使用点数指示字体大小,没英寸包含72个点。

在Font构造器中,提供字体名的位置也可以给出逻辑字体名。可以把Font构造器的第二个参数设置为一下值来指定字体的风格(常规、加粗、斜体或加粗斜体):

Font.PLAIN Font.BOLD Font.ITALIC Font.BOLD + Font.ITALIC

常规字体的字体大小为1点,可以使用deriveFont方法得到所需大小的字体:

Font f = f1.deriveFont(14.0F)

警告:deriveFont方法有两个重载版本,一个(有一个float参数)设置字体的大小,另一个(有一个int参数)设置字体风格,所以f1.deriveFont(14)设置的是字体风格,而不是大小(其结果为斜体,因为14的二进制表示的是ITALIC位为1,而BOLD位为0)。

下面这段代码将使用系统中14点加粗的标准sans serif字体显示字符串"Hello,World":

package draw;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class DrawFontTest {

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            var frame = new DrawFontFrame();
            frame.setTitle("DrawFontTest");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }

}

class DrawFontFrame extends JFrame {
    public DrawFontFrame() {
        add(new DrawFontComponent());
        pack();
    }
}


class DrawFontComponent extends JComponent {
    
    private static final int DEFAULT_WIDTH = 400;
    private static final int DEFAULT_HEIGHT = 400;
    
    @Override
    protected void paintComponent(Graphics g) {
        String[] fontNames = GraphicsEnvironment
                .getLocalGraphicsEnvironment()
                .getAvailableFontFamilyNames();
        
//        for (String fontName : fontNames) { System.out.println(fontName); }
        ArrayList<String> fontNameList = new ArrayList<>(Arrays.asList(fontNames));
        System.out.println(fontNameList.contains("SansSerif"));
        var sansbold14 = new Font("SansSerif",Font.BOLD,14);
        g.setFont(sansbold14);
        var message = "Hello, World!";
        g.drawString(message, 75, 100);
    }
    
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }
    
}

结果:

接下来,将字符串居中,而不是绘制在任意位置,因此,需要知道字符串占据的宽和高的像素数,这两个值取决于下面三个因素:

  • 使用的字体
  • 字符串
  • 绘制字体的设备(用户屏幕)

得到表示屏幕设备字体属性对象,需要调用Graphics2D类中的getFontRenderContext方法。返回一个FontRenderContext类的对象,可以直接将这个对象传递给Font类的getStringBounds方法:

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

getStringBounds方法将返回包围字符串的矩形。

getStringBounds方法返回的矩形宽度是字符串水平方向的宽度,矩形的高度是上坡度、下坡度和行间距的总和,这个矩形始于字符串的基线,矩形顶部的y坐标为负值,因此,可以使用下面的方法获得字符串的宽度、高度和上坡度:

  • double stringWidth = bounds.getWidth();
  • double stringHeight = bounds.getHeight();
  • double ascent = -bounds.getY();

如果需要知道下坡度或行间距,可以使用Font类的getLineMetrics方法,这个方法将返回一个LineMetrics类的对象,获得下坡度和行间距的方法是:

LineMetrics metrics = f.getLineMetrics(message,context);

float descent = metrics.getDescent();//下坡度

float leading = metrics.getLeading();//行间距

注释:如果需要再paintComponent方法外部计算布局大小,不能从Graphics2D对象得到字体绘制上下文,应该换做JComponent类的getFontMetrics方法,然后调用getFontRenderContext:

FontRenderContext context = getFontMetrics(f).getFontRenderContext();

绘制基线和字符串外框矩形

package font;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class FontTest {

    public static void main(String[] args) {
        EventQueue.invokeLater(()->{
            var frame = new FontFrame();
            frame.setTitle("FontTest");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }

}



class FontFrame extends JFrame {
    public FontFrame() {
        add(new FontComponent());
        pack();
    }
}

class FontComponent extends JComponent {
    
    private static final int DEFAULT_WIDTH = 300;
    private static final int DEFAULT_HEIGHT = 200;
    
    @Override
    protected void paintComponent(Graphics g) {
        var g2 = (Graphics2D)g;
        var message = "Hello, World!";
        var f = new Font("Serif",Font.BOLD,36);
        g2.setFont(f);
        //确定信息大小
        FontRenderContext context = g2.getFontRenderContext();
        Rectangle2D bounds = f.getStringBounds(message, context);
        //设置文本的左上角位置
        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));
        //画闭合的矩形
        var rect = new Rectangle2D.Double(x, y, bounds.getWidth(), bounds.getHeight());
        g2.draw(rect);
    }
    
    @Override
    public Dimension preferredSize() {
        // TODO Auto-generated method stub
        return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }
    
}

java.awt.Font 1.0

  • Font(String name,int style,int size),创建一个新字体对象,字体名可以是具体的字体名("Helvetica Bold")或逻辑字体名("Serif","SansSerif"),字体风格可以是Font.PLAIN、FontBOLD、FontITALIC、或FontBOLD+FontITALIC。
  • String getFontName(),获得字体名,例如,"Helvetica Bold"。
  • String getFamily(),获得字体族名,例如,Helvetica
  • String getName(),如果采用逻辑字体名创建字体,将获得逻辑字体名,例如,SansSerif否则,获得字体名。
  • Rectangle2D getStringBounds(String s,FontRenderContext context) 1.2,返回包围这个字符串矩形,矩形的起点为基线,矩形顶端的y坐标等于上坡度的负值,矩形的高度等于上坡度,下坡度和行间距之和。宽度等于字符串的宽度。
  • LineMetrics getLineMetrics(String s,FontRenderContext context) 1.2,返回确定字符串宽度的一个度量对象。
  • Font deriveFont(int style) 1.2
  • Font deriveFont(float size) 1.2
  • Font deriveFont(int style,float size) 1.2,返回一个新字体,除了有给定的大小和字体风格外,其余与原字体一样。

java.awt.font.LineMetrics 1.2

  • float getAscent(),获得字体的上坡度-从基线到大写字母顶端的距离
  • float getDescent(),获得字体的下坡度-从基线到坡底的距离。
  • float getLeading(),获得字体的行间距-从一行文本底端到下一行文本顶端之间的空隙。
  • float getHeight(),获得字体总高度-两条文本基线之间的距离(下坡度+行间距+上坡度)。

java.awt.Graphics2D 1.2

  • FontRenderContext getFontRenderContext(),获得这个图形上下文中指定字体特征的字体绘制上下文。
  • void drawString(String str,float x,float y),采用当前的字体和颜色绘制一个字符串。

javax.swing.JComponent 1.2

  • FontMetrics getFontMetrics(Font f),获取给定字体的字体度量对象,FontMetrics类是LineMetrics类的前身。

java.awt.FontMetrics 1.0

  • FontRenderContext getFontRenderContext() 1.2,返回字体的字体绘制上下文。

标签:Java,String,java,核心技术,awt,字体,import,Font,图形用户界面
From: https://blog.csdn.net/qq_36324341/article/details/143717466

相关文章

  • 深入 Java 多线程:解锁并发编程的奥秘
    在当今的软件开发世界中,性能和高并发是衡量一个应用程序成败的关键因素。无论是处理高流量的网络请求、执行复杂的数据分析任务,还是管理后台服务中的资源,Java多线程编程都是开发者必备的技能之一。本文将带领你深入Java多线程的世界,解锁并发编程的奥秘。1.并发与并行的区......
  • 2024年Java 八股文-基础篇
    1.为什么说Java语言“编译与解释并存”?高级编程语言按照程序的执行方式分为编译型和解释型两种。简单来说,编译型语言是指编译器针对特定的操作系统将源代码一次性翻译成可被该平台执行的机器码;解释型语言是指解释器对源程序逐行解释成特定平台的机器码并立即执行。比如,你......
  • Java中2个Integer比较相同的4种方式
    Java中2个Integer比较相同的4种方式概要使用前切记Integer的范围是【-128~127】例如:Integera=128;Integerb=128;1,使用==比较【-128~127】区间内返回true,否则返回false//==比较if(a==b){System.out.println("a,b使用==比较返回结果:true");......
  • 20天精通Java,day1
    面向对象编程static(静态):修饰成员变量和成员方法。类变量和类方法:有static修饰,属于类,在计算机中只有一份,会被类的全部对象共享。既可以通过类名访问(推荐),也可以通过对象名访问。类变量应用场景:在开发中如果某个数据只需要一份,且希望能够被共享(访问,修改),则该数据可以被定义成类......
  • 【JAVA】Java基础—面向对象编程:构造方法-实现一个Car类,包含多个构造方法,创建不同的汽
    在Java中,构造方法则是用于创建对象的特殊方法。通过构造方法,可以在创建对象时初始化其属性。构造方法的重载允许我们根据不同的需求定义多个构造方法,从而灵活地创建对象。我们可以将汽车的构造方法比作汽车的配置选项。比如,当你购买一辆汽车时,你可以选择不同的配置,如颜色、型......
  • 新手入门Java自动化测试的利器:Selenium WebDriver
    新手入门Java自动化测试的利器:SeleniumWebDriver今天我们将深入探讨一款强大的Java自动化测试工具——SeleniumWebDriver。在正式介绍SeleniumWebDriver之前,让我们首先对Selenium本身进行简要概述,以便更好地理解其背景和功能。官方学习网站:https://www.selenium.dev/Sele......
  • ssm093基于Java Web的毕业生就业状况管理系统设计与实现+jsp(论文+源码)_kaic
     毕业设计(论文)题目:毕业生就业状况管理系统设计与实现摘 要现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本毕业生就业状况管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内......
  • javaWeb开发实战:spring MVC+MyBatis实现网页登录验证
    1.环境和工具Idea2019、Tomcat8、Jdk82.新建springMVC项目打开idea,新建项目,选择springMVC->next:填写项目名、路径->finish完成创建3.项目属性配置文件(file)->项目结构:检查sdk、模块设置是否正确。4.运行调试配置Addconfigration点击“+”号,选择tomcat->loca......
  • 基于Java+SpringBoot+Vue+HTML5人职匹配推荐系统(源码+LW+调试文档+讲解等)/人职匹配/
    博主介绍......
  • 基于Java+SpringBoot+Vue+HTML5的网上商城系统(源码+LW+调试文档+讲解等)/网上商城系
    博主介绍......