本文共 6661 字,大约阅读时间需要 22 分钟。
博主纯业余,不是开发人员。
下面提到的四个文件:
Main.java FxmlController.java FXML文件(.fxml) test.css
src{ fx{ Main.java FxmlController.java } fxml{ FXML文件(test.fxml) } css{ test.css } }
Model View Controller
经典MVC模式中,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。(-百度百科:)
引用b站视频的评论 @东篱雪清 回复 @电脑玩家Rain :
8、HTML------------->FXML :结构 (美术人员)
9、CSS--------------->CSS: 外观权 (美术人员)
10、JavaScript-------->Controller.java : 行为 (开发人员)
JavaFX CSS文件里的选择器:(粗略的使用,未涉及深入的内容)
1.以#为前缀的ID选择器:
#id{ …/* 按行写的带-fx前缀的css代码格式:属性:值 */ …}
根据ID选择设置过ID的组件。
例如:
#fxmlButton1{ -fx-font-size: 18; -fx-background-color: black; -fx-text-fill:Snow;}
2.以.为前缀的 类class 与 类型type 选择器:
.className{ …/* 按行写的带-fx前缀的css代码格式 :属性:值*/ … }
同时改变一类组件。
例如:
.button{ -fx-font-size: 18; -fx-background-color: black; -fx-text-fill:Snow;}
3.给组件添加响应事件时的样式:(伪类选择器)
selector : pseudo-class {…/* 按行写的带-fx前缀的css代码格式:属性:值 */ …}
例如:
/* 鼠标在按钮上悬停 对所有按钮都生效 */.button:hover{ -fx-background-color: blue;}
注:css文件的语法错误等只有在调用到相关代码才能被报出来。
参考:
【 】
https://blog.csdn.net/yye894817571/article/details/79416036
在FXML文件中在根结点添加指定控制器FxmlController.java语句:
fx:controller=“包名.FxmlController”
(只加载一次)
例如:
<AnchorPane fx:controller="fxControl.FxmlController" ... >
这样就能在FxmlController.java类中实现对组件的控制了。
但下面的标题6可以知道,也可以把事件响应写在Main.java里。
fxmlController.java中的@FXML注释标签:
Main.java文件加载FXML文件,FXML文件实例化对象
例如:
public class FxmlController { @FXML private Button fxmlbutton; // 这个fxmlbutton已经被实例化了, // 实例化的对象就是FXML中以“fxmlbutton”为fx:id的组件。 // fxmlbutton得到了FXML文件中<Button fx:id="fxmlbutton">的引用。 public FxmlController(){ } @FXML private void initialize(){ System.out.println(fxmlbutton.getText()); //打印按钮上的文本 }}
正确的废话:
简单地说,@FXML标签和FXML文件内容对应。实际上对于public 即便不加此标签也能正确执行,但private 必须用到此标签。
而遵循规范的写法应该加上@FXML标签,以便在加载时得以执行。
在Main.java文件中的start方法或stop方法中添加加载FXML文件语句:
需使用FXMLLoader对象:
FXMLLoader fxLoader = new FXMLLoader();
例如:
FXMLLoader fxLoader = new FXMLLoader();URL url = fxLoader.getClassLoader().getResource("fxml/test.fxml");//此处要用getClassLoader(),路径从src下开始,fx包名前不加"/"fxLoader.setLocation(url);AnchorPane root = (AnchorPane) fxLoader.load();
或等价写成:
AnchorPane root = FXMLLoader.load(getClass().getResource("test.fxml"));//此处用getClass()
load()方法原型:(至少有URL参数)
public static <T> T load(URL location, ResourceBundle resources, BuilderFactory builderFactory) throws IOException
在Main.java文件中的start方法或stop方法中引入CSS文件语句:
使用Scene类对象加载:
例如:
Scene scene = new Scene(root);URL url_css = this.getClass().getClassLoader().getResource("/CSS/test.css");scene.getStylesheets().add(url_css.toExternalForm());
或等价写成:
Scene scene = new Scene(root);scene.getStylesheets().add(getClass().getResource("/CSS/test.css").toExternalForm());
比如给FXML里的<Button fx:id=“fxmlbutton”>添加一个事件
三种方法:
1.(推荐)在Main.java里通过控制器类FxmlController的实例化对象来实现控制:
需要在Main.java里实例化一个FxmlController类对象,比如叫做 fc,然后使用FxmlController类里自己写好的get方法(get方法不需要添加@FXML)返回组件。
关于多个监听器,如果通过方法3实例化对象后在Main.java里写动作,会取代(通过x:controller=“fxControl.FxmlController"与 onAction=”#buttonOnAction"组合的这种)方法2中FxmlController.java里写的动作。同一个文件出现重复的动作则后写的方法会覆盖先写的方法。
这种方式需要做的就是在FxmlController.java里写好组件的get方法,然后在Main.java里通过实例化FxmlController对象调用get方法获得组件的引用,然后写动作。
实例化FxmlController对象的方法:通过FXMLLoader类的实例化对象 .getController方法返回FxmlController实例。
例如:
FxmlController.java文件:
@FXML public Button button1; //相应的get方法 //button1的get方法,返回Button类 public Button getButton1() { return button1; }
Main.java文件:
//加载fxml文件 FXMLLoader fxLoader = new FXMLLoader(); URL url = fxLoader.getClass().getResource("fileURL"); fxLoader.setLocation(url); AnchorPane root = (AnchorPane) fxLoader.load(); //把FxmlHandler类实例化: FxmlHandler fxmlHandler = fxLoader.getController(); //获取组件的引用 Button button1= fxmlHandler.getButton1(); /* 然后在下面写响应的动作 */ button1.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { } });
之所以推荐这种写法,是因为这样易于处理组件与组件之间的相互调用。
2.在FXML文件的组件中直接以属性的方式指定,这样指定后就要在FXML中的fx:controller设定的文件中写事件响应:
FXML文件中的代码:
<AnchorPane fx:controller="fxControl.FxmlController" ...> <Button onAction="#buttonOnAction" ...> ...</AnchorPane>
FxmlController.java中的代码:
@FXMLprivate void buttonOnAction(){ ...}
3.可以通过在Main.java中用Button bu = root.lookup("#fxmlbutton"); 获得该组件,再在Main.java里写事件响应:
FXML文件中的代码:
<AnchorPane ...> <Button fx:id="fxmlbutton" ...> ...</AnchorPane>
Main.java中的代码:
Button bu = root.lookup("#fxmlbutton");
1.单独的.css文件(写完后.需要把css文件引入java文件)
遵循CSS语法,自行搜索或参考。
2.可以直接写在Main.java文件里的javafx组件调用的setStyle()方法里,以引号包裹。
例如:
button.setStyle("-fx-background-color: black;" + "-fx-text-fill:Snow;");
3.写在FXML文件里的组件的<style></style>标签里。
例如:
<AnchorPane ...> <Button ...> <style> -fx-background-color: black; -fx-text-fill:Snow; </style> ... </Button> ...</AnchorPane>
参考【】
https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html
参考【】
https://www.bilibili.com/video/BV1pb411s7cd
SceneBuilder可视化图形编辑工具:
下载地址:选择对应版本下载:
(1)gluonhq.com:
https://gluonhq.com/products/scene-builder/
(2)www.oracle.com:
https://www.oracle.com/java/technologies/javafxscenebuilder-1x-archive-downloads.html
在开发工具导入:
(1)Eclipse参考:
(2)IDEA参考:
使用:
在开发工具软件中右键点击.fxml文件,选择在SceneBuilder打开。
上面说的文件都是在在同一个src文件夹下的某个包里,如果更改了图片资源文件夹、CSS、FXML文件位置,变成和src文件并列的情况,要修改地址,不然会报错。
而且,在FXML文件里的地址也要修改。
而且,即使IDEA上按住ctrl能点击跳转,也不意味着执行不出错。同样,不能跳转也不意味着是错的。
示例:(src、css、fxml位置并列)
Main.java 的 start方法里:
HostServices host = this.getHostServices();
String css = host.resolveURI(host.getDocumentBase(),“css/test1.css”);
String fxml = host.resolveURI(host.getDocumentBase(),“fxml/test1.fxml”);
FXMLLoader fxLoader = new FXMLLoader();
URL url_fxml = new URL(fxml);
fxLoader.setLocation(url_fxml);
AnchorPane root = fxLoader.load();
Scene scene = new Scene(root);
scene.getStylesheets().add(css);
primaryStage.show();
FXML文件某图片地址:
<Image url="@…/res/img/test1.png" />
其他参考:
【JavaFX的API文档:(当前最新是15,修改路径中的数字15可以更换版本)】
https://openjfx.cn/javadoc/15/
【FXML + CSS 开发登陆界面】 https://blog.csdn.net/LiHaoYang11/article/details/71106755
【JavaFX入门(五):使用CSS样式美化你的UI控件】 https://blog.csdn.net/theonegis/article/details/50189443
【JavaFX中引用CSS文件出错的解决方法】 https://blog.csdn.net/weixin_43898956/article/details/102912443?utm_medium=distribute.pc_relevant.none-task-blog-utm_term-10&spm=1001.2101.3001.4242
【JavaFX - 不多数不啰嗦,开始肯定要来个HelloWorld】 https://www.cnblogs.com/oscar1987121/p/9019644.html
【JavaFX之FXController详解 】https://blog.csdn.net/wingfourever/article/details/41349855