JavaFX\FXML\CSS的简单使用

博主纯业余,不是开发人员。
下面提到的四个文件:
Main.java FxmlController.java FXML文件(.fxml) test.css

src{
    
    
	fx{
    
    
		Main.java
		FxmlController.java	}
	fxml{
    
    
		FXML文件(test.fxml)	}
	css{
    
    
		test.css } }

0.MVC框架

Model View Controller
经典MVC模式中,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。(-百度百科:MVC框架)

引用b站视频的评论 @东篱雪清 回复 @电脑玩家Rain :链接


8、HTML------------->FXML :结构 (美术人员)


9、CSS--------------->CSS: 外观权 (美术人员)


10、JavaScript-------->Controller.java : 行为 (开发人员)

1.选择器

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选择器
https://blog.csdn.net/yye894817571/article/details/79416036

2.在FXML文件中指定控制器fx:controller

在FXML文件中在根结点添加指定控制器FxmlController.java语句:
fx:controller=“包名.FxmlController”
(只加载一次)
例如:

<AnchorPane fx:controller="fxControl.FxmlController" ... >

这样就能在FxmlController.java类中实现对组件的控制了。
但下面的标题6可以知道,也可以把事件响应写在Main.java里。

3.FxmlController.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标签,以便在加载时得以执行。

4.加载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

5.引入CSS文件

在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());

6.添加事件响应

比如给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");

7.关于带-fx前缀的CSS语句可以写在哪

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

8.SceneBuilder可视化图形编辑工具

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打开。

9.FXMLLoader加载文件路径的问题

上面说的文件都是在在同一个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

猜你喜欢

转载自blog.csdn.net/qq_43750882/article/details/110679531