杰瑞科技汇

Java Graphics对象如何高效绘制图形?

Graphics 对象是 Java AWT (Abstract Window Toolkit) 包中的一个核心类,它代表了绘图上下文,你可以把它想象成一个“画笔”或者“画家”,它知道如何在特定的组件(如窗口、按钮、面板等)上绘制图形、文本和图像。

Java Graphics对象如何高效绘制图形?-图1
(图片来源网络,侵删)

核心概念:Graphics 对象是什么?

Graphics 对象本身并不存储要绘制的内容,它封装了执行绘图操作所需的所有信息和方法,

  • 绘图目标: 你要在哪个组件上画?(一个 JPanel
  • 当前颜色: 画笔的当前颜色是什么?
  • 当前字体: 绘制文本时使用的字体是什么?
  • 坐标系: 组件的左上角是坐标原点 (0, 0),X 轴向右,Y 轴向下。

当你调用一个组件的 paint()paintComponent() 方法时,Java 会自动为你创建一个 Graphics 对象作为参数传入,你不需要手动创建它,只需要使用它。


如何获取和使用 Graphics 对象?

Graphics 对象通常在重写绘画方法时获得,主要有两个关键方法:

a) paint(Graphics g) (AWT Component 类)

这是最基础的绘画方法,几乎所有可显示的 AWT 组件都有,当组件首次显示、被遮挡后重新显示、或者被调整大小时,系统会自动调用此方法。

Java Graphics对象如何高效绘制图形?-图2
(图片来源网络,侵删)
import java.awt.*;
import java.applet.Applet; // 为了简单,用 Applet 演示,在现代 Swing 中类似
public class MyFirstApplet extends Applet {
    @Override
    public void paint(Graphics g) {
        // g 就是系统传给我们的 "画笔"
        g.drawString("Hello, AWT Graphics!", 50, 50);
    }
}

b) paintComponent(Graphics g) (Swing JComponent 类)

这是在 Swing 中推荐使用的方法,它是 javax.swing.JComponent 类的一部分。

关键区别paintComponent() 只负责绘制组件的“内容”,而 paint() 方法会先绘制组件的边框和背景,然后再调用 paintComponent(),在 paintComponent() 中,你通常应该先调用 super.paintComponent(g) 来清除背景,然后再绘制你自己的内容。

import javax.swing.*;
import java.awt.*;
public class MyDrawingPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        // 1. 调用父类方法,清除组件背景(非常重要!)
        super.paintComponent(g);
        // 2. 现在可以使用 g 对象进行绘制
        g.setColor(Color.BLUE);
        g.fillRect(20, 20, 100, 50); // 画一个蓝色矩形
        g.setColor(Color.RED);
        g.drawString("Hello, Swing Graphics!", 30, 100);
    }
}

Graphics 对象的核心方法

Graphics 类提供了丰富的绘图方法,可以大致分为以下几类:

1 绘制基本图形

方法 描述
drawLine(int x1, int y1, int x2, int y2) 画一条从 (x1, y1) 到 (x2, y2) 的直线。
drawRect(int x, int y, int width, int height) 画一个矩形(空心)。
fillRect(int x, int y, int width, int height) 画一个填充的矩形(实心)。
drawOval(int x, int y, int width, int height) 画一个椭圆(空心),椭圆内切于指定的矩形。
fillOval(int x, int y, int width, int height) 画一个填充的椭圆(实心)。
drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) 画一个圆弧(空心)。
fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) 画一个填充的扇形(实心)。
drawPolygon(int[] xPoints, int[] yPoints, int nPoints) 画一个由多个点构成的多边形(空心)。
fillPolygon(int[] xPoints, int[] yPoints, int nPoints) 画一个填充的多边形(实心)。

示例:

Java Graphics对象如何高效绘制图形?-图3
(图片来源网络,侵删)
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    // 画一条线
    g.drawLine(10, 10, 200, 10);
    // 画一个红色实心矩形
    g.setColor(Color.RED);
    g.fillRect(10, 20, 100, 80);
    // 画一个蓝色空心椭圆
    g.setColor(Color.BLUE);
    g.drawOval(120, 20, 100, 80);
}

2 绘制文本

方法 描述
drawString(String str, int x, int y) 在指定的位置绘制字符串,坐标 (x, y) 是文本基线的起点。
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setFont(new Font("宋体", Font.BOLD, 24)); // 设置字体
    g.drawString("你好,世界!", 50, 150);
}

3 设置绘图属性

在绘制之前,你需要设置画笔的属性。

方法 描述
setColor(Color c) 设置绘图颜色。Color 类提供了预定义颜色,如 Color.RED, Color.BLACK,也可以用 new Color(r, g, b) 自定义。
setFont(Font f) 设置字体。Font 类通过字体名称、样式(Font.PLAIN, Font.BOLD, Font.ITALIC)和大小来创建。
setXORMode(Color c) 设置异或模式,在这种模式下,绘制的内容会与已有颜色进行异或运算,常用于实现“橡皮擦”或拖动时的临时效果。
setPaintMode() 恢复到正常的绘制模式(默认模式)。

Graphics2D:更强大的绘图

Graphics 是一个基础类,功能有限,现代 Java 图形编程主要使用它的子类 Graphics2D,它提供了更强大的功能,如抗锯齿、旋转变换、透明度、复杂形状等。

如何获取 Graphics2D 对象?只需将传入的 Graphics 参数强制转换即可。

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    // 将 Graphics 对象转换为 Graphics2D 对象
    Graphics2D g2d = (Graphics2D) g;
    // 开启抗锯齿,让图形边缘更平滑
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    // 设置一个渐变色
    GradientPaint gradient = new GradientPaint(0, 0, Color.CYAN, 200, 200, Color.MAGENTA);
    g2d.setPaint(gradient); // setPaint 比 setColor 更通用
    // 画一个圆角矩形
    g2d.fillRoundRect(50, 50, 150, 100, 30, 30);
    // 保存当前状态
    AffineTransform oldTransform = g2d.getTransform();
    // 平移坐标系
    g2d.translate(250, 0);
    // 旋转坐标系(角度是弧度制)
    g2d.rotate(Math.toRadians(45));
    // 画一个旋转的矩形
    g2d.setColor(Color.ORANGE);
    g2d.fillRect(0, 0, 100, 50);
    // 恢复之前的状态
    g2d.setTransform(oldTransform);
}

Graphics2D 的核心思想是将画笔(Graphics2D)和画布(组件)分离,它通过一个变换(AffineTransform对象来改变坐标系,从而实现平移、旋转、缩放等效果。


完整的 Swing 示例

下面是一个完整的、可运行的 Swing 示例,它创建一个窗口并在一个自定义的面板上绘制各种图形。

import javax.swing.*;
import java.awt.*;
public class GraphicsDemo {
    public static void main(String[] args) {
        // 创建一个窗口
        JFrame frame = new JFrame("Java Graphics Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 400);
        // 创建一个自定义的面板,并添加到窗口中
        DrawingPanel panel = new DrawingPanel();
        frame.add(panel);
        // 让窗口可见
        frame.setVisible(true);
    }
}
// 自定义的绘图面板
class DrawingPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        // 1. 调用父类方法,确保背景被正确绘制
        super.paintComponent(g);
        // 2. 将 g 转换为 Graphics2D 以获得更强大的功能
        Graphics2D g2d = (Graphics2D) g;
        // 3. 设置抗锯齿,使图形更平滑
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // --- 绘制基本图形 ---
        // 画一条线
        g2d.setColor(Color.BLACK);
        g2d.drawLine(20, 20, 200, 20);
        // 画一个红色实心矩形
        g2d.setColor(Color.RED);
        g2d.fillRect(20, 40, 100, 80);
        // 画一个蓝色空心椭圆
        g2d.setColor(Color.BLUE);
        g2d.drawOval(140, 40, 100, 80);
        // --- 绘制文本 ---
        g2d.setColor(Color.DARK_GRAY);
        g2d.setFont(new Font("Arial", Font.BOLD, 20));
        g2d.drawString("This is a String", 20, 160);
        // --- 使用 Graphics2D 的高级功能 ---
        // 画一个带渐变色和旋转的矩形
        g2d.translate(300, 100); // 将原点(0,0)移动到(300,100)
        // 创建一个线性渐变
        GradientPaint gp = new GradientPaint(0, 0, Color.GREEN, 100, 100, Color.YELLOW);
        g2d.setPaint(gp);
        // 画一个填充的矩形
        g2d.fillRect(0, 0, 150, 100);
        // 旋转画布
        g2d.rotate(Math.toRadians(30)); // 旋转30度
        // 画一个带透明度的红色矩形
        g2d.setColor(new Color(255, 0, 0, 128)); // 最后一个参数是透明度 (0-255)
        g2d.fillRect(50, -50, 100, 100);
        // 注意:变换是累积的,后续绘制会继续基于当前变换后的坐标系
        // 如果需要重置,可以使用 g2d.setTransform(new AffineTransform());
    }
}
特性 Graphics Graphics2D
功能 基础绘图功能 强大的 2D 绘图功能
图形 基本形状(线、矩形、椭圆) 任意 Shape 对象(如 RoundRectangle2D, Path2D
颜色 单一颜色 (setColor) 任何 Paint 对象(Color, GradientPaint, TexturePaint
变换 强大的 AffineTransform(平移、旋转、缩放)
渲染 可配置的渲染提示(如抗锯齿)
使用场景 简单的、对性能要求不高的绘图 现代、复杂、高质量的图形界面开发

核心要点

  1. 获取: Graphics 对象由系统在 paint()paintComponent() 方法中传入,无需手动创建。
  2. 使用: 在 paintComponent() 中,先调用 super.paintComponent(g),然后使用 g (或 g2d) 的方法进行绘制。
  3. 升级: 几乎所有情况下,都应该将 g 强制转换为 Graphics2D (Graphics2D g2d = (Graphics2D) g;) 来使用更现代、更强大的功能。
  4. 状态: Graphics 对象的状态(颜色、字体等)是累积的,绘制完一部分后,记得用 setColor(Color.BLACK) 等方法恢复或设置为你想要的状态。
分享:
扫描分享到社交APP
上一篇
下一篇