javaFx 工具开发

简介: javaFx 工具开发

提示框

package sample;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class demo1 extends Application{
    @Override
    public void start(Stage primaryStage) throws Exception {
        BorderPane root = new BorderPane();
        Button b1 = new Button("点我");
        b1.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                Alert alert = new Alert(Alert.AlertType.WARNING);
                alert.setHeaderText("弹窗");
                alert.setContentText("你好呀");
                alert.show();
            }
        });
        root.setCenter(b1);
        primaryStage.setTitle("鼠标操作");
        primaryStage.setScene(new Scene(root,500,50));
        primaryStage.show();
    }
}

登录案例

package sample;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.sql.*;
public class DemoAlert extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        // 文本框和密码框
        TextField user = new TextField();
        PasswordField pwd = new PasswordField();
        Button login = new Button("登录");
        // 创建布局
        BorderPane root = new BorderPane();
        VBox vBox = new VBox();
        vBox.getChildren().addAll(user,pwd,login);
        // 容器边距
        vBox.setSpacing(10);
        // 子父容器间距
        vBox.setPadding(new Insets(80));
        root.setCenter(vBox);
        login.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                String username = user.getText();
                String pass = pwd.getText();
                Alert warn = new Alert(Alert.AlertType.WARNING);
                // 获取当前数据库链接
                try {
                    Class.forName("com.mysql.jdbc.Driver");
                    Connection conn = DriverManager.getConnection("jdbc:mysql:///db4", "root", "root");
                    Statement stmt = conn.createStatement();
                    String sql = "select * from user where username ='"+username+"' and passwd = '"+pass+"' ";
                    System.out.println(sql);
                    ResultSet rs = stmt.executeQuery(sql);
                    if (rs.next()){
                        warn.setHeaderText("正在登录 请稍等");
                        warn.setContentText("登录成功");
                        warn.show();
                    } else {
                        warn.setHeaderText("正在查询 请稍等");
                        warn.setContentText("账号或密码错误,禁止登陆");
                        warn.show();
                    }
                    stmt.close();
                    conn.close();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        });
        primaryStage.setTitle("提示框");
        primaryStage.setScene(new Scene(root,400,300));
        primaryStage.show();
    }


640.png

仔细观察上面代码 sql哪里 没做过滤和判断 所以存在sql注入漏洞

如下

640.png

自定义对话框

Dialog:用于显示一个自定义的对话框
Dialog  -->  DialogPane --> (node + button)
Dialog 里要设置一个DialogPane
    Dialog.setDialogPane()
DialogPane里要设置根节点和按钮
    DialogPane.setContent()
    DialogPane.getButtonTypes().add()
package sample.Dailog;
public class Student {
    public int id = 0;
    public String name;
    public String phone;
    public Student(){}
    public Student(int id, String name, String phone) {
        this.id = id;
        this.name = name;
        this.phone = phone;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
}
package sample.Dailog;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.util.Callback;
import java.util.List;
public class StudentPane extends TreeTableView<Student> {
    // 根节点
    TreeItem rootItem = new TreeItem(new Student());
    // 设置3列
    TreeTableColumn<Student, Student> columns[] = new TreeTableColumn[3];
    public StudentPane(){
        // 初始化设置
        initColumns();
        // 扁平化显示 不显示根节点
        setRoot( rootItem);
        setShowRoot(false);
    }
    // 清空
    public  void clear(){
        rootItem.getChildren().clear();
    }
    // 添加
    public void  add(List<Student> datalist){
        for (Student fi : datalist) {
            TreeItem item = new TreeItem(fi);
            rootItem.getChildren().add(item);
        }
    }
    public  void add(Student data) {
        TreeItem item = new TreeItem(data);
        rootItem.getChildren().add(item);
    }
    @Override
    protected void layoutChildren() {
        super.layoutChildren();
        // 动态设置列宽
        double w = this.getWidth();
        double w0 = w * 0.3;
        double w1 = w * 0.4;
        double w2 = w - w0 - w1- 20;
        columns[0].setPrefWidth(w0);
        columns[1].setPrefWidth(w1);
        columns[2].setPrefWidth(w2);
    }
    private void initColumns() {
        // 添加多个列
        columns[0] = new TreeTableColumn("学号");
        columns[1] = new TreeTableColumn("姓名");
        columns[2] = new TreeTableColumn("手机号");
        this.getColumns().addAll(columns);
        // 设置 CellValueFactory (此段写法固定)
        Callback cellValueFactory = new Callback() {
            @Override
            public Object call(Object param) {
                TreeTableColumn.CellDataFeatures p = (TreeTableColumn.CellDataFeatures)param;
                return p.getValue().valueProperty();
            }
        };
        for(int i=0; i<columns.length; i++) {
            columns[i].setCellValueFactory(cellValueFactory);
        }
        // 设置CellFactory,定义每一列的单元格的显示
        // 这里使用了lambda表达式,否则写起来太长了!
        columns[0].setCellFactory((param)->{
            return new MyTreeTableCell("c0");
        });
        columns[1].setCellFactory((param)->{
            return new MyTreeTableCell("c1");
        });
        columns[2].setCellFactory((param)->{
            return new MyTreeTableCell("c2");
        });
    }
    // 单元格的显示
    static class MyTreeTableCell extends TreeTableCell<Student,Student> {
        String columnID;
        public MyTreeTableCell(String columnID) {
            this.columnID = columnID;
        }
        @Override
        protected void updateItem(Student item, boolean empty) {
            super.updateItem(item, empty);
            if (empty || item == null) {
                setText(null);
                setGraphic(null);
            } else {
                setGraphic(null);
                if(columnID.equals("c0")) {
                    setText(String.valueOf(item.id));
                }
                else if(columnID.equals("c1")) {
                    setText(String.valueOf(item.name));
                }
                else if(columnID.equals("c2")) {
                    setText(String.valueOf(item.phone));
                }
            }
        }
    }
}
package sample.Dailog;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
public class AddStudentDailog extends Dialog<Boolean> {
    // 添加信息面板
    TextField id = new TextField();
    TextField name = new TextField();
    TextField phone = new TextField();
    public AddStudentDailog(){
        VBox vBox = new VBox();
        id.setPromptText("学号");
        name.setPromptText("姓名");
        phone.setPromptText("手机号");
        // 添加到vbox
        vBox.getChildren().addAll(id,name,phone);
        // 创建dialogpane
        DialogPane dialogPane = new DialogPane();
        dialogPane.setContent(vBox);
        // 创建按钮
        Button ok = new Button("确定");
        vBox.getChildren().add(ok);
        ok.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 设置结果 关闭对话框
                setResult(true);
            }
        });
        // 创建对话框
        setDialogPane(dialogPane);
        setTitle("添加学生信息");
    }
    private boolean checkValid(){
        return true;
    }
    public Student getValue(){
        Student v = new Student();
        v.id = Integer.valueOf( id.getText() );
        v.name = name.getText();
        v. phone = phone.getText();
        return v;
    }
}
package sample.Dailog;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.util.Optional;
public class Main extends Application{
    public StudentPane studentPane;
    @Override
    public void start(Stage primaryStage) throws Exception {
        studentPane =new StudentPane();
        BorderPane root = new BorderPane();
        root.setCenter(studentPane);
        primaryStage.setScene(new Scene(root, 500, 400));
        primaryStage.setTitle("学生管理系统");
        primaryStage.show();
        Button add = new Button("添加");
        root.setTop(add);
        add.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                onAdd();
            }
        });
    }
    private void onAdd() {
        AddStudentDailog dlg = new AddStudentDailog();
        Optional<Boolean> result = dlg.showAndWait();
        if( result.isPresent() && result.get() == true) {
            Student s = dlg.getValue(); // getValue()是自己添加的方法
            studentPane.add(s);
        }
    }
}

先设计一个主程序 点击某个按钮 弹出一个小程序用来处理事件

这个就是自定义对话框

案例文本编辑器

package sample.FileChoose;
import java.io.*;
public class TextUtils {
    public static String read(File f, String charset) throws IOException {
        // 文件读取
        FileInputStream fis = new FileInputStream(f);
        int filesize = (int)f.length();
        byte[] bytes = new byte[filesize];
        fis.read(bytes);
        fis.close();
        return new String(bytes,charset);
    }
    // 文件写入
    public static void write(File f,String text,String charset) throws IOException {
        FileOutputStream fos = new FileOutputStream(f);
        fos.write(text.getBytes( charset));
        fos.close();
    }
}
package sample.FileChoose;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.web.HTMLEditor;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.io.File;
import java.io.IOException;
public class Main extends Application {
    // 创建编辑器
    HTMLEditor editor = new HTMLEditor();
    BorderPane root = new BorderPane();
    @Override
    public void start(Stage primaryStage) throws Exception {
        Button btnOpen = new Button("打开");
        Button btnSave = new Button("保存");
        HBox toolbar = new HBox();
        toolbar.getChildren().addAll(btnOpen, btnSave);
        toolbar.setPadding(new Insets(4));
        toolbar.setSpacing(4);
        root.setTop(toolbar);
        root.setCenter(editor);
        primaryStage.setTitle("文本编辑");
        primaryStage.setScene(new Scene(root, 640, 500));
        primaryStage.show();
        btnOpen.setOnAction(event -> {
            // 选择一个文件控制器
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("打开文件");
            fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Text Files", "*.txt"));
            // 可以从任意控件 Node 获取到 Window 对象,传给showOpenDialog()
            // Node.getScene().getWindow()
            File selectedFile = fileChooser.showOpenDialog(root.getScene().getWindow());
            if(selectedFile == null) {
                return; // 用户没有选中文件, 已经取消操作
            }
            try {
                String text = TextUtils.read(selectedFile,"GBK");
                editor.setHtmlText(text);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        btnSave.setOnAction(event -> {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("保存文件");
            fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Text Files", "*.txt"));
            // 选择文件
            File selectedFile = fileChooser.showSaveDialog(root.getScene().getWindow());
            if(selectedFile == null) {
                return; // 用户没有选中文件, 已经取消操作
            }
            try {
                // 获取编辑器内容
                String text = editor.getHtmlText();
                // 写内容
                TextUtils.write(selectedFile, text, "GBK");
            }catch(Exception e) {
                e.printStackTrace();
            }
        });
    }

菜单栏

package sample.FileChoose;
import java.io.*;
public class TextUtils {
    public static String read(File f, String charset) throws IOException {
        // 文件读取
        FileInputStream fis = new FileInputStream(f);
        int filesize = (int)f.length();
        byte[] bytes = new byte[filesize];
        fis.read(bytes);
        fis.close();
        return new String(bytes,charset);
    }
    // 文件写入
    public static void write(File f,String text,String charset) throws IOException {
        FileOutputStream fos = new FileOutputStream(f);
        fos.write(text.getBytes( charset));
        fos.close();
    }
}
package sample.FileChoose;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.HTMLEditor;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.io.File;
public class DemoMeme  extends Application {
    Stage primaryStage;// 主窗口
    MenuBar menuBar = new MenuBar();
    HTMLEditor editor = new HTMLEditor();
    @Override
    public void start(Stage primaryStage) {
        this.primaryStage = primaryStage;
            initMenu();
            BorderPane root = new BorderPane();
            root.setTop(menuBar);
            root.setCenter(editor);
            primaryStage.setScene(new Scene(root, 600, 400));
            primaryStage.show();
    }
    private void initMenu() {
        Menu menuFile = new Menu("文件");
        Menu menuHelp = new Menu("帮助");
        menuBar.getMenus().addAll(menuFile, menuHelp);
        MenuItem menuItemOpen = new MenuItem("打开");
        MenuItem menuItemSave = new MenuItem("保存");
        SeparatorMenuItem separator = new SeparatorMenuItem();
        MenuItem menuItemExit = new MenuItem("退出程序");
        menuFile.getItems().addAll(menuItemOpen, menuItemSave, separator, menuItemExit);
        // 简写为 lambda 表达式
        menuItemOpen.setOnAction((ActionEvent e)->{
            onOpen();
        });
        menuItemSave.setOnAction((ActionEvent e)->{
            onSave();
        });
        menuItemExit.setOnAction((ActionEvent e)->{
            Platform.exit();
        });
    }
    // 打开一个 *.txt 文件
    private void onOpen(){
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("打开文件");
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Text Files", "*.txt"));
        File selectedFile = fileChooser.showOpenDialog(primaryStage);
        if(selectedFile == null) return; // 用户没有选中文件, 已经取消操作
        try {
            String text = TextUtils.read(selectedFile, "GBK");
            editor.setHtmlText(text);
        }catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    // 保存到文件
    private void onSave()
{
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("保存文件");
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Text Files", "*.txt"));
        File selectedFile = fileChooser.showSaveDialog(primaryStage);
        if(selectedFile == null) return; // 用户没有选中文件, 已经取消操作
        try {
            String text = editor.getHtmlText();
            TextUtils.write(selectedFile, text, "GBK");
        }catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

上下文菜单

package memu;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
    // 创建ListView,指定数据项类型
    ListView<Student> listView = new ListView<Student>();
    // 数据源
    ObservableList<Student> listData = FXCollections.observableArrayList();
    // ListView的上下文菜单
    ContextMenu listContextMenu = new ContextMenu();
    @Override
    public void start(Stage primaryStage) {
            // 准备数据
            listData.add(new Student(1, "张三", true));
            listData.add(new Student(2, "李四", true));
            listData.add(new Student(3, "王五", false));
            // 设置数据源
            listView.setItems(listData);
            // 设置单元格生成器 (工厂)
            listView.setCellFactory(new Callback<ListView<Student>, ListCell<Student>>() {
                @Override
                public ListCell<Student> call(ListView<Student> param) {
                    return new MyListCell();
                }
            });
            initContextMenu();
            BorderPane root = new BorderPane();
            root.setCenter(listView);
            Scene scene = new Scene(root, 400, 400);
            primaryStage.setScene(scene);
            primaryStage.show();
    }
    // 初始化上下文菜单
    private void initContextMenu() {
        MenuItem menuItemRemove = new MenuItem("删除");
        menuItemRemove.setOnAction((ActionEvent e) -> {
            removeItem();
        });
        // 添加菜单项
        listContextMenu.getItems().add(menuItemRemove);
        // 给ListView设置上下文菜单
        listView.setContextMenu(listContextMenu);
    }
    // 删除当前选中的项
    private void removeItem() {
        int index = listView.getSelectionModel().getSelectedIndex();
        if(index >= 0) {
            listData.remove(index);
        }
    }
    // 负责单元格Cell的显示
    static class MyListCell extends ListCell<Student> {
        @Override
        public void updateItem(Student item, boolean empty) {
            // FX框架要求必须先调用 super.updateItem()
            super.updateItem(item, empty);
            // 自己的代码
            if (item == null) {
                this.setText(""); // 清空显示
            } else {
                this.setText(item.name); // 显示该项的值
            }
        }
    }
    // 数据项
    static class Student {
        public int id;
        public String name;
        public boolean sex;
        public Student() {}
        public Student(int id, String name, boolean sex){
            this.id = id;
            this.name = name;
            this.sex = sex;
        }
    }
}


案例 学生管理系统

package memu;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogEvent;
import javafx.scene.control.DialogPane;
import javafx.scene.control.TextField;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
// Dialog<Boolean> : showAndWait() 将返回Boolean值
public class AddStudentDialog extends Dialog<Boolean> {
  TextField id = new TextField();
  TextField name = new TextField();
  TextField phone = new TextField();
  public AddStudentDialog() {
    // 对话框内容
    VBox content = new VBox();
    id.setPromptText("学号");
    name.setPromptText("姓名");
    phone.setPromptText("手机号");
    content.setSpacing(10);
    content.getChildren().addAll(id, name, phone);
    // Dialog -> DialogPane -> Root Node
    DialogPane dialogPane = new DialogPane();    
    dialogPane.setContent(content);
    // 添加按钮
    ButtonType ok = new ButtonType("确定", ButtonData.OK_DONE);
    dialogPane.getButtonTypes().add(ok);
    ButtonType cancel = new ButtonType("取消", ButtonData.CANCEL_CLOSE);
    dialogPane.getButtonTypes().add(cancel);
    this.setResultConverter(new Callback<ButtonType,Boolean>(){
      @Override
      public Boolean call(ButtonType b) {
        if(b.getButtonData() == ButtonData.OK_DONE)
          return true;
        return false;
      }      
    });
    // 创建对话框
    this.setDialogPane(dialogPane);
    this.setTitle("添加学生信息");
  }
  private boolean checkValid() {
    int n = 0;
    try {
      n = Integer.valueOf( id.getText().trim() );      
    }catch(Exception e) {
    }
    if(n <=0) {
      Alert warning = new Alert(AlertType.WARNING);
      warning.setHeaderText(null);
      warning.setContentText("学号输入错误!请输入整数!");
      warning.showAndWait();
      return false;
    }
    return true;
  }
  // 获取用户输入的值
  public Student getValue() {
    try {
      Student v = new Student();
        v.id = Integer.valueOf( id.getText() );
        v.name = name.getText();
        v. phone = phone.getText();
        return v;
    }catch(Exception e) {
      e.printStackTrace();
      return null;
    }
  }
}
package memu;
public class Student {
  public int id = 0;
  public String name;
  public String phone;
  public Student(){}
  public Student(int id, String name, String phone) {
    this.id = id;
    this.name = name;
    this.phone = phone;
  }
  public int getId()
{
    return id;
  }
  public void setId(int id)
{
    this.id = id;
  }
  public String getName()
{
    return name;
  }
  public void setName(String name)
{
    this.name = name;
  }
  public String getPhone()
{
    return phone;
  }
  public void setPhone(String phone)
{
    this.phone = phone;
  }
}
package memu;
import java.util.ArrayList;
import java.util.List;
import javafx.collections.ObservableList;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.TreeTableColumn.CellDataFeatures;
import javafx.util.Callback;
public class StudentPane extends TreeTableView<Student> {
  // 根节点
  TreeItem rootItem = new TreeItem(new Student());
  // 列
  TreeTableColumn<Student, Student> columns[] = new TreeTableColumn[3];
  public StudentPane() {
    // 初始化列的设置
    initColumns();
    // 扁平化显示, 不显示根节点, 但必须要有根节点
    this.setRoot(rootItem);
    this.setShowRoot(false);
  }
  // 清空
  public void clear()
{
    rootItem.getChildren().clear();
  }
  // 添加
  public void add(List<Student> datalist) {
    for (Student fi : datalist) {
      TreeItem item = new TreeItem(fi);
      rootItem.getChildren().add(item);
    }
  }
  public void add(Student data) {
    TreeItem item = new TreeItem(data);
    rootItem.getChildren().add(item);
  }
  public void remove(int index)
{
    rootItem.getChildren().remove(index);
  }
  public List<Student> get()
{
    ArrayList<Student> results = new ArrayList<Student>();
    ObservableList<TreeItem<Student>> items = rootItem.getChildren();
    for (int i = 0; i < items.size(); i++) {
      TreeItem<Student> item = items.get(i);
      Student value = item.getValue();
      results.add(value);
    }
    return results;
  }
  @Override
  protected void layoutChildren()
{
    super.layoutChildren();
    // 动态设置列宽
    double w = this.getWidth();
    double w0 = w * 0.3;
    double w1 = w * 0.4;
    double w2 = w - w0 - w1 - 20;
    columns[0].setPrefWidth(w0);
    columns[1].setPrefWidth(w1);
    columns[2].setPrefWidth(w2);
  }
  private void initColumns() {
    // 添加多个列
    columns[0] = new TreeTableColumn("学号");
    columns[1] = new TreeTableColumn("姓名");
    columns[2] = new TreeTableColumn("手机号");
    this.getColumns().addAll(columns);
    // 重写layoutChildren() 动态调整个列的列宽
    // 设置 CellValueFactory (此段写法固定)
    Callback cellValueFactory = new Callback() {
      @Override
      public Object call(Object param) {
        CellDataFeatures p = (CellDataFeatures) param;
        return p.getValue().valueProperty();
      }
    };
    for (int i = 0; i < columns.length; i++) {
      columns[i].setCellValueFactory(cellValueFactory);
    }
    // 设置CellFactory,定义每一列的单元格的显示
    // 这里使用了lambda表达式,否则写起来太长了!
    columns[0].setCellFactory((param) -> {
      return new MyTreeTableCell("c0");
    });
    columns[1].setCellFactory((param) -> {
      return new MyTreeTableCell("c1");
    });
    columns[2].setCellFactory((param) -> {
      return new MyTreeTableCell("c2");
    });
  }
  // 单元格的显示
  static class MyTreeTableCell extends TreeTableCell<Student, Student> {
    String columnID;
    public MyTreeTableCell(String columnID)
{
      this.columnID = columnID;
    }
    @Override
    protected void updateItem(Student item, boolean empty) {
      super.updateItem(item, empty);
      if (empty || item == null) {
        setText(null);
        setGraphic(null);
      } else {
        setGraphic(null);
        if (columnID.equals("c0")) {
          setText(String.valueOf(item.id));
        } else if (columnID.equals("c1")) {
          setText(String.valueOf(item.name));
        } else if (columnID.equals("c2")) {
          setText(String.valueOf(item.phone));
        }
      }
    }
  }
}
package memu;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class TextUtils {
    public static String read(File f, String charset) throws IOException {
        // 文件读取
        FileInputStream fis = new FileInputStream(f);
        int filesize = (int)f.length();
        byte[] bytes = new byte[filesize];
        fis.read(bytes);
        fis.close();
        return new String(bytes,charset);
    }
    // 文件写入
    public static void write(File f,String text,String charset) throws IOException {
        FileOutputStream fos = new FileOutputStream(f);
        fos.write(text.getBytes( charset));
        fos.close();
    }
}
package memu;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.json.JSONArray;
import org.json.JSONObject;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.stage.FileChooser.ExtensionFilter;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.layout.BorderPane;
public class Main extends Application {
  Stage primaryStage;// 主窗口
  MenuBar menuBar = new MenuBar();
  StudentPane studentPane = new StudentPane();
  // 上下文菜单
  ContextMenu contextMenu = new ContextMenu();
  @Override
  public void start(Stage primaryStage) {
      initMenuBar(); // 初始化菜单栏
      initContextMenu(); // 初始化右键菜单
      BorderPane root = new BorderPane();
      root.setTop(menuBar);
      root.setCenter(studentPane);
      primaryStage.setScene(new Scene(root, 400, 400));
      primaryStage.show();
  }
  private void initMenuBar() {
        Menu menuFile = new Menu("文件");
        Menu menuHelp = new Menu("帮助");
        menuBar.getMenus().addAll(menuFile, menuHelp);
        MenuItem menuItemOpen = new MenuItem("打开");
        MenuItem menuItemSave = new MenuItem("保存");
        SeparatorMenuItem separator = new SeparatorMenuItem();
        MenuItem menuItemExit = new MenuItem("退出程序");
        menuFile.getItems().addAll(menuItemOpen, menuItemSave, separator, menuItemExit);
    // 简写为 lambda 表达式
        menuItemOpen.setOnAction((ActionEvent e)->{
      try {
        onOpen();
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    });
        menuItemSave.setOnAction((ActionEvent e)->{
      try {
        onSave();
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    });
        menuItemExit.setOnAction((ActionEvent e)->{
      Platform.exit();
    });
  }
  // 打开一个文件
  private void onOpen() throws IOException {
    FileChooser fileChooser = new FileChooser();
    fileChooser.setTitle("打开文件");
    fileChooser.getExtensionFilters().add(new ExtensionFilter("学生数据文件", "*.data"));
    File selectedFile = fileChooser.showOpenDialog(primaryStage);
    if(selectedFile == null) return; // 用户没有选中文件, 已经取消操作
      String text = TextUtils.read(selectedFile, "GBK");
      JSONArray jarray = new JSONArray(text);
      List<Student> sss = new ArrayList<Student>();
      for(int i = 0;i<jarray.length(); i++)
      {
        JSONObject jobj = jarray.getJSONObject(i);
        Student s = new Student();
        s.id = jobj.getInt("id");
        s.name = jobj.getString("name");
        s.phone = jobj.getString("phone");
        sss.add( s );
      }
      studentPane.clear();
      studentPane.add(sss);
  }
  // 保存到文件
  private void onSave() throws IOException {
    FileChooser fileChooser = new FileChooser();
    fileChooser.setTitle("保存文件");
    fileChooser.getExtensionFilters().add(new ExtensionFilter("学生数据文件", "*.data"));
    File selectedFile = fileChooser.showSaveDialog(primaryStage);
    if(selectedFile == null) return; // 用户没有选中文件, 已经取消操作
      List<Student> sss = studentPane.get();
      JSONArray jarray = new JSONArray(sss);
      String text = jarray.toString(2);
      TextUtils.write(selectedFile, text, "GBK");
  }
  // 初始化上下文菜单
  private void initContextMenu() {
    MenuItem menuItemAdd = new MenuItem("添加");
    menuItemAdd.setOnAction((ActionEvent e) -> {
      addItem();
    });
    MenuItem menuItemRemove = new MenuItem("删除");
    menuItemRemove.setOnAction((ActionEvent e) -> {
      removeItem();
    });
    // 添加菜单项
    contextMenu.getItems().addAll(menuItemAdd, menuItemRemove);
    // 给ListView设置上下文菜单
    studentPane.setContextMenu(contextMenu);
  }
  // 点菜单项 '添加'
  private void addItem() {
    AddStudentDialog dlg = new AddStudentDialog();
    Optional<Boolean> result = dlg.showAndWait();
    if( result.isPresent() && result.get() == true) {
      Student s = dlg.getValue(); // getValue()是自己添加的方法
      studentPane.add(s );
    }
  }
  // 点菜单项 '删除'
  private void removeItem() {
    int index = studentPane.getSelectionModel().getSelectedIndex();
    if(index >= 0){
      studentPane.remove(index);
    }
  }
}



相关文章
|
2月前
|
前端开发 Java API
使用JavaFX进行跨平台桌面应用开发的技术指南
【5月更文挑战第29天】JavaFX是Oracle的开源GUI工具包,用于跨平台桌面应用开发。它提供丰富的API、UI控件、图形动画支持及媒体集成。通过设置JDK和JavaFX SDK环境,使用IDE创建项目,编写并运行JavaFX代码,开发者可构建富客户端应用。遵循MVC模式、使用FXML和CSS,以及测试兼容性,能提升应用质量和用户体验。
|
2月前
|
前端开发 JavaScript Java
JavaFX学习笔记(三) 架构与图形系统
JavaFX学习笔记(三) 架构与图形系统
QGS
|
2月前
|
容器
JavaFX场景入门(下)
JavaFX场景入门
QGS
36 0
QGS
|
2月前
|
Android开发
JavaFX场景入门(上)
JavaFX场景入门
QGS
56 0
|
安全 Java
javaFx 安全开发 三
javaFx 安全开发
|
IDE Java 开发工具
QGS
JAVAFX+SceneBuilder基础
记JAVAFX+SceneBuilder基础
QGS
103 0
JAVAFX+SceneBuilder基础
|
XML 设计模式 前端开发
JavaFx-桌面应用开发利器(三)FXML和Scene Builder
本文首先简单介绍了Fxml和Scene Builder的基本知识,同时以eclipse为例,通过代码的形式说明如何进行Fxml的开发,最后使用SceneBuilder进行​应用快速开发。同时说明在使用eclipse中可能会遇到的一些问题以及解决办法​。
746 0
JavaFx-桌面应用开发利器(三)FXML和Scene Builder
|
前端开发 数据可视化 IDE
JavaFx-桌面应用开发利器(二)基础架构篇
本文简单介绍javafx的架构,并通过一个实际的例子说明如何构建一个​简单的java应用。
495 0
JavaFx-桌面应用开发利器(二)基础架构篇