基于javafx的简单画图应用

2023-05-16

代码比较简单,但初次接触javafx,会不知道从哪里下手,多与其他人交流看看代码能让我们事半功倍。代码内容我就不多做解释,自己有个思路知道有哪些函数该怎么下手就好。

效果:

一共就只有三个文件,其中fxml文件主要是利用javafx scene builder完成的。

//Painter.java

package p3;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Painter extends Application {   
   @Override
   public void start(Stage stage) throws Exception {
      Parent root = 
         FXMLLoader.load(getClass().getResource("Painter.fxml"));
      
      Scene scene = new Scene(root);
      stage.setTitle("Painter"); // displayed in window's title bar
      stage.setScene(scene);
      stage.show();
   }

   public static void main(String[] args) {
      launch(args);
   }
}
//PainterController.java

package p3;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;

public class PainterController {
	// enum representing pen sizes
	private enum PenSize {
		SMALL(2), MEDIUM(4), LARGE(6);

		private final int radius;

		PenSize(int radius) {
			this.radius = radius;
		}

		public int getRadius() {
			return radius;
		}
	};

	private enum Shape {
		RECT, CIRCLE, LINE
	};

	// RGB三元色
	private int red = 0;
	private int green = 0;
	private int blue = 0;
	// 初始化:粗细、颜色、形状
	private PenSize radius = PenSize.MEDIUM;
	private Paint brushColor = Color.BLACK;
	private Paint TRANSPARENT = Color.rgb(255,255,255,0.0);//透明色
	private Shape shape = Shape.LINE;
	//鼠标坐标
	private double mouseEnterX;
	private double mouseEnterY;
	private double mouseReleasedX;
	private double mouseReleasedY;
	private double rectangleWidth;
	private double rectangleHeight;
	private double circleCenterX;
	private double circleCenterY;
	private double circleRadius;
	@FXML
	private Button setColorButton;
	@FXML
	private RadioButton mediumRadioButton;
	@FXML
	private TextField greenTextField;
	@FXML
	private ToggleGroup sizeToggleGroup;
	@FXML
	private ToggleGroup shapeToggleGroup;
	@FXML
	private TextField redTextField;
	@FXML
	private RadioButton lineRadioButton;
	@FXML
	private RadioButton rectRadioButton;
	@FXML
	private Pane drawingAreaPane;
	@FXML
	private Button clearButton;
	@FXML
	private RadioButton largeRadioButton;
	@FXML
	private RadioButton smallRadioButton;
	@FXML
	private TextField blueTextField;
	@FXML
	private Button undoButton;
	@FXML
	private RadioButton circleRadioButton;

	public void initialize() {
		//形状按钮赋值
		lineRadioButton.setUserData(Shape.LINE);
		circleRadioButton.setUserData(Shape.CIRCLE);
		rectRadioButton.setUserData(Shape.RECT);
		//粗细按钮赋值
		smallRadioButton.setUserData(PenSize.SMALL);
		mediumRadioButton.setUserData(PenSize.MEDIUM);
		largeRadioButton.setUserData(PenSize.LARGE);
	}
	
	void getValueOfRgb() {
		red = Integer.parseInt(redTextField.getText());
		green = Integer.parseInt(greenTextField.getText());
		blue = Integer.parseInt(blueTextField.getText());
		brushColor = Color.rgb(red, green, blue);
	}
	@FXML
    void drawingAreaMousePressed(MouseEvent e) {
		mouseEnterX = e.getX();
		mouseEnterY = e.getY();	
		if(mouseEnterX > drawingAreaPane.getWidth() || mouseEnterY > drawingAreaPane.getHeight())
    		return;
    }
	
    @FXML
    void drawingAreaMouseReleased(MouseEvent e) {
    	mouseReleasedX=e.getX();
    	mouseReleasedY=e.getY();
    	if(mouseReleasedX > drawingAreaPane.getWidth() || mouseReleasedX < 0 || mouseReleasedY > drawingAreaPane.getHeight()|| mouseReleasedY <0)
    		return;
    	getValueOfRgb();
    	switch (shape) {
    	case LINE:
    		Line newLine = new Line(mouseEnterX, mouseEnterY, mouseReleasedX, mouseReleasedY);
    		newLine.setStroke(brushColor);
    		newLine.setStrokeWidth(radius.getRadius());   
    		drawingAreaPane.getChildren().add(newLine);
    		break;
    	case RECT:
    		rectangleWidth = Math.abs(mouseReleasedX - mouseEnterX);
    		rectangleHeight = Math.abs(mouseReleasedY - mouseEnterY);
    		if(mouseEnterX > mouseReleasedX)
    			mouseEnterX = mouseReleasedX;
    		if(mouseEnterY > mouseReleasedY)
    			mouseEnterY = mouseReleasedY;
    		Rectangle newRect = new Rectangle(mouseEnterX, mouseEnterY, rectangleWidth, rectangleHeight);
    		newRect.setStroke(brushColor);
    		newRect.setFill(TRANSPARENT);
    		newRect.setStrokeWidth(radius.getRadius()); 
    		drawingAreaPane.getChildren().add(newRect);
    		break;
		case CIRCLE:
			circleCenterX = (mouseEnterX + mouseReleasedX) / 2;
			circleCenterY = (mouseEnterY + mouseReleasedY) /2;
			circleRadius = Math.hypot((circleCenterX - mouseEnterX), (circleCenterY - mouseEnterY));
			Circle newCircle = new Circle(circleCenterX,circleCenterY,circleRadius);
    		newCircle.setStroke(brushColor);
    		newCircle.setFill(TRANSPARENT);
    		newCircle.setStrokeWidth(radius.getRadius()); 
    		drawingAreaPane.getChildren().add(newCircle);	
    		break;
		}
    }
    
	@FXML
	void sizeRadioButtonSelected(ActionEvent event) {
		radius = (PenSize) sizeToggleGroup.getSelectedToggle().getUserData();
	}


	@FXML
	void shapeRadioButtonSelected(ActionEvent event) {
		shape = (Shape) shapeToggleGroup.getSelectedToggle().getUserData();
		//shapeRadioButtonSelected
	}

	@FXML
	void undoButtonPressed(ActionEvent event) {
		int count = drawingAreaPane.getChildren().size();

	      // if there are any shapes remove the last one added
	    if (count > 0) {
	       drawingAreaPane.getChildren().remove(count - 1);
	    }
	}

	@FXML
	void clearButtonPressed(ActionEvent event) {
		drawingAreaPane.getChildren().clear(); // clear the canvas
	}
}

 Painter.fxml我是使用scene builder完成的

 

<!--Painter.fxml-->
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>

<BorderPane prefHeight="530.0" prefWidth="650.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="p3.PainterController">
   <left>
      <VBox maxHeight="1.7976931348623157E308" prefHeight="464.0" prefWidth="106.0" spacing="8.0" BorderPane.alignment="CENTER">
         <children>
            <TitledPane text="粗细">
               <content>
                  <VBox spacing="8.0">
                     <children>
                        <RadioButton fx:id="smallRadioButton" mnemonicParsing="false" onAction="#sizeRadioButtonSelected" text="细">
                           <toggleGroup>
                              <ToggleGroup fx:id="sizeToggleGroup" />
                           </toggleGroup>
                        </RadioButton>
                        <RadioButton fx:id="mediumRadioButton" mnemonicParsing="false" onAction="#sizeRadioButtonSelected" selected="true" text="中等" toggleGroup="$sizeToggleGroup" />
                        <RadioButton fx:id="largeRadioButton" mnemonicParsing="false" onAction="#sizeRadioButtonSelected" text="粗" toggleGroup="$sizeToggleGroup" />
                     </children>
                  </VBox>
               </content>
            </TitledPane>
            <TitledPane text="形状">
               <content>
                  <VBox spacing="8.0">
                     <children>
                        <RadioButton fx:id="lineRadioButton" mnemonicParsing="false" onAction="#shapeRadioButtonSelected" selected="true" text="直线">
                           <toggleGroup>
                              <ToggleGroup fx:id="shapeToggleGroup" />
                           </toggleGroup></RadioButton>
                        <RadioButton fx:id="rectRadioButton" mnemonicParsing="false" onAction="#shapeRadioButtonSelected" text="矩形" toggleGroup="$shapeToggleGroup" />
                        <RadioButton fx:id="circleRadioButton" mnemonicParsing="false" onAction="#shapeRadioButtonSelected" text="圆形" toggleGroup="$shapeToggleGroup" />
                     </children>
                  </VBox>
               </content>
            </TitledPane>
            <TitledPane text="颜色">
               <content>
                  <VBox spacing="8.0">
                     <children>
                        <GridPane alignment="CENTER_LEFT" prefHeight="90.0" prefWidth="84.0">
                          <columnConstraints>
                            <ColumnConstraints hgrow="SOMETIMES" maxWidth="95.0" minWidth="10.0" prefWidth="37.0" />
                            <ColumnConstraints hgrow="SOMETIMES" maxWidth="171.0" minWidth="10.0" prefWidth="43.0" />
                          </columnConstraints>
                          <rowConstraints>
                            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                          </rowConstraints>
                           <children>
                              <Label alignment="CENTER_RIGHT" contentDisplay="CENTER" prefHeight="24.0" prefWidth="40.0" text="红:">
                                 <font>
                                    <Font size="18.0" />
                                 </font>
                              </Label>
                              <Label alignment="CENTER_RIGHT" prefHeight="20.0" prefWidth="64.0" text="绿:" GridPane.rowIndex="1">
                                 <font>
                                    <Font size="18.0" />
                                 </font>
                              </Label>
                              <Label alignment="CENTER_RIGHT" prefHeight="24.0" prefWidth="52.0" text="蓝:" GridPane.rowIndex="2">
                                 <font>
                                    <Font size="18.0" />
                                 </font>
                              </Label>
                              <TextField fx:id="redTextField" alignment="CENTER" text="0" GridPane.columnIndex="1" />
                              <TextField fx:id="greenTextField" alignment="CENTER" text="0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
                              <TextField fx:id="blueTextField" alignment="CENTER" text="0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
                           </children>
                        </GridPane>
                     </children>
                  </VBox>
               </content>
            </TitledPane>
            <Button fx:id="undoButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#undoButtonPressed" text="上一步" />
            <Button fx:id="clearButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#clearButtonPressed" text="清空" />
         </children>
         <BorderPane.margin>
            <Insets right="8.0" />
         </BorderPane.margin>
      </VBox>
   </left>
   <center>
      <Pane fx:id="drawingAreaPane" onMousePressed="#drawingAreaMousePressed" onMouseReleased="#drawingAreaMouseReleased" prefHeight="513.0" prefWidth="520.0" style="-fx-background-color: white;" BorderPane.alignment="CENTER" />
   </center>
   <padding>
      <Insets bottom="8.0" left="8.0" right="8.0" top="8.0" />
   </padding>
</BorderPane>

由于本人水平有限,代码存在错误之处欢迎指正。

代码查看:https://gitee.com/tian-aqiang/Painter/tree/master/Lab9/src/p3icon-default.png?t=M3K6https://gitee.com/tian-aqiang/Painter/tree/master/Lab9/src/p3

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于javafx的简单画图应用 的相关文章

  • 银河麒麟4.0.2二进制安装mysql5.7

    先查看银河麒麟的版本 root 64 idiom kylin1 cat etc kylin build Kylin 4 0 2 Build 20191024 一 下载二进制包 xff0c 并安装所需软件 root 64 idiom kyli
  • 使用shell脚本一键部署LNMP架构

    span class token comment bin bash span span class token comment 将需要的安装包传到 opt目录下 xff0c 并关闭防火墙 span systemctl stop firewa
  • Nginx优化与防盗链

    目录 一 隐藏版本号二 修改用户与组三 缓存时间四 日志分割五 连接超时六 更改进程数七 配置网页压缩八 配置防盗链九 fpm参数优化 一 隐藏版本号 可以使用Fiddler工具抓取数据包 xff0c 查看Nginx版本 也可以在Cento
  • MySQL索引、事务与存储引擎

    目录 一 MySQL索引1 索引的概念2 索引的作用3 创建索引的原则依据4 索引的分类和创建4 1 61 61 普通索引 61 61 4 2 61 61 唯一索引 61 61 4 3 61 61 主键索引 61 61 4 4 61 61
  • openstack基础知识

    目录 一 云计算1 什么是云计算2 云计算的特色3 云计算的三种使用方式1 xff09 公有云2 xff09 私有云3 xff09 混合云 4 云计算服务模型1 xff09 IaaS 基础架构即服务 2 xff09 PaaS xff08 平
  • openstack-keystone

    目录 一 keystone身份服务二 keystone的主要功能三 keystone相关概念四 keystone认证流程五 OpenStack Keystone组件部署步骤部署步骤 一 keystone身份服务 keystone xff08
  • k8s-----------YAML&harbor

    目录 概述使用YAML文件创建资源1 查看资源版本的标签2 创建yaml文件测试 Pod1 特点2 pod容器分类3 镜像拉取策略 部署harbor1 登录harbor私有仓库2 下载Tomcat镜像进行推送3 推送 概述 Kubernet
  • k8s-----------高级pod&调度

    目录 pod进阶pod重启策略 健康检查 探针调度约束调度方式 故障排除 pod进阶 limits cup cpu上限limits memory 内存上限requests cpu 创建时分配的基本CPU资源requests memory 创
  • k8s-----------控制器

    目录 Deployment 部署无状态应用 Pod与控制器之间的关系 SatefulSet xff08 部署有状态应用 xff09 无状态和有状态无状态有状态 常规service和无头服务区别DaemonSetjobCronJob 控制器
  • 安装electron时安装失败解决

    错误描述 xff1a 在安装 electron 的时候 xff0c 使用官方推荐的如下命令 xff1a npm install save dev electron 结果报错如下 npm ERR code 1 npm ERR path D A
  • 10:天干地支

    10 天干地支 时间限制 1 S 内存限制 8192 KB Accept 15 Submit 41 提交 讨论版 描述 天干地支 xff0c 源自中国远古时代对天象的观测 甲 乙 丙 丁 戊 己 庚 辛 壬 癸 称为十天干 xff0c 子
  • txt格式vscode转码

    txt打开异常 xff0c 或乱码 右下角有格式类型 xff1a utf 8 xff0c 点击它会有一个 select action 弹框 可选择特定格式重新打开 xff0c 或保存 选择好对应的格式 乱码解决 或者点击 save with
  • 送给 Java 程序员的 Spring 学习指南

    https www infoq cn article Ad 8ghcGGCNU572U6oEX 学习 Spring 的基础要求 Spring 官网首页是这么介绍自己的 Spring the source for modern Java xf
  • Centos下如果是二进制文件,编辑是文本,后缀是sh也无法执行

    这次部署redis遇到个问题 xff0c 执行sh文件来启动redis xff0c 结果报配置文件无法打开 用vi打开sh文件反复检查过路径是对的 然后手敲路径执行 xff0c 运行正常 xff1b 直接执行sh文件不行 xff1a 反复修
  • Python Pandas 查看数据信息 DataFrame.info()

    在进行数据分析之前 xff0c 需要先查看数据的信息 xff0c 这样才方便后续的数据处理 比如 xff0c 在excel表中20220520是一个常规类型的数据 xff0c 那它导入到DataFrame中是int类型还是str类型呢 xf
  • 03-1.MariaDB安装配置详细步骤

    Author xff1a Sickey Date xff1a 2021 11 25 安装前准备 配置静态IP防火墙等等 1 安装mariadb数据库 先查看RDO中MariaDB的版本及配置 etc my cnf d server cnf
  • 24行代码简单实现qq空间自动点赞

    什么是Auto js xff1f Auto js是基于JavaScript语言运行在Android平台上的工具 它依赖于无障碍服务 它可以做什么 xff1f 解放双手 xff0c 让手机自动打游戏 自动签到 自动领红包等等等等 它有什么优点
  • 操作系统(C++)——生产者消费者模型

    一 C 43 43 实现代码 span class token macro property span class token directive hash span span class token directive keyword i
  • 2023.03.14java内置的线程池 -》 ScheduledExecutorService 具备延迟运行的能力!的使用

    区别 ScheduledExecutorService xff0c 执行任务方法为schedule xff0c 而不是submit es schedule new MyRunnable i 2 TimeUnit SECONDS 指定线程了线
  • sudo rm -rf /* 命令运行演示(管理员身份删除根目录所有文件)

    一 前言 闲来无事 xff0c 好奇传说中的 sudo rm rf 命令究竟有什么样的魅力让无数人趋之若鹜 xff0c 本着奉献精神 xff0c 作者将在自己的服务器上测试一番 xff0c 各位读者切勿轻易尝试 不 xff0c 切勿尝试 x

随机推荐