142. JavaFX 图形绘制

一、JavaFX 图形绘制基础

JavaFX 图形绘制概述

概念定义

JavaFX 图形绘制是指使用 JavaFX API 在屏幕上创建和渲染 2D 或 3D 图形的过程。它是 JavaFX 图形引擎的核心功能之一,通过一系列类(如 ShapePathCanvas 等)提供丰富的绘图能力。

核心特点
  1. 矢量图形支持:基于数学公式绘制图形,可无损缩放。
  2. 硬件加速:利用 GPU 提高渲染性能。
  3. 声明式风格:支持通过 FXML 或代码方式定义图形。
  4. CSS 样式支持:可通过 CSS 控制图形外观。
基本绘制流程
  1. 创建图形对象(如 Circle, Rectangle
  2. 设置图形属性(填充色、描边等)
  3. 将图形添加到场景图的容器中(如 Pane, Group
示例代码(简单圆形绘制)
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class BasicDrawing extends Application {
   
   
    @Override
    public void start(Stage primaryStage) {
   
   
        Circle circle = new Circle(100, Color.BLUE);
        circle.setStroke(Color.BLACK);
        
        StackPane root = new StackPane(circle);
        Scene scene = new Scene(root, 400, 400);
        
        primaryStage.setTitle("JavaFX 绘图示例");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}
主要绘制方式
  1. 预定义形状:使用 Shape 的子类(如 Circle, Rectangle
  2. 路径绘制:通过 Path 类自定义复杂形状
  3. Canvas API:使用 GraphicsContext 进行像素级绘制
  4. 3D 图形:通过 Shape3D 相关类实现
性能考量
  • 对于静态图形:优先使用 Shape 节点
  • 对于动态/游戏图形:考虑使用 Canvas
  • 复杂场景建议使用 Group 而非单个 Pane 容器
常见应用场景
  • 数据可视化图表
  • 游戏开发
  • 自定义 UI 控件
  • 交互式绘图应用
  • 教学演示工具

JavaFX 图形绘制的基本类与接口

核心类与接口概述

JavaFX 提供了一套完整的图形绘制 API,主要包含以下核心类和接口:

  1. javafx.scene.shape.Shape

    • 所有图形类的抽象基类
    • 提供公共属性:填充色(fill)、描边色(stroke)、描边宽度(strokeWidth)等
    • 子类包括 RectangleCirclePath 等具体图形
  2. javafx.scene.Node

    • 所有图形节点的基类(Shape 间接继承自 Node
    • 提供通用功能:坐标变换、事件处理、CSS 样式等
  3. javafx.scene.canvas.Canvas

    • 基于像素的绘图画布
    • 通过 GraphicsContext 进行底层绘制操作
常用图形类
  1. Rectangle(矩形)

    Rectangle rect = new Rectangle(50, 50, 100, 80);
    rect.setFill(Color.BLUE);
    
  2. Circle(圆形)

    Circle circle = new Circle(100, 100, 50);
    circle.setStroke(Color.RED);
    
  3. Line(线段)

    Line line = new Line(0, 0, 200, 200);
    line.setStrokeWidth(3);
    
  4. Polygon/Polyline(多边形/折线)

    Polygon triangle = new Polygon(0, 0, 50, 100, 100, 0);
    
高级绘制类
  1. Path(路径)

    • 通过 MoveToLineToArcTo 等子命令组合复杂图形
    Path path = new Path();
    path.getElements().addAll(
        new MoveTo(0, 0),
        new LineTo(100, 0),
        new CubicCurveTo(150, 50, 50, 50, 100, 100)
    );
    
  2. SVGPath(SVG 路径)

    • 支持 SVG 格式的路径字符串
    SVGPath svg = new SVGPath();
    svg.setContent("M0 0 L100 0 L50 100 Z");
    
画布绘制(Canvas API)
  1. GraphicsContext
    • 提供类似 HTML5 Canvas 的绘制方法
    Canvas canvas = new Canvas(300, 300);
    GraphicsContext gc = canvas.getGraphicsContext2D();
    gc.setFill(Color.GREEN);
    gc.fillRect(10, 10, 100, 50);
    
关键接口
  1. Paint

    • 定义填充/描边样式(ColorLinearGradientImagePattern 等实现类)
  2. StrokeType

    • 描边类型枚举(INSIDEOUTSIDECENTERED
使用场景
  • 静态图形:直接使用 Shape 子类
  • 动态绘图:优先选择 Canvas + GraphicsContext
  • 复杂矢量图形:使用 PathSVGPath
注意事项
  1. 性能敏感场景避免过度使用 Shape 节点(改用 Canvas
  2. Path 对象创建后不可修改元素列表(需新建 Path
  3. 坐标系统以左上角为原点 (0,0),Y 轴向下为正方向

坐标系与绘图空间

概念定义

JavaFX 使用二维笛卡尔坐标系进行图形绘制:

  • 原点 (0,0):默认位于场景(Scene)的左上角
  • X轴:向右为正方向
  • Y轴:向下为正方向(与传统数学坐标系相反)
  • 单位:以像素(px)为基本单位
绘图空间层次
  1. 画布(Canvas):通过 GraphicsContext 直接绘制的区域
  2. 场景(Scene):容纳所有节点的顶级容器
  3. 节点(Node):所有图形元素的基类(如 Shape 的子类)
关键特性
  • 局部坐标系:每个节点拥有自己的坐标系,其原点通常是该节点的左上角
  • 坐标系变换:可通过 setTranslateX/Y(), setScaleX/Y(), setRotate() 等方法修改
  • 边界框:通过 getBoundsInLocal()getBoundsInParent() 获取不同参照系下的坐标范围
示例代码:坐标系演示
Canvas canvas = new Canvas(400, 300);
GraphicsContext gc = canvas.getGraphicsContext2D();

// 绘制坐标轴
gc.setStroke(Color.BLUE);
gc.strokeLine(0, 150, 400, 150); // X轴
gc.strokeLine(200, 0, 200, 300); // Y轴

// 在(100,100)处绘制矩形(局部坐标系)
Rectangle rect = new Rectangle(100, 100, 50, 30);
rect.setFill(Color.RED);

// 将矩形平移到(200,200)的父坐标系
rect.setTranslateX(200);
rect.setTranslateY(200);
注意事项
  1. Y轴方向:GUI坐标系与传统数学坐标系相反,需特别注意纵坐标计算
  2. 嵌套变换:父子节点的坐标系变换会叠加生效
  3. 抗锯齿:在非整数坐标绘制时可能产生模糊效果,建议使用 SnapToPixel 属性
  4. 性能影响:频繁的坐标系变换会影响渲染性能
典型应用场景
  • 自定义控件开发时计算绘制位置
  • 实现图形拖拽时的坐标转换
  • 复杂动画中的路径计算
  • 精确控制图形元素的相对位置关系

颜色设置

Color类

JavaFX使用javafx.scene.paint.Color类表示颜色,提供多种构造方式:

  • RGB值:Color.rgb(red, green, blue)
  • HSB值:Color.hsb(hue, saturation, brightness)
  • 十六进制:Color.web("#RRGGBB")
  • 预定义常量:Color.RED, Color.BLUE
透明度设置

通过alpha通道(0-1)控制透明度:

Color semiTransparent = new Color(1, 0, 0, 0.5); // 50%透明的红色

填充设置

纯色填充

直接使用Color对象:

rectangle.setFill(Color.CORNFLOWERBLUE);
渐变填充
  1. 线性渐变(LinearGradient)
LinearGradient gradient = new LinearGradient(
    0, 0, 1, 1, // 起始点(x1,y1)和结束点(x2,y2)
    true, // 是否循环
    CycleMethod.NO_CYCLE, // 循环方式
    new Stop(0, Color.RED),
    new Stop(1, Color.BLUE)
);
circle.setFill(gradient);
  1. 径向渐变(RadialGradient)
RadialGradient gradient = new RadialGradient(
    0, 0, // 焦点坐标
    0.5, 0.5, // 中心坐标
    1, // 半径
    true, // 是否循环
    CycleMethod.REFLECT, // 循环方式
    new Stop(0, Color.YELLOW),
    new Stop(1, Color.GREEN)
);
图像填充

使用ImagePattern填充形状:

Image image = new Image("file:texture.jpg");
ImagePattern pattern = new ImagePattern(image);
polygon.setFill(pattern);

常见注意事项

  1. 颜色值范围:RGB为0-255,HSB中Hue为0-360,Saturation/Brightness为0-100
  2. 渐变Stop的offset应在0.0到1.0之间
  3. 图像填充时需注意图片路径是否正确
  4. 透明色会影响渲染性能

示例代码

// 创建带渐变的矩形
Rectangle rect = new Rectangle(100, 100);
LinearGradient lg = new LinearGradient(
    0, 0, 1, 0, 
    true, 
    CycleMethod.REFLECT,
    new Stop(0, Color.TRANSPARENT),
    new Stop(1, Color.BLACK)
);
rect.setFill(lg);
rect.setStroke(Color.GRAY);

线条与描边属性

概念定义

在 JavaFX 中,线条(Line)是用于绘制直线的基本图形节点,而描边(Stroke)属性用于定义线条的外观,包括颜色、宽度、样式等。描边不仅适用于线条,还适用于其他形状(如矩形、圆形等)的轮廓。

核心属性
  1. 描边颜色(Stroke Color)
    通过 setStroke() 方法设置,接受 Paint 类型(如 Color.RED)。

    line.setStroke(Color.BLUE);
    
  2. 描边宽度(Stroke Width)
    通过 setStrokeWidth() 方法设置,单位为像素。

    line.setStrokeWidth(3.0); // 3像素宽
    
  3. 描边样式(Stroke Dash Pattern)
    通过 setStrokeDashArray() 设置虚线样式,参数为虚线间隔的数组。

    line.getStrokeDashArray().addAll(10.0, 5.0); // 10像素实线,5像素空白
    
  4. 线帽样式(Stroke Line Cap)
    定义线条端点的形状,可选值:

    • StrokeLineCap.BUTT(默认,平头)
    • StrokeLineCap.ROUND(圆头)
    • StrokeLineCap.SQUARE(方头)
    line.setStrokeLineCap(StrokeLineCap.ROUND);
    
  5. 线段连接样式(Stroke Line Join)
    定义线段转折处的连接方式,可选值:

    • StrokeLineJoin.MITER(尖角,默认)
    • StrokeLineJoin.BEVEL(斜切)
    • StrokeLineJoin.ROUND(圆角)
    line.setStrokeLineJoin(StrokeLineJoin.ROUND);
    
使用场景
  1. 绘制简单直线

    Line line = new Line(50, 50, 200, 50); // 从(50,50)到(200,50)
    line.setStroke(Color.GREEN);
    
  2. 自定义虚线边框

    Rectangle rect = new Rectangle(100, 100);
    rect.setStroke(Color.BLACK);
    rect.setStrokeWidth(2);
    rect.getStrokeDashArray().addAll(5.0, 5.0);
    
注意事项
  1. 性能影响
    复杂的描边样式(如虚线)可能增加渲染开销,在动态图形中需谨慎使用。

  2. 默认无填充
    Line 默认无填充色,仅依赖描边属性。若对形状(如 Rectangle)未设置描边,则不会显示轮廓。

  3. 坐标系统
    线条的起点和终点坐标是相对于父容器的局部坐标系。


二、基本图形绘制

Line 类概述

Line 是 JavaFX 中用于绘制直线的基本图形类,属于 javafx.scene.shape 包。它通过定义起点和终点的坐标来创建一条直线段。

核心属性
  • startXstartY:直线起点的 X 和 Y 坐标
  • endXendY:直线终点的 X 和 Y 坐标
  • stroke:直线的颜色(默认为黑色)
  • strokeWidth:线宽(默认为 1.0)

使用场景

  1. 绘制简单的线段
  2. 作为复杂图形的基础构建块(如折线、多边形)
  3. 创建图表、网格线等可视化元素

示例代码

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class LineExample extends Application {
   
   
    @Override
    public void start(Stage primaryStage) {
   
   
        Line line = new Line(50, 50, 250, 150);
        line.setStrokeWidth(3);
        line.setStroke(javafx.scene.paint.Color.RED);
        
        Pane root = new Pane();
        root.getChildren().add(line);
        
        primaryStage.setScene(new Scene(root, 300, 200));
        primaryStage.setTitle("JavaFX Line Example");
        primaryStage.show();
    }
}

常见注意事项

  1. 坐标系:JavaFX 使用左上角为原点 (0,0) 的坐标系
  2. 可见性:必须设置 stroke 颜色才能使直线可见
  3. 性能:大量直线绘制时建议使用 Canvas 替代
  4. 交互:可通过 setOnMouseClicked 等添加事件处理

高级用法

虚线样式
line.getStrokeDashArray().addAll(5d, 5d);  // 创建5像素间隔的虚线
旋转直线
line.setRotate(45);  // 以起点为中心旋转45度
动态更新
line.endXProperty().bind(...);  // 可以绑定到其他属性

绘制矩形(Rectangle)

概念定义

JavaFX 中的 Rectangle 类用于绘制矩形,是 Shape 类的子类。它通过指定位置(左上角坐标)、宽度和高度来定义矩形区域。可以设置填充颜色、边框颜色、边框宽度等属性。

核心属性
  1. xy:矩形左上角的坐标(相对于父容器)。
  2. widthheight:矩形的宽度和高度。
  3. fill:矩形的填充颜色(Paint 类型,如 Color.RED)。
  4. stroke:边框颜色(Paint 类型)。
  5. strokeWidth:边框宽度(默认 1.0)。
使用场景
  • 绘制 UI 组件(如按钮、面板背景)。
  • 游戏开发中的碰撞检测区域。
  • 数据可视化中的柱状图。
示例代码
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class RectangleDemo extends Application {
   
   
    @Override
    public void start(Stage stage) {
   
   
        Rectangle rect = new Rectangle(50, 50, 200, 100); // x, y, width, height
        rect.setFill(Color.LIGHTBLUE);
        rect.setStroke(Color.DARKBLUE);
        rect.setStrokeWidth(2);

        Pane root = new Pane(rect);
        Scene scene = new Scene(root, 300, 200);
        stage.setScene(scene);
        stage.setTitle("JavaFX Rectangle");
        stage.show();
    }

    public static void main(String[] args) {
   
   
        launch(args);
    }
}
常见误区
  1. 坐标原点:默认左上角为 (0,0),向右和向下为正方向。
  2. 动态调整:修改 width/height 属性会自动更新渲染,无需手动重绘。
  3. 圆角矩形:需使用 arcWidtharcHeight 属性(示例:rect.setArcWidth(20))。
高级功能
  • 绑定属性:可通过属性绑定动态调整大小(如 rect.widthProperty().bind(scene.widthProperty().divide(2)))。
  • 剪切区域:用 Rectangle 作为 Nodeclip 实现裁剪效果。

JavaFX 中的圆形(Circle)

概念定义

Circle 是 JavaFX 中 javafx.scene.shape 包提供的一个类,用于在场景图中绘制圆形。它继承自 Shape 类,具有以下核心属性:

  • centerX:圆心 X 坐标(默认 0)
  • centerY:圆心 Y 坐标(默认 0)
  • radius:半径(默认 0)
使用场景
  1. 基础图形绘制(如仪表盘、图表元素)
  2. 游戏开发(角色、道具的圆形碰撞检测)
  3. UI 设计(圆形按钮、进度指示器)
关键方法
// 构造方法
Circle(double radius)  // 默认圆心(0,0)
Circle(double centerX, double centerY, double radius)

// 样式设置
circle.setFill(Color.RED);    // 填充色
circle.setStroke(Color.BLACK); // 边框色
circle.setStrokeWidth(2);     // 边框粗细
示例代码
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class CircleDemo extends Application {
   
   
    @Override
    public void start(Stage primaryStage) {
   
   
        Circle circle = new Circle(150, 150, 100);
        circle.setFill(Color.LIGHTBLUE);
        circle.setStroke(Color.DARKBLUE);
        circle.setStrokeWidth(3);

        StackPane root = new StackPane(circle);
        Scene scene = new Scene(root, 300, 300);
        
        primaryStage.setTitle("JavaFX Circle Demo");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}
注意事项
  1. 坐标系:圆心坐标基于父容器的局部坐标系
  2. 性能优化:避免动态修改大量圆的属性(考虑使用 Canvas 替代)
  3. 事件处理:可通过 setOnMouseClicked 等添加交互
  4. 抗锯齿:默认启用,如需关闭需设置 Sceneantialiasing 属性
高级特性
// 虚线边框
circle.getStrokeDashArray().addAll(10d, 5d);

// 阴影效果
circle.setEffect(new DropShadow(10, Color.GRAY));

// 渐变填充
RadialGradient gradient = new RadialGradient(...);
circle.setFill(gradient);

绘制椭圆(Ellipse)

概念定义

椭圆是JavaFX中javafx.scene.shape.Ellipse类表示的几何图形,由以下参数定义:

  • 中心点(centerX, centerY):椭圆中心的坐标
  • 半径X(radiusX):水平方向的半轴长度
  • 半径Y(radiusY):垂直方向的半轴长度

当radiusX = radiusY时,椭圆退化为圆形。

核心属性
属性 类型 说明
centerX double 中心点X坐标
centerY double 中心点Y坐标
radiusX double 水平半径
radiusY double 垂直半径
使用场景
  1. 数据可视化中的饼图/环形图
  2. UI设计中的圆形按钮/图标
  3. 游戏开发中的碰撞检测区域
  4. 科学计算中的轨道模拟
示例代码
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
import javafx.stage.Stage;

public class EllipseDemo extends Application {
   
   
    @Override
    public void start(Stage primaryStage) {
   
   
        Ellipse ellipse = new Ellipse();
        ellipse.setCenterX(200);
        ellipse.setCenterY(150);
        ellipse.setRadiusX(100);
        ellipse.setRadiusY(70);
        ellipse.setFill(Color.LIGHTBLUE);
        ellipse.setStroke(Color.DARKBLUE);
        ellipse.setStrokeWidth(2);
        
        Pane root = new Pane(ellipse);
        Scene scene = new Scene(root, 400, 300);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}
注意事项
  1. 坐标系:JavaFX使用屏幕坐标系(Y轴向下为正)
  2. 性能优化:大量椭圆绘制时应考虑使用Canvas替代
  3. 变形控制:通过scaleX/scaleY属性可实现非均匀缩放
  4. 事件处理:需要点击检测时应设置setPickOnBounds(true)
进阶技巧
// 创建旋转45度的椭圆
Ellipse rotatedEllipse = new Ellipse(200, 150, 80, 50);
rotatedEllipse.setRotate(45);

// 创建虚线边框椭圆
Ellipse dashedEllipse = new Ellipse(200, 150, 60, 40);
dashedEllipse.setStroke(Color.RED);
dashedEllipse.setStrokeWidth(3);
dashedEllipse.getStrokeDashArray().addAll(10d, 5d);
数学关系

椭圆上任意点(x,y)满足方程:
[
\frac{(x - centerX)2}{radiusX2} + \frac{(y - centerY)2}{radiusY2} = 1
]


绘制多边形(Polygon)

概念定义

Polygon 是 JavaFX 中用于绘制多边形的类,属于 javafx.scene.shape 包。它通过连接一系列坐标点(顶点)形成闭合图形,支持自定义边数、顶点位置、填充颜色和描边样式。

核心特性
  1. 顶点定义:通过 getPoints()<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值