博主纯业余,不是开发人员。 下面提到的四个文件: 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的实现代码分离,从而使同一个程序可以使用不同的表现形式。(-百度百科:MVC框架)
引用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文件的语法错误等只有在调用到相关代码才能被报出来。
参考: 【JavaFX——CSS选择器 】
在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中的代码:
@FXML
private 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语法,自行搜索或参考JavaFX 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>参考【JavaFX CSS官方文档:JavaFX CSS Reference Guide:】 https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html 参考【Bilibili视频:JavaFX视频教程第119课,CSS的简单使用】 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参考:【JavaFx教程】第一部分:Scene Builder (2)IDEA参考:IDEA中使用scene builder 使用: 在开发工具软件中右键点击.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 开发登陆界面】
【JavaFX入门(五):使用CSS样式美化你的UI控件】
【JavaFX中引用CSS文件出错的解决方法】
【JavaFX - 不多数不啰嗦,开始肯定要来个HelloWorld】
【JavaFX之FXController详解 】
















