用JAVAFX做一个简单的桌面宠物(一)

一、写在前面

  1. 这学期才学的java,课设不会写游戏,只好做一个桌面宠物了。JavaFX更是第一次用,边学边做的,所以有不足的地方还请提出,感激不尽。
  2. 环境:jdk1.8.0_241, eclipse。
  3. 用javafx是因为它gif的显示效果很好,不会像swing那样闪烁或循环过快,用来做桌面宠物正合适。
  4. 宠物用的是罗小黑和比丢(墙裂推荐,超好看的国漫),lxh和biu分别是它们对应的图片文件夹,。
  5. 有四个类,包括Main(设置窗体),EventListener(处理点击事件和加载图片),UI(设置系统托盘、弹出菜单、聊天气泡和实现自定义功能),Move(实现自动行走)。
  6. 源代码:https://gitee.com/june_day/javafx_desktop_pet

二、窗体设置(Main类)

(一)类成员

	private static ImageView imageView;
	EventListener listen;
	VBox messageBox;//聊天气泡
	int petID = 1;//宠物ID。罗小黑=0,比丢=1
	double xOffset = 0; 
	double yOffset = 0;

(二)图片容器

	Image image = new Image(this.getClass().getResourceAsStream("/biu/biu0.gif"));//biu即比丢
	ImageView  imageView = new ImageView(image); 
	//设置容器的位置
	imageView.setX(0); 
	imageView.setY(0);
	imageView.setLayoutX(0);
	imageView.setLayoutY(50);
	//设置图片显示的大小
	imageView.setFitHeight(150); 
	imageView.setFitWidth(150); 
	imageView.setPreserveRatio(true); //保留 width:height的比例

特别说明:加载相对路径的图片要用class.getResourceAsStream,不然打包成jar包运行时会报错:找不到文件路径!路径中第一个“/”是必需的,它表示类的根目录,类文件夹在此项目中与lxh文件夹和biu文件夹在同一级。

(三)创建UI类

	UI ui = new UI(imageView, petID, listen,primaryStage);
   	ui.addMessageBox("你好吖~");

(四)创建pane, scene, stage

	AnchorPane pane = new AnchorPane(ui.getMessageBox(),ui.getImageView());
	Scene scene = new Scene(pane,400,400);
	scene.setFill(null);
	primaryStage.setScene(scene);
	//设置窗体的初始位置
	primaryStage.setX(850);
	primaryStage.setY(400);
	primaryStage.setAlwaysOnTop(true);//窗口总显示在最前
	//因为最后要播放告别动画,所以要延缓关闭
	primaryStage.setOnCloseRequest( event ->{event.consume(); ui.end();});
	primaryStage.show();

primaryStage.setOnCloseRequest( event ->{event.consume(); ui.end();});的说明:

  • 点击任务栏的“关闭窗口”时,播放告别动画,同时使托盘的图标也关闭。
  • event.consume()是必需的,这样才能真正阻止Window Close事件的默认处理。
  • 如果不设置告别动画,可以仅仅使用System.exit(0);来直接退出,不需要event.consume();

(五)设置窗体背景透明

imageView.setStyle("-fx-background:transparent;");
pane.setStyle("-fx-background:transparent;");
primaryStage.initStyle(StageStyle.TRANSPARENT);

这样做之后标题栏、边框、右上角的关闭等按钮也都没有了。

(六)让宠物可拖动

	//先获取按下鼠标时的坐标p1,再将窗体坐标设为p1加拖动的位移量
	pane.setOnMousePressed(event -> {
	    xOffset = event.getSceneX();
	    yOffset = event.getSceneY();
	});
	pane.setOnMouseDragged(event -> {
		primaryStage.setX(event.getScreenX() - xOffset);
		primaryStage.setY(event.getScreenY() - yOffset);
	});

三、Main类完整代码

public class Main extends Application {
	private static ImageView imageView;
	EventListener listen;
	VBox messageBox;//聊天气泡
	int petID = 1;//宠物ID。罗小黑=0,比丢=1
	double xOffset = 0; 
	double yOffset = 0;
	
	public void start(Stage primaryStage) {
		try {
			/*
			 * 创建初始的图
			 * 加载相对路径的图片要用class.getResource,不然运行jar包时会报错:找不到文件路径!
			 * 路径中第一个“/”是必需的,它表示类的根目录,类文件夹在此项目中与lxh和biu在同一级
			 */
			Image image = new Image(this.getClass().getResourceAsStream("/biu/biu0.gif"));
	      	imageView = new ImageView(image); 
	      	imageView.setX(0); 
	      	imageView.setY(0);
	      	imageView.setLayoutX(0);
	      	imageView.setLayoutY(50);
	      	//设置图片显示的大小
	      	imageView.setFitHeight(150); 
	      	imageView.setFitWidth(150); 
	      	//添加图片的点击事件
	      	listen = new EventListener(imageView , petID);
	      	imageView.addEventHandler(MouseEvent.MOUSE_CLICKED, listen);
	      	
	      	imageView.setPreserveRatio(true); //保留 width:height的比例
	      	imageView.setStyle("-fx-background:transparent;");//容器背景设为透明
	      	
	      	UI ui = new UI(imageView, petID, listen,primaryStage);
	      	ui.addMessageBox("你好吖~");
	      	
			AnchorPane pane = new AnchorPane(ui.getMessageBox(),ui.getImageView());
			
			pane.setStyle("-fx-background:transparent;");
			//使窗体能拖动。先获取按下鼠标时的坐标p1,再将窗体坐标设为p1加拖动的位移量
			pane.setOnMousePressed(event -> {
			    xOffset = event.getSceneX();
			    yOffset = event.getSceneY();
			});
			pane.setOnMouseDragged(event -> {
				primaryStage.setX(event.getScreenX() - xOffset);
				primaryStage.setY(event.getScreenY() - yOffset);
			});
			
			Scene scene = new Scene(pane,400,400);
			scene.setFill(null);
			scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
			
			primaryStage.setScene(scene);
			//设置窗体的初始位置
			primaryStage.setX(850);
			primaryStage.setY(400);
			primaryStage.setAlwaysOnTop(true);//窗口总显示在最前
			//修改任务栏图标
			primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("icon.png")));
			//下句隐藏任务栏图标,但javafx的stage.initStyle(Style)只能有一个起效,只好作罢
//			stage.initStyle(StageStyle.UTILITY);
			primaryStage.initStyle(StageStyle.TRANSPARENT);//背景透明
			/*
			 * 点击任务栏的“关闭窗口”时,播放告别动画,同时使托盘的图标也关闭.
			 * event.consume()是必需的,这样才能真正阻止Window Close事件的默认处理。
			 * 如果仅仅使用System.exit(0);则不需要event.consume();
			*/
			primaryStage.setOnCloseRequest( event ->{event.consume(); ui.end();});
			primaryStage.show();
			
			ui.setTray(primaryStage);//添加系统托盘
			Thread thread = new Thread(ui);
			thread.start();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		launch(args);
	}
}
  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值