JavaFX

143 阅读5分钟

前言

官方文档:Client Technologies: Java Platform, Standard Edition (Java SE) 8 Release 8

参考地址:2.1 了解JavaFX项目_哔哩哔哩_bilibili

代码地址:gitee.com/yuexiaying/…

p4 了解项目

主要结构: Main.java 启动类 Application 应用程序 Stage 舞台(窗口) Scene 场景 Node 节点 一个应用程序可以有多个舞台,舞台是固定不变的,上面可以布置不同的场景,场景上可以有多个节点,这些节点有一个root节点。

p5 添加标签Label

Node是所有节点的跟类,下面分

@Override
    public void start(Stage primaryStage) throws Exception{
    // 准备子节点
    Label label = new Label("这是一个标签");
    // 父节点
    BorderPane root = new BorderPane();
    root.setCenter(label);
    // 场景
    Scene scene = new Scene(root,400,400);
    // 舞台
    primaryStage.setScene(scene);
    primaryStage.show();
}

p6 添加按钮Button

本节主要是学习事件

  @Override
    public void start(Stage primaryStage) throws Exception{
        // 准备子节点
       Button button = new Button("我是按钮");
       button.setOnAction(new MyEventHandler());
        // 父节点
        BorderPane root = new BorderPane();
        root.setCenter(button);
        // 场景
        Scene scene = new Scene(root,400,400);
        // 舞台
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private static class MyEventHandler implements EventHandler<ActionEvent>{

        @Override
        public void handle(ActionEvent event) {

            System.out.println("被点击了");
        }
    }

p7 添加图片ImageView

注意添加图片的方式,及其支持的格式

   @Override
    public void start(Stage primaryStage) throws Exception{
        // 仅支持BMP GIF JPEG PNG四种格式
        // 本地文件
        //Image image = new Image("file:\\E:\\笔记\\source\\资源\\头像1.jpeg");
        // 网络文件
        Image image = new Image("https://cdn.nlark.com/yuque/0/2022/png/26420489/1667889759088-4bf78470-022f-4a4a-8dd6-85169994f04d.png");
        double width = image.getWidth();
        double height = image.getHeight();
        ImageView imageView = new ImageView();
        imageView.setImage(image);
        // 父节点
        BorderPane root = new BorderPane();
        root.setCenter(imageView);
        // 场景
        Scene scene = new Scene(root,width,height);
        // 舞台
        primaryStage.setScene(scene);
        primaryStage.setTitle("测试");
        primaryStage.show();
    }

p8 实战练习-相册

public class App extends Application {

    List<Image> imageViewList = new ArrayList<>();
    ImageView imageView = new ImageView();

    private Integer index = 0;

    @Override
    public void init() throws Exception {
        imageViewList.add(new Image("/p8/1.jpeg"));
        imageViewList.add(new Image("/p8/2.png"));
        imageViewList.add(new Image("/p8/3.jpg"));
        imageView.setPreserveRatio(true);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        BorderPane root = new BorderPane();
        Button button = new Button("下一个");
        button.setOnAction((event) -> {
            next(primaryStage);
        });
        root.setTop(button);
        root.setCenter(imageView);
        // 场景
        Scene scene = new Scene(root);
        // 舞台
        primaryStage.setScene(scene);
        primaryStage.setTitle("测试");
        next(primaryStage);
        primaryStage.show();

    }

    private void next(Stage stage) {
        Image image = imageViewList.get((index++) % 3);
        imageView.setImage(image);
        stage.setWidth(image.getWidth());
        stage.setHeight(image.getHeight()+100);
        System.out.println("被调用的第"+index +"次");
    }

    public static void main(String[] args) {
        launch(args);
    }
}

p10 边缘布局 BorderPane

支持五种位置

    @Override
    public void start(Stage primaryStage) throws Exception {
        BorderPane root = new BorderPane();
        root.setTop(new Label("顶部"));
        root.setLeft(new Label("左部"));
        root.setRight(new Label("右部"));
        root.setCenter(new Label("中部"));
        root.setBottom(new Label("底部"));
        Scene scene = new Scene(root,400,400);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

p11 水平布局

    @Override
    public void start(Stage primaryStage) throws Exception {
        HBox root = new HBox();
        root.setAlignment(Pos.CENTER);
        // 设置边缘距离
        root.setPadding(new Insets(10));
        TextField textField = new TextField();
        root.getChildren().addAll(textField,new Button("选择文件"),new Button("开始上传"));
        // 设置水平成长
        HBox.setHgrow(textField, Priority.ALWAYS);
        Scene scene = new Scene(root,400,400);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

p12 控件的尺寸

  @Override
    public void start(Stage primaryStage) throws Exception {
        HBox root = new HBox();
        Button b1 = new Button("中国");
        // 最小宽度
        b1.setMinWidth(100);
        // 最大宽度
        b1.setMaxWidth(400);
        // 最佳宽度
        b1.setPrefWidth(200);
        // 以上并不能决定控件大小,最终是由容器决定使用哪个
        Button b2 = new Button("中华人民共和国");
        // 默认宽度
        b2.setMaxHeight(Control.USE_COMPUTED_SIZE);
        // 最佳宽度
        b2.setMaxHeight(Control.USE_PREF_SIZE);
        root.getChildren().setAll(b1,b2);
        Scene scene = new Scene(root,400,400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

p13 控件的布局

    @Override
    public void start(Stage primaryStage) throws Exception {
        HBox root = new HBox();
        TextField textField = new TextField();
        root.getChildren().addAll(textField,new Button("选择文件"),new Button("开始上传"));
        // 对齐
        root.setAlignment(Pos.CENTER);
        // 填充 子控件和父级的边距
        root.setPadding(new Insets(10));
        // 间距
        root.setSpacing(10);
        // 优先增长 注意是静态方法
        HBox.setHgrow(textField,Priority.ALWAYS);
        Scene scene = new Scene(root,400,400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
  • 精确布局

p14 自定义容器

主要是实现Pane容器接口

 @Override
    public void start(Stage primaryStage) throws Exception {
        Image image = new Image("/p8/1.jpeg");
        ImageView imageView = new ImageView(image);
        ImageViewPane root = new ImageViewPane();
        root.getChildren().add(imageView);
        Scene scene = new Scene(root,400,400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private static class ImageViewPane extends Pane {
        @Override
        protected void layoutChildren() {
            if (getChildren().isEmpty()){
                return;
            }
            double width = getWidth();
            double height = getHeight();
            ImageView imageView = (ImageView) getChildren().get(0);
            imageView.resizeRelocate(0,0,width,height);
            imageView.setFitWidth(width);
            imageView.setFitHeight(height);
            imageView.setPreserveRatio(true);
        }
    }

p15 布局的嵌套

public class App extends Application {

    HBox hBox = new HBox();
    TextArea textArea = new TextArea();

    @Override
    public void init() throws Exception {
        TextField textField = new TextField();
        Button button = new Button("添加");
        button.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                textArea.appendText(textField.getText() +"\r\n");
                textField.clear();
            }
        });
        hBox.getChildren().addAll(textField, button);
        HBox.setHgrow(textField, Priority.ALWAYS);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        BorderPane root = new BorderPane();
        root.setTop(hBox);

        root.setCenter(textArea);
        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

p16 列表控件

多项数据的表示方法: ListView 列表 TreeView 树 TableView 表格 TreeTableView 多列列表

public class App extends Application {

    /**
     * 列表控件
     */
    ListView<Student> listView = new ListView<>();
    /**
     * 承载数据
     */
    ObservableList<Student> listData = FXCollections.observableArrayList();

    @Override
    public void init() throws Exception {

    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        listData.addAll(
                Student.builder().id(1).name("make").age(18).build(),
                Student.builder().id(1).name("ming").age(15).build(),
                Student.builder().id(1).name("jen").age(20).build()
        );
        listView.setItems(listData);
        listView.setCellFactory(new Callback<ListView<Student>, ListCell<Student>>() {
            @Override
            public ListCell<Student> call(ListView<Student> param) {
                return new MyCell();
            }
        });
        Button button = new Button("删除");
        button.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                if (!listData.isEmpty()){
                    listData.remove(0);
                }
            }
        });

        BorderPane root = new BorderPane();
        root.setTop(button);
        root.setCenter(listView);
        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * 自定义单元格类
     */
    private class MyCell extends ListCell<Student>{
        @Override
        protected void updateItem(Student item, boolean empty) {
            // 必须先调用父方法
            super.updateItem(item, empty);
            // 为了刷新列表,当为空时要执行以下操作
            if (empty || item == null){
                setText(null);
                setGraphic(null);
            }else {
                this.setText(item.getName());
            }
        }
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class Student {

        private Integer id;

        private String name;

        private Integer age;

    }


    public static void main(String[] args) {
        launch(args);
    }
}

p17 列表项的操作

增删改操作

public class App extends Application {

    /**
     * 列表控件
     */
    ListView<Student> listView = new ListView<>();
    /**
     * 承载数据
     */
    ObservableList<Student> listData = FXCollections.observableArrayList();

    HBox hBox = new HBox();

    @Override
    public void start(Stage primaryStage) throws Exception {
        TextField textField = new TextField();
        Button add = new Button("新增");
        add.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                String text = textField.getText();
                listData.add(Student.builder().name(text).build());
                textField.clear();
            }
        });
        Button del = new Button("删除");
        del.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                int selectedIndex = listView.getSelectionModel().getSelectedIndex();
                if (selectedIndex >= 0) {
                    listData.remove(selectedIndex);
                }
            }
        });
        Button update = new Button("修改");
        update.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                int selectedIndex = listView.getSelectionModel().getSelectedIndex();
                if (selectedIndex >= 0) {
                    String text = textField.getText();
                    listData.set(selectedIndex, Student.builder().name(text).build());
                    textField.clear();
                }
            }
        });
        hBox.getChildren().addAll(textField, add, del, update);
        HBox.setHgrow(textField, Priority.ALWAYS);
        listData.addAll(
                Student.builder().id(1).name("make").age(18).build(),
                Student.builder().id(1).name("ming").age(15).build(),
                Student.builder().id(1).name("jen").age(20).build()
        );
        listView.setItems(listData);
        listView.setCellFactory(new Callback<ListView<Student>, ListCell<Student>>() {
            @Override
            public ListCell<Student> call(ListView<Student> param) {
                return new MyCell();
            }
        });

        BorderPane root = new BorderPane();
        root.setTop(hBox);
        root.setCenter(listView);
        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * 自定义单元格类
     */
    private class MyCell extends ListCell<Student> {
        @Override
        protected void updateItem(Student item, boolean empty) {
            // 必须先调用父方法
            super.updateItem(item, empty);
            // 为了刷新列表,当为空时要执行以下操作
            if (empty || item == null) {
                setText(null);
                setGraphic(null);
            } else {
                this.setText(item.getName());
            }
        }
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class Student {

        private Integer id;

        private String name;

        private Integer age;

    }


    public static void main(String[] args) {
        launch(args);
    }
}

p18 多项选择

public class App extends Application {

    /**
     * 列表控件
     */
    ListView<Student> listView = new ListView<>();
    /**
     * 承载数据
     */
    ObservableList<Student> listData = FXCollections.observableArrayList();

    HBox hBox = new HBox();

    @Override
    public void start(Stage primaryStage) throws Exception {
        Button del = new Button("删除");
        del.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                listData.removeIf(e  -> e.isChecked());
            }
        });
        hBox.getChildren().addAll( del );
        listData.addAll(
                Student.builder().id(1).name("make").age(18).build(),
                Student.builder().id(1).name("ming").age(15).build(),
                Student.builder().id(1).name("jen").age(20).build()
        );
        listView.setItems(listData);
        listView.setCellFactory(new Callback<ListView<Student>, ListCell<Student>>() {
            @Override
            public ListCell<Student> call(ListView<Student> param) {
                return new MyCell();
            }
        });

        BorderPane root = new BorderPane();
        root.setTop(hBox);
        root.setCenter(listView);
        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * 自定义单元格类
     */
    private class MyCell extends ListCell<Student> {
        @Override
        protected void updateItem(Student item, boolean empty) {
            // 必须先调用父方法
            super.updateItem(item, empty);
            // 为了刷新列表,当为空时要执行以下操作
            if (empty || item == null) {
                setText(null);
                setGraphic(null);
            } else {
                CheckBox checkBox = new CheckBox();
                checkBox.setText(item.getName());
                checkBox.setSelected(item.isChecked());
                checkBox.selectedProperty().addListener(new MyChangeListener(item));
                this.setGraphic(checkBox);
            }
        }
    }

    private class MyChangeListener implements ChangeListener<Boolean>{

        private Student student;

        public MyChangeListener(Student student) {
            this.student = student;
        }

        @Override
        public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
            student.setChecked(newValue);
        }
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class Student {

        private Integer id;

        private String name;

        private Integer age;

        private boolean checked;

    }


    public static void main(String[] args) {
        launch(args);
    }
}