【javaFX基础】利用鼠标拖拽事件实现绘图

一、绘图代码实践

1、鼠标绘线图

用到setOnMousePressed和setOnMouseDragged两个属性

复制代码
package org.example.testsc1;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import javax.print.attribute.standard.PrinterMakeAndModel;
import java.io.IOException;

public class HelloApplication extends Application {
    public static final double WIDTH =800,HEIGHT = 600;
    private Canvas canvas =new Canvas(WIDTH,HEIGHT);
    private GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
    private double x,y;//坐标

    public static void main(String[] args){
        Application.launch(args);
    }
    @Override
    public void start(Stage primaryStage)throws Exception {
        canvas.setLayoutX(0);
        canvas.setLayoutY(0);
        canvas.setOnMousePressed(event -> {//鼠标按下的初始位置
                x=event.getX();
                y=event.getY();
    });
        canvas.setOnMouseDragged(event->{//鼠标拖拽
            double x2=event.getX(),y2=event.getY();
            graphicsContext.strokeLine(x,y,x2,y2);
            x=x2;
            y=y2;
        });
        AnchorPane root=new AnchorPane(canvas);
        Scene scene=new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

实现效果

2、鼠标绘框图

在 JavaFX 的 GraphicsContext 类中,strokeRect 方法用于绘制一个矩形的边框。它不会填充矩形内部,只画轮廓。

复制代码
/*
x:矩形左上角的 X 坐标。
y:矩形左上角的 Y 坐标。
width:矩形的宽度。
height:矩形的高度
*/
void strokeRect(double x, double y, double width, double height)

完整代码

其中注意清除过程框图、往上绘框图、保存快照的细节

复制代码
package org.example.testsc1;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import javax.print.attribute.standard.PrinterMakeAndModel;
import java.io.IOException;
import java.io.WriteAbortedException;
import java.lang.ref.WeakReference;

public class HelloApplication extends Application {
    public static final double WIDTH =800,HEIGHT = 600;
    private Canvas canvas =new Canvas(WIDTH,HEIGHT);
    private GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
    private double x,y;//坐标
    private WritableImage image=null;

    public static void main(String[] args){
        Application.launch(args);
    }
    @Override
    public void start(Stage primaryStage)throws Exception {//鼠标按下的初始位置
        canvas.setLayoutX(0);
        canvas.setLayoutY(0);
        canvas.setOnMousePressed(event -> {
                x=event.getX();
                y=event.getY();
    });
        canvas.setOnMouseDragged(event->{//鼠标拖拽
            double startx=x,starty=y;
            double endx=event.getX();
            double endy=event.getY();
            if(endx<startx){//解决不能往上绘制的问题
                startx=endx;
                endx=x;
            }
            if(endy<starty){
                starty=endy;
                endy=y;
            }
            double height=endy-starty;
            double width=endx-startx;
            graphicsContext.clearRect(0,0,WIDTH,HEIGHT);//清除画布上指定矩形区域内的所有内容
            graphicsContext.drawImage(image,0,0,WIDTH,HEIGHT);//保存快照
            graphicsContext.strokeRect(startx,starty,width,height);//绘制一个矩形的边框。它不会填充矩形内部,只画轮廓。
        });
        //设置松开手的快照
        canvas.setOnMouseReleased(event->{
            image=canvas.snapshot(null,null);
            //创建当前 Canvas 内容的快照,生成一个 WritableImage 对象,包含绘制在 Canvas 上的所有图形。
        });
        AnchorPane root=new AnchorPane(canvas);
        Scene scene=new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

实现效果

二、保存所绘的图

作用: 将 JavaFX 的 WritableImage 转换为 Java AWT 的 BufferedImage
结果: 得到 BufferedImage(标准 Java 图像类型)
**特点:**这是 Java 标准库的图像格式,兼容性更好

复制代码
BufferedImage bufferedImage = SwingFXUtils.fromFXImage(writableImage, null);

转换的必要性:
文件保存: ImageIO.write() 只接受 BufferedImage
图像处理: 很多 Java 图像处理库只支持 BufferedImage
**兼容性:**与旧版 Swing 应用程序集成

三、问题待解决

复制代码
  BufferedImage bufferedImage = SwingFXUtils.fromFXImage(writableImage, null);

使用上述语句,会提示:java: 程序包javafx.embed.swing不存在

相关推荐
土族程序员3 个月前
JavaFX CSS @font-face 错误全面分析 loadStylesheetUnPrivileged / reportException
java·css·javafx
qqxhb5 个月前
零基础学Java——第十一章:实战项目 - 桌面应用开发(JavaFX入门)
java·开发语言·javafx
程序猿小D7 个月前
第三百八十九节 JavaFX教程 - JavaFX WebEngine
java·eclipse·intellij-idea·vr·javafx
海边漫步者8 个月前
Idea2024中搭建JavaFX开发环境并创建运行项目
java·intellij-idea·javafx
十秒耿直拆包选手10 个月前
IDEA下加载音频文件操作
java·ide·intellij-idea·javafx
Suncsf1 年前
JavaFX WebView + Vue初始化加载数据解决方案
前端·javascript·vue.js·javafx
0zxm1 年前
JavaFx -- chapter06(UDPSocket)
java·网络·单片机·嵌入式硬件·gui·javafx
ceclar1231 年前
JavaFX基本控件-Label
java·javafx
南怪布德1 年前
Gluon 编译 JavaFx -> android apk
android·linux·javafx·centos8·gluon