javaFX初探(使用画布 API)_canvas roundrect api-天下标王

javaFX初探(使用画布 API)

135 篇文章 2 订阅
52 篇文章 0 订阅
47 篇文章 4 订阅

本章介绍javaFX画布API的使用。

概述


javaFX  画布API提供了自定义的纹理。画布API有两个主要的类,Canvas 和 GraphicsContext,定义在javafx.scene.canvas包下。我们可

以创建一个Canvas对象,燃火获得它的GraphicsContext,然后渲染我们自定义的形状。因为Canvas是Node的子类,所以我们可以在场景图

中使用。

基本形状:

下面这个例子使用 Canvas和GraphicesContext来画出圆,矩形,多边形等。代码如下:

package com.chu.canvas;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.shape.ArcType;
import javafx.stage.Stage;
 
public class BasicOpsTest extends Application {
 
    public static void main(String[] args) {
        launch(args);
    }
 
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Drawing Operations Test");
        Group root = new Group();
        Canvas canvas = new Canvas(300, 250);
        GraphicsContext gc = canvas.getGraphicsContext2D();
       
        drawShapes(gc);
        
        root.getChildren().add(canvas);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

    private void drawShapes(GraphicsContext gc) {
        gc.setFill(Color.GREEN);
        gc.setStroke(Color.BLUE);
        gc.setLineWidth(5);
        gc.strokeLine(40, 10, 10, 40);
        gc.fillOval(10, 60, 30, 30);
        gc.strokeOval(60, 60, 30, 30);
        gc.fillRoundRect(110, 60, 30, 30, 10, 10);
        gc.strokeRoundRect(160, 60, 30, 30, 10, 10);
        gc.fillArc(10, 110, 30, 30, 45, 240, ArcType.OPEN);
        gc.fillArc(60, 110, 30, 30, 45, 240, ArcType.CHORD);
        gc.fillArc(110, 110, 30, 30, 45, 240, ArcType.ROUND);
        gc.strokeArc(10, 160, 30, 30, 45, 240, ArcType.OPEN);
        gc.strokeArc(60, 160, 30, 30, 45, 240, ArcType.CHORD);
        gc.strokeArc(110, 160, 30, 30, 45, 240, ArcType.ROUND);
        gc.fillPolygon(new double[]{10, 40, 10, 40},
                       new double[]{210, 210, 240, 240}, 4);
        gc.strokePolygon(new double[]{60, 90, 60, 90},
                         new double[]{210, 210, 240, 240}, 4);
        gc.strokePolyline(new double[]{110, 140, 110, 140},
                          new double[]{210, 210, 240, 240}, 4);
    }
}

运行如下图所示:

]

使用渐变和阴影]

这个例子使用了更多的GraphicsContext的方法,比如:strokeLine, fillOval, strokeArc, 和fillPolygon

代码如下:

package com.chu.canvas;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.effect.DropShadow;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.stage.Stage;

public class CanvasTest extends Application {

    private Canvas canvas = new Canvas(200, 200);
    private GraphicsContext gc = canvas.getGraphicsContext2D();
    private Group root = new Group();

    @Override
    public void start(Stage primaryStage) {
              //  setUserAgentStylesheet(STYLESHEET_MODENA);
        primaryStage.setTitle("Canvas Test");
        moveCanvas(0,0);
        drawDShape();
        drawRadialGradient(Color.RED, Color.YELLOW);
        drawLinearGradient(Color.BLUE, Color.GREEN);
        drawDropShadow(Color.GRAY, Color.BLUE, Color.GREEN, Color.RED);
        root.getChildren().add(canvas);
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }

    /**
     * Moves the canvas to a new location within the Scene. This is accomplished
     * by performing a translation transformation on the Canvas object, passing 
     * in the desired x and y coordinates. Passing in values of 0,0 will position
     * the Canvas in the upper left corner of the Scene.
     * @param x The new x coordinate
     * @param y The new y coordinate
     */
    private void moveCanvas(int x, int y) {
        canvas.setTranslateX(x);
        canvas.setTranslateY(y);
    }

    /**
     * Draws an area in the shape of a capital letter "D."
     * The user can try substituting numbers 
     * of their own in the bezierCurveTo parameters to 
     * warp the shape away from the letter "D."
     */
    private void drawDShape() {
        gc.beginPath();
        gc.moveTo(50, 50);
        gc.bezierCurveTo(150, 20, 150, 150, 75, 150);
        gc.closePath();
    }

    /**
     * Draws a radial gradient on the Canvas object, which appears as a series of
     * circles radiating outward. This demo uses RED and YELLOW by default. 
     * 
     * @param firstColor The color used in the first Stop of the gradient.
     * @param lastColor  The color used in the last Stop of the gradient.
     */
    private void drawRadialGradient(Color firstColor, Color lastColor) {
        gc.setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.1, true,
                CycleMethod.REFLECT,
                new Stop(0.0, firstColor),
                new Stop(1.0, lastColor)));
        gc.fill();
    }

    /**
     * Draws a linear gradient on the Canvas object, which colors the letter "D"
     * from top to bottom. The default colors used in this demo are BLUE and GREEN.
     * 
     * @param firstColor
     * @param secondColor 
     */
    private void drawLinearGradient(Color firstColor, Color secondColor) {
        LinearGradient lg = new LinearGradient(0, 0, 1, 1, true,
                CycleMethod.REFLECT,
                new Stop(0.0, firstColor),
                new Stop(1.0, secondColor));
        gc.setStroke(lg);
        gc.setLineWidth(20);
        gc.stroke();
    }

    /**
     * Draws a four separate drop shadows around the letter "D." The default 
     * colors used in the demo are GREY, BLUE, GREEN, and RED. 
     * 
     * @param firstColor
     * @param secondColor
     * @param thirdColor
     * @param fourthColor 
     */
    private void drawDropShadow(Color firstColor, Color secondColor,
            Color thirdColor, Color fourthColor) {
        gc.applyEffect(new DropShadow(20, 20, 0, firstColor));
        gc.applyEffect(new DropShadow(20, 0, 20, secondColor));
        gc.applyEffect(new DropShadow(20, -20, 0, thirdColor));
        gc.applyEffect(new DropShadow(20, 0, -20, fourthColor));
    }
        
    public static void main(String[] args) {
        launch(args);
    }
    
}

运行如下图所示:


用户交互

下面的例子,显示了一个蓝色的矩形,用户拖动鼠标可以抹去蓝色,双击可以还原。
代码如下:

package com.chu.canvas;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class CanvasDoodleTest extends Application {

    /**
     * Resets the canvas to its original look by filling in a rectangle covering
     * its entire width and height. Color.BLUE is used in this demo.
     *
     * @param canvas The canvas to reset
     * @param color The color to fill
     */
    private void reset(Canvas canvas, Color color) {
        GraphicsContext gc = canvas.getGraphicsContext2D();
        gc.setFill(color);
        gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Canvas Doodle Test");
        Group root = new Group();
        
        // Draw background with gradient
        Rectangle rect = new Rectangle(400, 400);
        drawBackground(rect);
        root.getChildren().add(rect);

        // Create the Canvas, filled in with Blue
        final Canvas canvas = new Canvas(200, 200);
        canvas.setTranslateX(100);
        canvas.setTranslateY(100);
        reset(canvas, Color.BLUE);
        
        final GraphicsContext gc = canvas.getGraphicsContext2D();
        
        // Clear away portions as the user drags the mouse
        canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent e) {
                gc.clearRect(e.getX() - 2, e.getY() - 2, 5, 5);
            }
        });

        // Fill the Canvas with a Blue rectnagle when the user double-clicks
        canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {            
                if (t.getClickCount() >1) {
                    reset(canvas, Color.BLUE);
                }  
            }
        });

        // Add the Canvas to the Scene, and show the Stage
        root.getChildren().add(canvas);
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }

    /**
     * Draws the background with a RadialGradient 
     * that transitions from Red to Yellow.
     * @param rect the Rectangle to draw on the Canvas 
     */
    private void drawBackground(Rectangle rect) {
        rect.setFill(new LinearGradient(0, 0, 1, 1, true,
                CycleMethod.REFLECT,
                new Stop(0, Color.RED),
                new Stop(1, Color.YELLOW)));
    }
    
    public static void main(String[] args) {
        launch(args);
    }
    
}


运行如下图所示:

创建一个简单的系统层

我们可以创建多个Canvas对象,使用这个对象定义一个系统层。改变层后可以画不同的东西在画布上。

代码如下:

package com.chu.canvas;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.scene.control.ChoiceBox;
import javafx.collections.FXCollections;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;

public class LayerTest extends Application {

	private Group root;
	private BorderPane borderPane;
	private Canvas layer1;
	private Canvas layer2;
	private GraphicsContext gc1;
	private GraphicsContext gc2;
	private ChoiceBox cb;

	private void createLayers() {

		// Layers 1&2 are the same size
		layer1 = new Canvas(300, 250);
		layer2 = new Canvas(300, 250);

		// Obtain Graphics Contexts
		gc1 = layer1.getGraphicsContext2D();
		gc1.setFill(Color.GREEN);
		gc1.fillOval(50, 50, 20, 20);
		gc2 = layer2.getGraphicsContext2D();
		gc2.setFill(Color.BLUE);
		gc2.fillOval(100, 100, 20, 20);
	}

	private void handleLayers() {
		// Handler for Layer 1
		layer1.addEventHandler(MouseEvent.MOUSE_PRESSED,
				new EventHandler<MouseEvent>() {
					@Override
					public void handle(MouseEvent e) {
						gc1.fillOval(e.getX(), e.getY(), 20, 20);
					}
				});

		// Handler for Layer 2
		layer2.addEventHandler(MouseEvent.MOUSE_PRESSED,
				new EventHandler<MouseEvent>() {
					@Override
					public void handle(MouseEvent e) {
						gc2.fillOval(e.getX(), e.getY(), 20, 20);
					}
				});
	}

	private void createChoiceBox() {
		cb = new ChoiceBox();
		cb.setItems(FXCollections.observableArrayList("Layer 1 is GREEN",
				"Layer 2 is BLUE"));
		cb.getSelectionModel().selectedItemProperty()
				.addListener(new ChangeListener() {
					@Override
					public void changed(ObservableValue o, Object o1, Object o2) {
						if (o2.toString().equals("Layer 1 is GREEN")) {
							layer1.toFront();
						} else if (o2.toString().equals("Layer 2 is BLUE")) {
							layer2.toFront();
						}
					}
				});
		cb.setValue("Layer 1 is GREEN");
	}

	private void addLayers() {
		// Add Layers
		borderPane.setTop(cb);
		Pane pane = new Pane();
		pane.getChildren().add(layer1);
		pane.getChildren().add(layer2);
		layer1.toFront();
		borderPane.setCenter(pane);
		root.getChildren().add(borderPane);
	}

	public static void main(String[] args) {
		launch(args);
	}

	@Override
	public void start(Stage primaryStage) {

		// Build GUI
		borderPane = new BorderPane();
		primaryStage.setTitle("Layer Test");
		root = new Group();
		createLayers();
		handleLayers();
		createChoiceBox();
		addLayers();

		// Show Scene
		primaryStage.setScene(new Scene(root));
		primaryStage.show();
	}
}


运行代码如下图所示:


褚金辉 CSDN认证博客专家 CSDN认证企业博客
码龄15年 暂无认证
222
原创
6万+
周排名
132万+
总排名
192万+
访问
等级
1万+
积分
467
粉丝
316
获赞
289
评论
737
收藏
私信

分类专栏

java高分局之jstat命令使用

好饿啊早知道不学java了: 受教了,但FGC对应的应该是应该是Full GC吧,Full GC是指整堆收集而非老年代收集。

  • javafX8初探(表格)

    m0_67954902: 依赖包出现问题,楼主可以更新代码吗?

  • Netty的LengthFieldBasedFrameDecoder使用

    ༺鲸落༻: yes

  • Netty的LengthFieldBasedFrameDecoder使用

    xiaoFizz: 需求5 中 meta是两个字节,lengthAdjustment 应该是2

  • 利用ftp多线程上传文件

    北漂小多: 前端接过来的文件,本地没有 工具类应该怎样改

  • 目录

    hadoop
    11篇
  • python之路
    17篇
  • java高分局
    18篇
  • JavaFX
    46篇
  • java操作MongoDB
    7篇
  • 从零开始写MVC框架
    9篇
  • java设计模式
    12篇
  • js
    4篇
  • java
    135篇
  • oracle
    1篇
  • web
    5篇
  • windows
    2篇
  • word
    3篇
  • db2
    1篇
  • wso2esb
    2篇
  • eclipse
    52篇
  • sdo
    6篇
  • tomcat
    5篇
  • webservice
    1篇
  • java网络编程
    6篇
  • cassandra
    4篇
  • jvm
    11篇
  • python
    18篇
  • 设计模式
    12篇
  • 编程相关
    4篇
  • java8
    3篇
  • easyui
    2篇
  • c++
    16篇
  • 算法
    1篇
  • spring
    2篇
  • hibernate
    1篇
  • maven
    1篇
  • 定时器
    1篇
  • mongodb
    9篇
  • 类加载器
    2篇
  • ftp
    1篇
  • 多线程
    2篇
  • javaFX
    47篇
  • 学习
    1篇
  • 编辑器
    1篇
  • dialog
    1篇
  • 并行流
    1篇
  • 垃圾回收
    2篇
  • class文件解析
    1篇
  • 热加载
    2篇
  • native
  • java热加载
    1篇
  • java动态加载
    1篇
  • jstat
    1篇
  • jmap
    1篇
  • jstack
  • 选项
    5篇
  • 参数
    4篇
  • 标准
    1篇
  • 非标准
    1篇
  • nginx
    1篇
  • redis
    1篇
  • 集群
    4篇
  • quartz
  • api
    1篇
  • 正则表达式
    4篇
  • HashMap
    1篇
  • 数据结构
    1篇
  • TreeMap
    1篇
  • 红黑树
    1篇
  • hadoop
    11篇
  • 分布式
    5篇
  • 实战
  • HDFS
    5篇
  • 命令
    1篇
  • shell
    1篇
  • mapreduce
    1篇
  • yarn
    1篇
  • hbase
    3篇
  • netty
    1篇
  • 拆包
    1篇
  • 脚本
    1篇
  • 守护进程
    1篇
  • logrotate
    1篇
  • 编码
    1篇
  • utf-8
    1篇
  • 微信支付
    1篇
  • 支付宝app支付
    1篇
  • java9
    1篇
  • openpyxl
    1篇
  • Jinja2
    1篇
  • numpy
    3篇
  • LaTex
  • 爬虫
    1篇
  • boost
    7篇
  • go
    1篇
  • template
    1篇
  • 为什么被折叠? 到【灌水乐园】发言
    前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值

    相关内容推荐

    梧州企业网站优化方案网站快速优化排名称赞火26星靠谱的网站优化收费标准优化网站设计脚桶冫云速捷深圳网站建设及优化专业网站开发优化报价网站优化率怎么算仁化网站排名优化青岛网站优化联系方式网站创新优化要求延边州网站优化无锡专业网站优化黄石浙江网站建站优化推广如何网站关键词优化排名金州网站优化甘孜藏族自治州网站推广优化网站优化提高点击率蓬莱网站优化排名网站漏洞优化支付行业网站优化宣传铜川关键词网站优化信管家网站TDK优化案例分析渝中网站优化软件怎样去优化网站企业网站关键词优化价格图片尺寸不同对于网站优化廊坊网站页面优化达州网站优化在线咨询网站内页优化的方法聊城济南网站优化公司价格多少放心的电商网站优化热线丰泽区网站seo优化排名福保网站优化在线推广金山区公司官方网站优化定制方案自贡网站制作优化费用邯郸网站快照优化汤阴县网站优化哪个公司实力强网站优化不限点击福州市网站优化外包海口公司网站优化厦门网站怎么优化私人优化网站杭州机械行业网站优化梅州网站优化效果如何网站自然优化关键词巩义网站推广优化价格多少网站内链如何做优化江北网站优化哪家好宁德网站搜索优化临海企业网站优化湘潭标准网站建设优化布吉网站自动优化哪家好遵义洛阳网站优化济南企业网站关键词优化公司兴平市网站seo优化排名河南专业网站seo优化一天内网站优化最佳时间天河网站搜索优化怒江网站建设优化哪家优化网站好泰安网站优化的关键点聚搜信息网站排名优化收藏易速达纺织业网站优化方案丹寨网站关键词优化价格珠宝行业网站优化策划方案最新的网站优化软件推荐的seo网站优化排名电脑网站导航优化坪山网站排名优化服务商照明网站优化技术海珠优化网站哪家有名广州优化网站排名招商濮阳网站优化公司推荐潮州搜索引擎网站优化服务网站内容seo优化南阳价格低的SEO网站优化网站优化方案3000字常州网站推广优化网站优化软件测试面试马山县网站seo优化排名广安优化网站的公司网站怎么优化询问火30星佛山节能设备网站seo优化通州seo网站优化最专业学校网站优化及运营市北网站优化哪家好网站优化公司日常广州网站优化工具沙河网站优化公司台州百度网站优化特点武侯网站优化找哪家昆明网站seo优化网站福田手机网站优化哪里好福建信息化网站优化价格对比网络优化和网站推广网站建设优化易服常规网站有哪些优化工作网站优化是多少钱房山网站整体优化网站建设优化就择火1星惠网站外联优化河北品质网站优化价格表网站推广优化特点资深的网站优化效果如何济南企业网站关键词优化公司福田产品网站优化如何做宿迁市网站关键词优化哪家好湖南电商网站优化阜宁网站怎么优化排名龙岩网站权重优化乐山网站优化服务泰安网站优化外包荔湾区优化网站报价网站做优化采选火30星周口网站关键词优化多少钱渝中seo网站优化公司优化网站建设就属大将军22盐田网站优化推广如何让网站排名靠前最优化开封专业网站优化系统巩义seo网站关键词优化华联超市南昌附近网站优化大连推荐珠宝行业网站优化网站移动端如何优化常州网站优化厂商苏州网站安全优化新乡网站自然优化服务商浦口区小企业网站建设优化谷歌优化网站怎么看咨询网站搭建优化兰州电商网站优化关于公司网站优化哪个公司好襄城seo网站优化哪家快安康网站搜索优化保定网站快照优化价格机械行业网站优化保定正规网站优化seo公司网站存储优化原理网站优化设置内存占用百分比新乡县网站关键词优化网站建设与优化计入什么科莫网站的题目怎么优化网站快速优化适合火25星推网站改版优化升级平湖有效的网站优化河南濮阳哪家网站排名优化专业宁夏银川贺兰网站优化推广梅州网站seo优化软件网站排名优化乺金苹果实力阿拉尔湖南网站优化推广网站图片链接seo优化太仓网站seo优化永州长沙网站优化公司哪家好网站单词优化和整站优化的区别鄂州网站优化开发惠州网站关键词优化工具金乡网站优化公司阳江seo网站关键词优化方法甘肃省资深的网站优化金融行业网站怎么优化推广优化网站方法认证云速捷力荐百度优化网站有用吗贵州省网站优化柳州网站关键词优化沙田服装网站优化互联网推广网站建设优化救赎金手指18资兴网站优化推广网站内部链接优化包括哪些内容沙洋县网站排名优化如何广州网站推广优化案例网站诊断及优化是什么网站设计优化价格嘉峪关网站优化推广公司哪家好兰州全面的网站优化必看莆田市网站seo优化安庆网站seo优化哪个品牌好扶绥县网站seo优化排名新乡网站优化方案株洲网站优化营商环境网站优化关键词分析网站优化过程中如何秒收文章芜湖网站优化如何选择云服务器婚纱摄影网站优化方法昭通网站优化方式萝岗网站排名推广优化技巧桐乡如何优化网站网站怎么做seo信息优化绥宁网站排名优化在线咨询东坑网站优化有哪些方法网站的优化核心不包括虞城个性化网站优化怎么收费优化改版网站推荐中山服务网站优化公司快速网站优化方案横峰网站优化排名陕西网站营销公司产品上线优化福田做网站优化乐云seo网站优化中的关键词项城网站自然优化方案优化网站界面

    合作伙伴

    天下标王

    龙岗网络公司
    深圳网站优化
    龙岗网站建设
    坪山网站建设
    百度标王推广
    天下网标王
    SEO优化按天计费
    SEO按天计费系统