手拉手JavaFX UI控件与springboot3+FX桌面开发(中):https://developer.aliyun.com/article/1431715
drawImage绘制图片
drawImage(Image img,double sx,double sy,double sw,double sh,double dx,double dy,double dw,double dh)
img:要绘制的图片
sx,sy,sw,sh:源矩形(s,source)
dx,dy,sw,dh:目标矩形(d,destination)
样式单CSS
CSS,Cascading Style Sheets
用于定义界面的显示样式(背景,边框,字体等)
-fx-padding:填充、-fx-font-size:字体大小、-fx-text-fill:文件颜色
新建javafx项目时,已经默认创建了一个CSS文件:application.css
图片背景
CSS文件
#pane{ -fx-background-image: url("中国风1.JPG"); /*-fx-background-repeat: stretch; -fx-background-size: 900 506; -fx-background-position: center center;*/ /*-fx-effect: dropshadow(three-pass-box, black, 30, 0.5, 0, 0);*/ } .root{ -fx-background-image: url("中国风1.JPG"); } Java文件 public class CSSdemo extends Application { TextField textField =new TextField(); @Override public void start(Stage stage) throws Exception { stage.setTitle("CSSdemo"); BorderPane borderPane = new BorderPane(); HBox hbox =new HBox(10); Button b =new Button("选择"); Button c =new Button("提交"); textField.getStyleClass().add("text"); b.getStyleClass().add("button"); hbox.getChildren().addAll(textField,b,c); // borderPane.setId("pane"); borderPane.setTop(hbox); Scene scene =new Scene(borderPane,300,400); //scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm()); //scene.getStylesheets().add(CSSdemo.class.getResource("style.css").toExternalForm()); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(); } }
SceneBuilder可视化设计
Eclipse添加javafx组件
在Work with中添加:http://download.eclipse.org/efxclipse/updates-released/2.3.0/site/
Eclpise-jdk11-javaFx
module Java11 { exports com; requires javafx.base; requires javafx.controls; requires javafx.fxml; requires javafx.graphics; requires javafx.media; requires javafx.swing; requires javafx.web; requires javafx-swt; }
媒体播放器
Javafx自带媒体播放的支持
Media:表示一个媒体文件(URL)
MediaPlayer:表示一个播放器(播放控件)
MediaView:表示一个播放控件(显示)
Eclpise应用程序的发布
创建一个文件夹,将jdk里的jre拷贝过去
创建启动脚本
IEDA 应用程序的发布
右击项目或模块
open module settings
选择ArtiFacts->JAR->From modules with dependencies
可以选择包含测试类或者不包含
第一个仅导出目标jar包
第二个导出目标jar包和项目所依赖的jar包
选择Include in project build
Build -> Build Artifacts -> Build
构建结果如下:
创建一个文件夹,将jdk里的jre拷贝过去
创建启动脚本
start jre\bin\javaw.exe -jar ch01.jar
登入窗口+小知识点
public class LoginDemo extends Application{ public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { stage.setTitle("Login"); Label name =new Label("账号:"); Label password = new Label("密码:"); name.setFont(Font.font("宋体",20)); TextField inname =new TextField(); inname.setUserData("hello"); PasswordField inPasswordField =new PasswordField(); inPasswordField.setUserData("123456"); Button login =new Button("登录"); Button clear =new Button("清理"); GridPane gr =new GridPane(); gr.setStyle("-fx-background-color:#FFF5EE"); //列,行 gr.add(name, 0, 0); gr.add(inname, 1, 0); gr.add(password, 0, 1); gr.add(inPasswordField, 1, 1); gr.add(login, 1, 2); gr.add(clear, 0, 2); gr.setHgap(10); gr.setVgap(10); GridPane.setMargin(login, new Insets(0, 0, 0, 150)); gr.setAlignment(Pos.CENTER); //清理事件 clear.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { inname.setText(""); inPasswordField.setText(""); } }); //登录事件 login.setOnAction((e)->{ String name1 =inname.getText(); String password1 =inPasswordField.getText(); if (inname.getUserData().equals(name1) && inPasswordField.getUserData().equals(password1)) { loginWindos lonWindos = new loginWindos(name1); stage.close(); }else { Alert waring = new Alert(Alert.AlertType.WARNING); waring.setHeaderText("用户名/密码出错"); waring.setContentText("请重新输入!"); //showAndWait();当输入的焦点在对话框里,后面的界面无法输入(不往下走,知道对话框关闭) waring.showAndWait(); //呼吸灯 FadeTransition fade = new FadeTransition(); fade.setDuration(javafx.util.Duration.seconds(2)); fade.setNode(gr); fade.setFromValue(0); fade.setToValue(1); fade.play(); } }); Scene scene =new Scene(gr); stage.setScene(scene); stage.setWidth(400); stage.setHeight(500); stage.setResizable(false); stage.show(); } class loginWindos { private final Stage stage = new Stage(); public loginWindos(String name) { stage.setTitle("qgs"); Alert waring = new Alert(Alert.AlertType.INFORMATION); waring.setHeaderText("欢迎"+name+"来到qgs操作界面"); waring.showAndWait(); stage.show(); } } }
Springboot3+JavaFX
Pom.xml加入依赖
<dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>17.0.2</version> </dependency>
package com.example.fx; import javafx.application.Application; import javafx.application.HostServices; import javafx.geometry.Rectangle2D; import javafx.scene.Cursor; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.TextArea; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.stage.Screen; import javafx.stage.Stage; public class fxmain extends Application { @Override public void start(Stage stage) throws Exception { stage.setTitle("SceneDemo"); BorderPane borderPane =new BorderPane(); TextArea textArea =new TextArea(); HBox hbox =new HBox(); Button openbaidu =new Button("打开百度"); Button getScreenvalue = new Button("获取屏幕属性值"); hbox.getChildren().addAll(openbaidu,getScreenvalue); openbaidu.setOnAction((e)->{ HostServices hostServices = getHostServices(); hostServices.showDocument("https://www.baidu.com/"); }); getScreenvalue.setOnAction((e)->{ Screen primary = Screen.getPrimary(); double dpi = primary.getDpi(); System.out.println("当前屏幕dpi:"+dpi); Rectangle2D rec1 = primary.getBounds(); Rectangle2D rec2 = primary.getVisualBounds(); textArea.appendText("\n----全部屏幕--------"); // textArea.appendText("\n左上角x:"+rec1.getMinX()+"左上角y"+rec1.getMinY()); // textArea.appendText("\n右下角x--"+ rec1.getMaxX()+"右下角y--"+ rec1.getMaxY()); textArea.appendText("\n宽度:"+rec1.getWidth()+"高度"+rec1.getHeight()); textArea.appendText("\n----可以看到的屏幕--------"); // textArea.appendText("\n左上角x:"+rec2.getMinX()+"左上角y"+rec2.getMinY()); // textArea.appendText("\n右下角x--"+ rec2.getMaxX()+"右下角y--"+ rec2.getMaxY()); textArea.appendText("\n宽度:"+rec2.getWidth()+"高度"+rec2.getHeight()); }); borderPane.setTop(hbox); borderPane.setCenter(textArea); Scene scene =new Scene(borderPane,400,400); scene.setCursor(Cursor.CLOSED_HAND);//手 /** * scene.setCursor(Cursor.HAND);//手,箭头啥的 * Cursor CROSSHAIR 光标十字光标 * Cursor . DEFAULT 光标默认值 * Cursor DISAPPEAR 光标消失 * Cursor CLOSED_HAND 光标闭合手 * Contextmenudemo 上下文菜单演示 * Cursor E _ RESIZE 光标E _ RESIZE */ stage.setScene(scene); stage.show(); } }
package com.example.fx; import com.example.domain.Corrdinate; import com.example.util.EasyExcelUtil; import javafx.application.Application; import javafx.application.HostServices; import javafx.geometry.Rectangle2D; import javafx.scene.Cursor; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.TextArea; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.stage.FileChooser; import javafx.stage.Screen; import javafx.stage.Stage; import java.io.File; import java.io.IOException; import java.util.List; public class fxmain extends Application { private static String filePath =null; @Override public void start(Stage stage) throws Exception { stage.setTitle("坐标验证"); BorderPane borderPane =new BorderPane(); TextArea textArea =new TextArea(); HBox hbox =new HBox(); Button openbaidu =new Button("打开百度"); Button upFile =new Button("上传文件"); Button executeFile =new Button("执行"); Button getScreenvalue = new Button("获取屏幕属性值"); hbox.getChildren().addAll(upFile,executeFile); openbaidu.setOnAction((e)->{ HostServices hostServices = getHostServices(); hostServices.showDocument("https://www.baidu.com/"); }); //上传文件 upFile.setOnAction((e)->{ FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("选择Excel文件"); fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); //过滤 fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("All Excel", "*.xlsx"), new FileChooser.ExtensionFilter("XLS", "*.xls"), new FileChooser.ExtensionFilter("XLSX", "*.xlsx")); File file = fileChooser.showOpenDialog(stage); try { System.out.println("路径:"+file.getCanonicalPath()); textArea.setText("路径:"+file.getCanonicalPath()); filePath=file.getCanonicalPath(); } catch (IOException ex) { throw new RuntimeException(ex); } if (file != null) { } }); //执行 executeFile.setOnAction((e)->{ List<Corrdinate> list = EasyExcelUtil.importExcel(filePath); textArea.setText("生成文件路径C:\\Users\\Administrator\\Desktop\\demofile"); for (Corrdinate corrdinate : list) { textArea.appendText("\n"+corrdinate.toString()); } }); getScreenvalue.setOnAction((e)->{ Screen primary = Screen.getPrimary(); double dpi = primary.getDpi(); System.out.println("当前屏幕dpi:"+dpi); Rectangle2D rec1 = primary.getBounds(); Rectangle2D rec2 = primary.getVisualBounds(); textArea.appendText("\n----全部屏幕--------"); // textArea.appendText("\n左上角x:"+rec1.getMinX()+"左上角y"+rec1.getMinY()); // textArea.appendText("\n右下角x--"+ rec1.getMaxX()+"右下角y--"+ rec1.getMaxY()); textArea.appendText("\n宽度:"+rec1.getWidth()+"高度"+rec1.getHeight()); textArea.appendText("\n----可以看到的屏幕--------"); // textArea.appendText("\n左上角x:"+rec2.getMinX()+"左上角y"+rec2.getMinY()); // textArea.appendText("\n右下角x--"+ rec2.getMaxX()+"右下角y--"+ rec2.getMaxY()); textArea.appendText("\n宽度:"+rec2.getWidth()+"高度"+rec2.getHeight()); }); borderPane.setTop(hbox); borderPane.setCenter(textArea); Scene scene =new Scene(borderPane,400,400); scene.setCursor(Cursor.CLOSED_HAND);//手 /** * scene.setCursor(Cursor.HAND);//手,箭头啥的 * Cursor CROSSHAIR 光标十字光标 * Cursor . DEFAULT 光标默认值 * Cursor DISAPPEAR 光标消失 * Cursor CLOSED_HAND 光标闭合手 * Contextmenudemo 上下文菜单演示 * Cursor E _ RESIZE 光标E _ RESIZE */ stage.setScene(scene); stage.show(); } }
jdk1.8以上的版本(jdk9,jdk11,jdk17等)没有jre的问题
D:\Program Files\Java\jdk-17目录下执行
bin\jlink.exe --module-path jmods --add-modules java.desktop --output jre