JavaFX桌面应用-构建程序框架
看到JavaFX应用很多人都会说JavaFX应用太丑了,确实JavaFX比起Qt、MFC、Delphi这些界面确实丑了一点,但也不是没有可以美化的空间。
跟网页一样,单纯HTML不加任何CSS的时候也不是很美观,JavaFX如稍微美化一下还是可以接受的。
比如,没有任何css修饰前的JavaFX应用是这样的:

经过简单的修饰之后的JavaFX应用是这样的:

对比一下,很明显简单修饰美化过的界面要比原始的好看很多(个人觉得)。
如果需要将界面改造成上图的样式,那么就不能使用JavaFX自带stage的样式,需要自己改造一下。
本文涉及的JavaFX用法可以参考之前的文章。
~ JavaFX桌面应用开发系列文章传送门 ~
- JavaFX桌面应用开发-HelloWorld
- JavaFX布局神器-SceneBuilder
- JavaFX让UI更美观-CSS样式
- JavaFX桌面应用-为什么应用老是“未响应”
- JavaFX桌面应用-MVC模式开发,“真香”
- JavaFX桌面应用-loading界面
- JavaFX桌面应用-表格用法
- JavaFX桌面应用-视频转码工具
- JavaFX桌面应用-SpringBoot + JavaFX
构建自己的JavaFX程序框架,需要解决以下问题:
- 取消默认的Stage样式
- 构造自己“最小化”,“关闭”面板
- 让程序可以拖动
- 处理“最小化”,“关闭”事件
- 构造自己的桌面程序
取消Stage样式
取消Stage的样式比较简单,这个在“JavaFX桌面应用-loading界面”那篇文件已经提过,就是设置Stage的Style为TRANSPARENT即可。
stage.initStyle(StageStyle.TRANSPARENT);
Style为TRANSPARENT之后,应用就没有了“最小化”、“最大化”、“关闭”面板了,如图:

这个时候,可以用BorderPane来重构桌面框架,将原来放在Scene的root组件放在BorderPane的CENTER位置,然后自己构造的“最小化”、“最大化”、“关闭”面板放在BorderPane中的TOP位置即可。

构造自己“最小化”、“最大化”、“关闭”面板
按照上面设想的布局,构造自己“最小化”、“最大化”、“关闭”面板,这里我不需要“最大化”按钮,只需要“最小化”和关闭。
整体的布局为:
HBox[LOGO,标题,最小化,关闭]
这里采用一个HBox里面放置四个Label来实现“最小化”、“关闭”面板,可以在“标题”和“最小化”中间插入一个Pane,采用HGrow将两边“撑开”。
HBox hbox = new HBox();
// LOGO
Label logo = new Label();
hbox.getChildren().add(logo);
// TITLE
Label titleLbl = new Label(title);
hbox.getChildren().add(titleLbl);
// PANE
Pane pane = new Pane();
HBox.setHgrow(pane, Priority.ALWAYS);
hbox.getChildren().add(pane);
// MIN
Label min = new Label();
hbox.getChildren().add(min);
// CLOSE
Label close = new Label();
hbox.getChildren().add(close);
代码只用到了两个容器(HBox、Pane)和一个控件(Label),而所有具体的内容交给CSS来处理:
.hbox{
-fx-background-color: #40444f;
}
.logo{
-fx-background-radius: 2px;
-fx-background-position: center center;
-fx-background-repeat: no-repeat;
-fx-background-size: 35px 35px;
-fx-background-color: transparent;
-fx-background-image: url("/images/logo.jpg");
-fx-border-width: 0;
}
.title{
-fx-text-fill: #fff;
}
.close{
-fx-background-position: center center;
-fx-background-repeat: no-repeat;
-fx-background-size: 43px 34px;
-fx-background-color: transparent;
-fx-background-image: url("/images/close_0.png");
-fx-cursor: hand;
-fx-border-width: 0;
}
.close:hover{
-fx-background-color: #f45454;
-fx-background-image: url("/images/close_1.png");
-fx-border-width: 0;
}
.min{
-fx-background-position: center center;
-fx-background-repeat: no-repeat;
-fx-background-size: 43px 34px;
-fx-background-color: transparent;
-fx-background-image: url("/images/min_0.png");
-fx-cursor: hand;
-fx-border-width: 0;
}
.min:hover{
-fx-background-color: derive(#ddd, 10%);
-fx-background-image: url("/images/min_1.png");
-fx-border-width: 0;
}
然后让HBox容器加载这个CSS,并为每个控件设置对一个的class:
// HBox
hbox.getStylesheets().add(this.getClass().getResource("/css/title-hbox.css").toExternalForm());
hbox.getStyleClass().add(hboxCssClass);
// LOGO
logo.getStyleClass().add(logoCssClass);
// TITLE
titleLbl.getStyleClass().add(this.titleCssClass);
// MIN
min.getStyleClass().add(minCssClass);
// CLOSE
close.getStyleClass().add(closeCssClass);
面板构建完成后,只需要将它跟原来Scene的root用BorderPane组装起来即可。
stage.initStyle(StageStyle.TRANSPARENT);
BorderPane borderPane = new BorderPane();
borderPane.setTop(hbox);
borderPane.setCenter(root);
Scene scene = new Scene(borderPane);
stage.setScene(scene);
这样整个界面框架就构造完成了。
让程序可以拖动
界面已经构造完成了,但是会发现重构的界面无法拖动,需要自己来实现拖动功能。
界面拖动功能可以通过鼠标的拖拽事件和位置计算来实现,通过鼠标拖拽时的坐标同步更新Stage的坐标来达到拖动效果。
鼠标拖拽事件需要实现EventHandler<MouseEvent>接口:
public class JFXStage implements EventHandler<MouseEvent> {
private double xOffset = 0;
private double yOffset = 0;
@Override
public void handle(MouseEvent event) {
if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
xOffset = event.getSceneX();
yOffset = event.getSceneY();
} else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
stage.setX(event.getScreenX() - xOffset);
if (event.getScreenY() - yOffset < 0) {
stage.setY(0);
} else {
stage.setY(event.getScreenY() - yOffset);
}
}
}
}
然后让需要拖拽的组件注册这个监听器即可,这里只需要头部自定义面板那块可以按住拖动即可,所以只需要HBox注册这个监听器即可:
hbox.setOnMousePressed(this);
hbox.setOnMouseDragged(this);
这样,自己构建的JavaFX桌面框架就可以拖动了,效果如下:

处理“最小化”、“最大化”、“关闭”事件
最后需要做的就是处理,自定义按钮的那些事件,这个自己构建的JavaFX桌面应用才能实现最小化和关闭功能。
最小化功能通过setIconified来实现,当用户点击min这个Label的实现,调用stage的setIconified,将程序最小化:
min.setOnMouseClicked(e -> stage.setIconified(true));
关闭按钮则复杂一点,要看有没有注册关闭回调,如果有就交给回调去处理,如果没有就直接关闭。
close.setOnMouseClicked(e -> {
EventHandler<WindowEvent> opt = stage.onCloseRequestProperty().get();
if (opt != null) {
opt.handle(new WindowEvent(stage, WindowEvent.WINDOW_CLOSE_REQUEST));
} else {
stage.close();
}
});
构建自己的桌面程序
使用方面其他流程不变,只是不需要在构建Scene了,然后将Stage和root叫JFXStage去构建即可:
@SpringBootApplication
public class Main extends JFXApplication {
public static void main(String[] args) {
launch(Main.class, HelloworldView.class, new CustomStarterScreen(), args);
}
@Override
protected void beforeStageDisplay(Stage stage, Parent root, ConfigurableApplicationContext ctx) {
JFXStage.of(stage, root).setTitle(" JavaFX桌面应用", null).build();
}
}
结合Springboot,再构建自己的JavaFX桌面框架不仅界面美化了,而且开发方便了很多。
本文的完成源码仅JFXStage这个类,可以在公众号上获取。
关注公众号,下次将介绍JavaFX桌面应用如何实现在线升级。
=========================================================
关注 公众号 “HiIT青年” 发送 “javafx-jfxstage” 获取源码。

关注公众号,阅读更多文章。
JavaFX桌面应用-构建程序框架的更多相关文章
- 《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立
原文:<ArcGIS Engine+C#实例开发教程>第一讲桌面GIS应用程序框架的建立 摘要:本讲主要是使用MapControl.PageLayoutControl.ToolbarCon ...
- Microsoft Orleans构建高并发、分布式的大型应用程序框架
Microsoft Orleans 在.net用简单方法构建高并发.分布式的大型应用程序框架. 原文:http://dotnet.github.io/orleans/ 在线文档:http://dotn ...
- [资源共享]C#+AE构建GIS桌面端应用系统框架-全代码
转自:http://www.cnblogs.com/gispeng/archive/2008/10/06/1304534.html [资源共享]C#+AE构建GIS桌面端应用系统框架-全代码 ( ...
- JavaFX桌面应用-MVC模式开发,“真香”
使用mvc模块开发JavaFX桌面应用在JavaFX系列文章第一篇 JavaFX桌面应用开发-HelloWorld 已经提到过,这里单独整理使用mvc模式开发开发的流程. ~ JavaFX桌面应用开发 ...
- JavaFX桌面应用-SpringBoot + JavaFX
SpringBoot对于Java程序员来说可以是一个福音,它让程序员在开发的时候,大大简化了各种spring的xml配置. 那么在JavaFX项目使用SpringBoot会是怎么样的体验呢? 这次使用 ...
- Android核心分析之二十Android应用程序框架之无边界设计意图
Android应用程序框架1 无边界设计理念 Android的应用框架的外特性空间的描述在SDK文档(http://androidappdocs.appspot.com/guide/topics/fu ...
- VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)
VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html 上一讲中讲了VS20 ...
- 美团小程序框架mpvue入门
mpvue 主要特性 使用 mpvue 开发小程序,你将在小程序技术体系的基础上获取到这样一些能力: 1. 彻底的组件化开发能力:提高代码复用性 2. 完整的 Vue.js 开发体验 3. 方便的 V ...
- VS2010/MFC编程入门之五十二(Ribbon界面开发:创建Ribbon样式的应用程序框架)
上一节中鸡啄米讲了GDI对象之画刷CBrush,至此图形图像的入门知识就讲完了.从本节开始鸡啄米将为大家带来Ribbon界面开发的有关内容.本文先来说说如何创建Ribbon样式的应用程序框架. Rib ...
随机推荐
- Windows Server2008RFTP隔离账户的搭建
Step1:添加用户 打开DOS命令, net user net user u1 123.com /add net user u2 123.com /add Step2:创建文件夹 Step3:修改用 ...
- 百钱百鸡小游戏PHP代码
<?php // 计算小鸡的数量 $count=[]; // 第一个for循环计算公鸡 for ($gj=1;$gj<(100/5);$gj++){ // 第二个for循环计算母鸡 for ...
- 手把手教Linux驱动1-模块化编程,玩转module
大家好,从本篇起,一口君将手把手教大家如何来学习Linux驱动,预计会有20篇关于驱动初级部分知识点.本专题会一直更新,有任何疑问,可以留言或者加我微信. 一.什么是模块化编程? Linux的开发者, ...
- Java算法——回溯法
回溯法一种选优搜索法,又称试探法.利用试探性的方法,在包含问题所有解的解空间树中,将可能的结果搜索一遍,从而获得满足条件的解.搜索过程采用深度遍历策略,并随时判定结点是否满足条件要求,满足要求就继续向 ...
- 服务发现Eureka、zookeeper、consul
Spring Cloud为开发人员提供了工具,以快速构建分布式系统中的某些常见模式(例如,配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举,分布式会话,群集状态). ...
- 用Java写编译器(1)- 词法和语法分析
词法和语法分析器构建 ANTLR简介 ANTLR全称ANother Tool for Languate Recognition,是基于LL(*)算法实现的语法分析器生成器和词法分析器生成器,由旧金山大 ...
- 【API进阶之路】破圈,用一个API代替10人内容团队
摘要:我用一个API代替10人内容团队,一年帮老板省了一百万. 自从学习API以后,我用技术手段相继帮助业务部.市场部解决了不少难题,算是从纯研发破圈发展到了业务端.老板召开业务讨论会的时候也会带上我 ...
- MySQL 数据库 查 续
MySQL 增删查改 必知必会 4.1.13 使用 like 关键字进行模糊查询 -- 说明:模糊查询,使用查询关键字like,like意思是类似于,像...的意思 -- 模糊查询,支持两种字符匹配符 ...
- Palindrome subsequence(区间dp+容斥)
In mathematics, a subsequence is a sequence that can be derived from another sequence by deleting so ...
- Jwt快速入门(copy即可)
Jwt 什么是jwt JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理和用法. 互联网服务离不开用户认证.一般流程是下面这样. 1.用户向服务器发送用户名和 ...