1. fxml文件基本编写方式,加载和根据id获取组件
src/main/resources/main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:controller="top.onefine.control.MainCtl"
prefHeight="400.0" prefWidth="600.0">
<children>
<Button text="按钮1" prefWidth="100" prefHeight="36" id="b1">
<AnchorPane.leftAnchor>100</AnchorPane.leftAnchor>
<AnchorPane.topAnchor>100</AnchorPane.topAnchor>
</Button>
</children>
</AnchorPane>
src/main/java/top/onefine/Main.java:
package top.onefine;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import java.io.File;
import java.io.FileInputStream;
import java.net.URL;
public class Main extends Application {
public static void main(String[] args) {
Application.launch(args);
// System.out.println(System.getProperty("java.version"));
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.getIcons().add(new Image("Icon.png")); // 设置图标
primaryStage.setTitle("条码识别");
primaryStage.setWidth(1680);
primaryStage.setHeight(1050);
FXMLLoader fx = new FXMLLoader();
// 加载类路径下的资源
URL resource = getClass().getClassLoader().getResource("main.fxml");
if (resource == null)
throw new RuntimeException("资源文件找不到");
// 加载方式一
// AnchorPane root = (AnchorPane) fx.load(new FileInputStream(resource.getPath()));
// 加载方式二
fx.setLocation(resource);
AnchorPane root = (AnchorPane) fx.load();
// 获取fxml中的组件
Button b1 = (Button) root.lookup("#b1");// b1为要获取组件Button的id名
b1.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("点击了" + ((Button) event.getSource()).getText());
}
});
Scene scene = new Scene(root); // 场景
primaryStage.setScene(scene);
primaryStage.show();
}
}
2. 控制器controller
src/main/resources/main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:controller="top.onefine.control.MainCtl"
prefHeight="400.0" prefWidth="600.0">
<children>
<Label fx:id="label" id="label" text="标签"/>
<Button fx:id="b1" id="b1" text="按钮1" prefWidth="100" prefHeight="36" onAction="#b1_action">
<AnchorPane.leftAnchor>100</AnchorPane.leftAnchor>
<AnchorPane.topAnchor>100</AnchorPane.topAnchor>
</Button>
</children>
</AnchorPane>
src/main/java/top/onefine/control/MainCtl.java:
package top.onefine.control;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
/**
* 控制器
*/
public class MainCtl {
public MainCtl() {
System.out.println("加载了类");
}
@FXML // 获取main.fxml中id为b1的引用
private Button b1;
@FXML
private Label label;
public Button getB1() {
return b1;
}
public void setB1(Button b1) {
this.b1 = b1;
}
public Label getLabel() {
return label;
}
public void setLabel(Label label) {
this.label = label;
}
@FXML // 处理事件,对应:onAction="#b1_action"
private void b1_action() {
System.out.println("点击了");
}
@FXML // 初始化方法
private void initialize() {
System.out.println("初始化了");
// System.out.println(label.getText());
// System.out.println(b1.getText());
}
}
src/main/java/top/onefine/client/Main.java:
package top.onefine.client;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import top.onefine.control.MainCtl;
import java.net.URL;
public class Main extends Application {
public static void main(String[] args) {
Application.launch(args);
// System.out.println(System.getProperty("java.version"));
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.getIcons().add(new Image("Icon.png")); // 设置图标
primaryStage.setTitle("条码识别");
primaryStage.setWidth(1680);
primaryStage.setHeight(1050);
FXMLLoader fx = new FXMLLoader();
// 加载类路径下的资源
URL resource = getClass().getClassLoader().getResource("main.fxml");
if (resource == null)
throw new RuntimeException("资源文件找不到");
// 加载方式一
// AnchorPane root = (AnchorPane) fx.load(new FileInputStream(resource.getPath()));
// 加载方式二
fx.setLocation(resource);
AnchorPane root = (AnchorPane) fx.load();
// 获取fxml中的组件
// Button b1 = (Button) root.lookup("#b1");// b1为要获取组件Button的id名
// b1.setOnAction(new EventHandler<ActionEvent>() {
// @Override
// public void handle(ActionEvent event) {
// System.out.println("点击了" + ((Button) event.getSource()).getText());
// }
// });
// 获取控制器,对控制器中的按钮进行监听绑定
// 注意:这会使得控制器中b1按钮的监听失效
MainCtl controller = (MainCtl) fx.getController();
controller.getB1().setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("又点击了!");
}
});
Scene scene = new Scene(root); // 场景
primaryStage.setScene(scene);
primaryStage.show();
}
}
2. 设置图片,布局,列表数据,切换布局
src/main/resources/main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.image.Image?>
<?import javafx.collections.FXCollections?>
<AnchorPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:controller="top.onefine.control.MainCtl"
prefHeight="400.0" prefWidth="600.0">
<children>
<Label fx:id="label" id="label" text="标签"
AnchorPane.topAnchor="100" AnchorPane.leftAnchor="100"/>
<Button fx:id="b1" id="b1" prefWidth="100" prefHeight="36"
AnchorPane.topAnchor="100" AnchorPane.leftAnchor="200">
<String fx:value="按钮1" />
</Button>
<!-- 加载图片 -->
<ImageView AnchorPane.topAnchor="300" AnchorPane.leftAnchor="100"
fitHeight="600" preserveRatio="true"> <!-- preserveRatio保持图片宽高比例 -->
<Image url="@demoPhoto.png" />
</ImageView>
<!-- 布局 -->
<BorderPane style="-fx-background-color: #FFFF55" prefWidth="600" prefHeight="200" AnchorPane.leftAnchor="300">
<left>
<ListView fx:id="list" prefWidth="200" prefHeight="200">
<!--
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="data1" />
<String fx:value="data2" />
<String fx:value="data3" />
<String fx:value="data4" />
</FXCollections>
</items>
-->
</ListView>
</left>
<right>
<ComboBox>
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="data1" />
<String fx:value="data2" />
<String fx:value="data3" />
<String fx:value="data4" />
</FXCollections>
</items>
</ComboBox>
</right>
</BorderPane>
</children>
</AnchorPane>
src/main/resources/other.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="top.onefine.control.Other"
prefHeight="400.0" prefWidth="600.0">
<Button text="哈哈哈回不去了" onAction="#button_action"/>
</AnchorPane>
src/main/java/top/onefine/control/MainCtl.java:
package top.onefine.control;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
/**
* 控制器
*/
public class MainCtl {
public MainCtl() {
System.out.println("加载了类");
}
@FXML // 获取main.fxml中id为b1的引用
private Button b1;
@FXML
private Label label;
@FXML
private ListView<String> list;
public Button getB1() {
return b1;
}
public void setB1(Button b1) {
this.b1 = b1;
}
public Label getLabel() {
return label;
}
public void setLabel(Label label) {
this.label = label;
}
public ListView<String> getList() {
return list;
}
public void setList(ListView<String> list) {
this.list = list;
}
@FXML // 初始化方法
private void initialize() {
ObservableList<String> objlist = FXCollections.observableArrayList();
objlist.add("data1");
objlist.add("data2");
objlist.add("data3");
objlist.add("data4");
objlist.add("data5");
list.setItems(objlist);
list.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
System.out.println("选中了:" + newValue);
}
});
}
}
src/main/java/top/onefine/control/Other.java:
package top.onefine.control;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import java.io.IOException;
public class Other {
public Other() {
}
@FXML
private void button_action() {
FXMLLoader f1 = new FXMLLoader();
f1.setLocation(getClass().getClassLoader().getResource("other.fxml"));
try {
AnchorPane an = (AnchorPane) f1.load();
Stage stage = new Stage();
Scene scene = new Scene(an);
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
Platform.exit();
}
}
@FXML
private void initialize() {
}
}
src/main/java/top/onefine/client/Main.java:
package top.onefine.client;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import top.onefine.control.MainCtl;
import java.io.IOException;
import java.net.URL;
public class Main extends Application {
public static void main(String[] args) {
Application.launch(args);
// System.out.println(System.getProperty("java.version"));
}
@Override
public void start(Stage primaryStage) {
primaryStage.getIcons().add(new Image("Icon.png")); // 设置图标
primaryStage.setTitle("条码识别");
// primaryStage.setWidth(1680);
// primaryStage.setHeight(1050);
primaryStage.setWidth(1600);
primaryStage.setHeight(900);
FXMLLoader fx = new FXMLLoader();
// 加载类路径下的资源
URL resource = getClass().getClassLoader().getResource("main.fxml");
if (resource == null)
throw new RuntimeException("资源文件找不到");
fx.setLocation(resource);
AnchorPane root = null;
try {
root = (AnchorPane) fx.load();
} catch (IOException e) {
e.printStackTrace();
Platform.exit();
return;
}
Scene scene = new Scene(root); // 场景
primaryStage.setScene(scene);
// 点击button时切换场景
MainCtl controller = (MainCtl) fx.getController(); // 获取控制器——Main对应的控制类
controller.getB1().setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
FXMLLoader fx2 = new FXMLLoader();
fx2.setLocation(getClass().getClassLoader().getResource("other.fxml"));
try {
AnchorPane ohter = (AnchorPane) fx2.load();
scene.setRoot(ohter); // 切换场景
} catch (IOException e) {
e.printStackTrace();
Platform.exit();
}
}
});
primaryStage.show();
}
}
3. 利用Builder和BuilderFactory接口,读取自定义FXML标签
3.1 Builder和BuilderFactory接口1
src/main/java/top/onefine/demo/javafx/Person.java:
package top.onefine.demo.javafx;
public class Person {
private String name;
private Integer age;
// 默认使用无参构造函数初始化对象
// public Person() {
// }
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
src/main/java/top/onefine/demo/javafx/PersonBuilder.java:
package top.onefine.demo.javafx;
import javafx.util.Builder;
public class PersonBuilder implements Builder<Person> {
@Override
public Person build() {
return new Person(name, age);
}
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
src/main/java/top/onefine/demo/javafx/PersonBuilderFactory.java:
package top.onefine.demo.javafx;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.util.Builder;
import javafx.util.BuilderFactory;
public class PersonBuilderFactory implements BuilderFactory {
private final JavaFXBuilderFactory bf = new JavaFXBuilderFactory();
@Override
public Builder<?> getBuilder(Class<?> type) {
if (type == Person.class) {
System.out.println("xxxxxx");
// 特别奇怪,这里既不能用内部类又不能直接返回匿名实现类...
/**
return new Builder<Person>() {
@Override
public Person build() {
return new Person(name, age);
}
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
};**/
return new PersonBuilder();
}
System.out.println("hhhhhhh"); // 这句也奇怪,也是执行不到...
return bf.getBuilder(type);
}
}
src/main/resources/main_demo.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import top.onefine.demo.javafx.Person?>
<!--<AnchorPane xmlns="http://javafx.com/javafx"-->
<!-- xmlns:fx="http://javafx.com/fxml"-->
<!-- fx:controller="top.onefine.demo.javafx.MainCtrDemo"-->
<!-- prefHeight="400.0" prefWidth="600.0">-->
<!--</AnchorPane>-->
<Person name="onefine" age="18">
</Person>
src/main/java/top/onefine/demo/javafx/TestDemo.java:
package top.onefine.demo.javafx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import java.net.URL;
public class TestDemo extends Application {
public static void main(String[] args) {
Application.launch(args);
// System.out.println(System.getProperty("java.version"));
}
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader fx = new FXMLLoader();
// 加载类路径下的资源
URL resource = getClass().getClassLoader().getResource("main_demo.fxml");
if (resource == null)
throw new RuntimeException("资源文件找不到");
fx.setLocation(resource);
// 使用带参数的构造方法,替换默认的无参构造方法
fx.setBuilderFactory(new PersonBuilderFactory());
Person person = (Person) fx.load();
System.out.println(person.getName());
// Scene scene = new Scene(root);
// primaryStage.setScene(scene);
primaryStage.setTitle("demo");
primaryStage.show();
}
}
3.2 Builder和BuilderFactory接口2
src/main/java/top/onefine/demo/javafx/PersonBuilderMap.java:
package top.onefine.demo.javafx;
import javafx.util.Builder;
import java.util.HashMap;
public class PersonBuilderMap extends HashMap<String, Object> implements Builder<Person> {
private String name;
private Integer age;
@Override
public Object put(String key, Object value) {
// return super.put(key, value);
if ("name".equals(key))
this.name = String.valueOf(value);
else if ("age".equals(key))
this.age = Integer.valueOf(String.valueOf(value));
return null;
}
@Override
public Person build() {
return new Person(name, age);
}
}
src/main/java/top/onefine/demo/javafx/PersonBuilderFactoryMap.java:
package top.onefine.demo.javafx;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.util.Builder;
import javafx.util.BuilderFactory;
public class PersonBuilderFactoryMap implements BuilderFactory {
private final JavaFXBuilderFactory bf = new JavaFXBuilderFactory();
@Override
public Builder<?> getBuilder(Class<?> type) {
if (type == Person.class) {
System.out.println("xxxxxx");
return new PersonBuilderMap();
}
System.out.println("hhhhhhh"); // 这句也奇怪,也是执行不到...
return bf.getBuilder(type);
}
}
src/main/resources/main_demo.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import top.onefine.demo.javafx.Person?>
<!--<AnchorPane xmlns="http://javafx.com/javafx"-->
<!-- xmlns:fx="http://javafx.com/fxml"-->
<!-- fx:controller="top.onefine.demo.javafx.MainCtrDemo"-->
<!-- prefHeight="400.0" prefWidth="600.0">-->
<!--</AnchorPane>-->
<ArrayList>
<Person name="one" age="18" />
<Person name="fine" age="17" />
<Person name="one fine" age="16" />
</ArrayList>
src/main/java/top/onefine/demo/javafx/TestDemo.java:
package top.onefine.demo.javafx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ArrayList;
public class TestDemo extends Application {
public static void main(String[] args) {
Application.launch(args);
// System.out.println(System.getProperty("java.version"));
}
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader fx = new FXMLLoader();
// 加载类路径下的资源
URL resource = getClass().getClassLoader().getResource("main_demo.fxml");
if (resource == null)
throw new RuntimeException("资源文件找不到");
fx.setLocation(resource);
// 使用带参数的构造方法,替换默认的无参构造方法
// fx.setBuilderFactory(new PersonBuilderFactory());
fx.setBuilderFactory(new PersonBuilderFactoryMap());
ArrayList<Person> personList = (ArrayList<Person>) fx.load();
System.out.println(personList.size());
// Scene scene = new Scene(root);
// primaryStage.setScene(scene);
primaryStage.setTitle("demo");
primaryStage.show();
}
}
执行结果:
hhhhhhh
xxxxxx
xxxxxx
xxxxxx
3
4. fxml文件补充
src/main/resources/main_demo.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.geometry.Pos?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="top.onefine.demo.javafx.MainCtrDemo"
prefHeight="400.0" prefWidth="600.0">
<fx:define>
<ToggleGroup fx:id="group" />
<Insets fx:id="margin" top="0" left="0" bottom="10" right="10" />
<Button fx:id="bu" text="button" prefWidth="120"/>
</fx:define>
<HBox prefWidth="400" prefHeight="200" spacing="10" alignment="CENTER">
<!-- 设置对齐方式 -->
<!-- <alignment>-->
<!-- <Pos fx:constant="CENTER" />-->
<!-- </alignment>-->
<RadioButton text="A" toggleGroup="$group" />
<RadioButton text="B" toggleGroup="$group" />
<RadioButton text="C" toggleGroup="$group" />
<Button text="hello" HBox.margin="$margin" prefWidth="120"/>
<Button text="world" HBox.margin="$margin" prefWidth="120" />
<fx:reference source="bu" /> <!-- 引用 ,注意只能引用一次-->
<!-- 导入其他fxml -->
<fx:include source="other_demo.fxml" />
</HBox>
<!-- 使用b1的属性 -->
<Button AnchorPane.topAnchor="300.0" fx:id="b1" text="button1" prefWidth="100" />
<Button AnchorPane.topAnchor="400.0" text="button2" prefWidth="${b1.prefWidth}" />
</AnchorPane>
src/main/resources/other_demo.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<!--<AnchorPane xmlns="http://javafx.com/javafx"-->
<!-- xmlns:fx="http://javafx.com/fxml"-->
<!-- fx:controller="OtherDemo"-->
<!-- prefHeight="400.0" prefWidth="600.0">-->
<!--</AnchorPane>-->
<Button text="otherButton"/>
src/main/java/top/onefine/demo/javafx/TestDemo.java:
package top.onefine.demo.javafx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import java.net.URL;
public class TestDemo extends Application {
public static void main(String[] args) {
Application.launch(args);
// System.out.println(System.getProperty("java.version"));
}
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader fx = new FXMLLoader();
// 加载类路径下的资源
URL resource = getClass().getClassLoader().getResource("main_demo.fxml");
if (resource == null)
throw new RuntimeException("资源文件找不到");
fx.setLocation(resource);
AnchorPane anchorPane = (AnchorPane) fx.load();
Scene scene = new Scene(anchorPane);
primaryStage.setScene(scene);
primaryStage.setTitle("demo");
primaryStage.setHeight(500);
primaryStage.setWidth(800);
primaryStage.show();
}
}