javaFx 安全开发 三

admin 2025年6月26日01:57:39评论2 views字数 17256阅读57分31秒阅读模式

今天这个文章 比上两篇就稍微难了点,emm 代码也比之前多了点。

列表

ListView   列表TreeView   树列表TableView  表格TreeTableView  多列多表

代码分析:

首先就是使用了 hbox 作为top部分的 文件行 和 三个按钮

每个按钮对应一个监听器 监听不同的处理动作

整体使用了布局嵌套 使用了student泛型 把内容显示在列表里

列表里需要自定义单元格 最终把字符显示在单元格里

package sample;import javafx.application.Application;import javafx.collections.FXCollections;import javafx.collections.ObservableList;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.ListCell;import javafx.scene.control.ListView;import javafx.scene.control.TextField;import javafx.scene.layout.BorderPane;import javafx.scene.layout.HBox;import javafx.scene.layout.Priority;import javafx.stage.Stage;import javafx.util.Callback;public class DemoList extends Application {    @Override    public void start(Stage primaryStage) throws Exception {        // 添加hbox        HBox hBox = new HBox();        TextField field = new TextField();        Button b1 = new Button("添加");        Button b2 = new Button("删除");        Button b3 = new Button("修改");        hBox.getChildren().addAll(field,b1,b2,b3);        // 设置listview        ListView<Student> listView = new ListView<>();        // 设置数据源        ObservableList<Student> list = FXCollections.observableArrayList();        // 设置数据源        listView.setItems(list);        // 生成单元格        listView.setCellFactory(new Callback<ListView<Student>, ListCell<Student>>() {            @Override            public ListCell<Student> call(ListView<Student> param) {                return new mycell();            }        });        // 添加数据        list.add(new Student("张三"));        list.add(new Student("王五"));        list.add(new Student("李丹"));        BorderPane root = new BorderPane();        HBox.setHgrow(field, Priority.ALWAYS);        // 添加按钮监听        b1.setOnAction(new EventHandler<ActionEvent>() {            @Override            public void handle(ActionEvent event) {                String text = field.getText();                list.add(new Student(text));            }        });        b2.setOnAction(new EventHandler<ActionEvent>() {            @Override            public void handle(ActionEvent event) {                // 选择当前选择的行                int i = listView.getSelectionModel().getSelectedIndex();                if (i >= 0){                    list.remove(i);                }            }        });        b3.setOnAction(new EventHandler<ActionEvent>() {            @Override            public void handle(ActionEvent event) {                int i = listView.getSelectionModel().getSelectedIndex();                String name = field.getText();                if (i > 0){                    // 获取索引对应的数字                    Student s = list.get(i);                    // 覆盖数据                    s.name = name;                    list.set(i,s);                }            }        });        root.setTop(hBox);        root.setCenter(listView);        primaryStage.setTitle("列表属性");        primaryStage.setScene(new Scene(root,400,300));        primaryStage.show();    }    // 单元格显示    static class mycell extends ListCell<Student>{        @Override        protected void updateItem(Student item, boolean empty) {            super.updateItem(item, empty);            if (item != null){                this.setText(item.name);            } else if(empty || item == null){                setText(null);            }        }    }    static class Student{        private String name;        public Student(){}        public Student( String name) {            this.name = name;        }        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }    }}

效果图如下

javaFx 安全开发 三

鼠标事件处理

鼠标可以常用的监听方式左键单击左键双击右键单击在MouseEvent 对象里,能得到以下信息:event.getButton()  按钮 (左,中,右)event.getClickCount()  移动0 单击1 双击2event.getX() 点击位置 窗口坐标event.getSceneX()  单击位置 屏幕坐标
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) {                // 对鼠标点击的事件进行处理                if ( event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2){                    System.out.println("鼠标左键点击了两次");                } else if(event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 1){                    System.out.println("鼠标左键点击了一次");                }                /**                Alert alert = new Alert(Alert.AlertType.INFORMATION);                alert.setTitle("弹窗标题");                alert.setHeaderText("弹窗信息");                alert.showAndWait();                */            }        });        root.setCenter(b1);        primaryStage.setTitle("鼠标操作");        primaryStage.setScene(new Scene(root,500,50));        primaryStage.show();    }}

javaFx 安全开发 三

树列表

import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.control.TreeItem;import javafx.scene.control.TreeView;import javafx.scene.layout.StackPane;import javafx.stage.Stage;public class DemoTreeView extends Application {    @Override    public void start(Stage primaryStage) throws Exception{        StackPane root = new StackPane();        TreeItem treeItem = new TreeItem<>("根目录");        treeItem.setExpanded(true);        for(int i = 0;i < 5;i++){            TreeItem item = new TreeItem<>("节点:" + i);            treeItem.getChildren().add(item);        }        TreeView treeView = new TreeView<>(treeItem);        root.getChildren().add(treeView);        primaryStage.setTitle("TreeView的使用");        primaryStage.setScene(new Scene(root, 300, 275));        primaryStage.show();    }}

代码分析:

使用treeview 展示树列表 多层嵌套TreeItem 就是多层树列表

javaFx 安全开发 三

多列表

顾名思义 就是树列表 多排几列 如下图: 名词对应的列 修改时间 类型 大小等

javaFx 安全开发 三

import java.io.File;public class UploadItem{    public long localId; // 本地上传分配的ID    public String localGUID; // 本地上传分配的GUID    public String thumb;    public File filePath; // 本地文件路径    public String title;  // 标题, 默认为文件名, 但允许被用户改名    public long size;  // 文件大小    public long timeCreated;    public UploadItem(){}    public UploadItem(String title, long size, long timeCreated){        this.title = title;        this.size = size;        this.timeCreated = timeCreated;    }}
package sample.duoTree;import javafx.application.Application;import javafx.stage.Stage;import javafx.util.Callback;import javafx.scene.Scene;import javafx.scene.control.TreeItem;import javafx.scene.control.TreeTableCell;import javafx.scene.control.TreeTableColumn;import javafx.scene.control.TreeTableColumn.CellDataFeatures;import javafx.scene.control.TreeTableView;import javafx.scene.layout.BorderPane;public class Main extends Application{    TreeTableView<UploadItem> treeTable = new TreeTableView<UploadItem>();    @Override    public void start(Stage primaryStage){        initTreeTable();        initTreeData();        BorderPane root = new BorderPane();        root.setCenter(treeTable);        Scene scene = new Scene(root, 400, 400);        primaryStage.setScene(scene);        primaryStage.show();    }    private void initTreeTable(){        // 添加多个列        TreeTableColumn<UploadItem, UploadItem> columns[] = new TreeTableColumn[3];        columns[0] = new TreeTableColumn("文件名");        columns[1] = new TreeTableColumn("大小");        columns[2] = new TreeTableColumn("任务创建时间");        treeTable.getColumns().addAll(columns);        // 定义每个列的列宽        columns[0].setPrefWidth(150);        columns[1].setPrefWidth(80);        columns[2].setPrefWidth(120);        // 设置 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 MyTableTreeCell("title");        });        columns[1].setCellFactory((param)->{            return new MyTableTreeCell("size");        });        columns[2].setCellFactory((param)->{            return new MyTableTreeCell("filePath");        });    }    private void initTreeData(){        // 根节点只是占一个位置        TreeItem<UploadItem> root = new TreeItem<UploadItem>(new UploadItem());        treeTable.setRoot( root );        treeTable.setShowRoot(false);        UploadItem data_1 = new UploadItem("测试视频", 192000, System.currentTimeMillis());        root.getChildren().add( new TreeItem( data_1));        UploadItem data_2 = new UploadItem("测试图片", 239000, System.currentTimeMillis());        root.getChildren().add( new TreeItem( data_2));    }    // 单元格的显示    class MyTableTreeCell extends TreeTableCell<UploadItem,UploadItem>{        String columnID;        public MyTableTreeCell(String columnID){            this.columnID = columnID;        }        @Override        protected void updateItem(UploadItem item, boolean empty){            super.updateItem(item, empty);            // 自定义单元格显示内容            if (empty || item == null){                setText(null);                setGraphic(null);            } else{                setGraphic(null);                if(columnID.equals("title"))                    this.setText(String.valueOf(item.title));                else if(columnID.equals("size"))                    this.setText(String.valueOf(item.size));                else if(columnID.equals("filePath"))                    this.setText(String.valueOf(item.timeCreated));            }        }    }}

javaFx 安全开发 三

案例 文件查看器

思路:

程序支持查看java代码 txt文件 图片。

左侧显示文件名 右侧显示其内容

package sample.readUtils;import java.io.File;public class FileItem {    public String fileName;   // 文件名    public String firstName;  // 前缀名    public File file;    public int type = BAD_FORMAT; // 1, 文本文件; 2,图片文件; -1, 不支持的文件类型    // 文件类型常量    public static final int TEXT = 1;    public static final int IMAGE = 2;    public static final int BAD_FORMAT = -1;    // 后缀数组    private final String[] txtTypes = { "txt", "java"};    private final String[] imageTypes = { "jpg", "jpeg", "png", "bmp" };    // 构造函数,传入一个file并取得file的名字和类型    public FileItem(File file) {        this.file = file;        // 取得文件名        fileName = file.getName();        firstName = getFileFirstName(fileName);        // 根据文件后缀来判断文件的类型        String suffix = getFileSuffix(fileName);        type = BAD_FORMAT;        if (contains(txtTypes, suffix))            type = TEXT;        else if (contains(imageTypes, suffix))            type = IMAGE;    }    // 判断是否图片    public boolean contains(String[] types, String suffix) {        suffix = suffix.toLowerCase(); // 统一转成小写        for (String s : types) {            if (s.equals(suffix))                return true;        }        return false;    }    // 获取文件名的后缀    public String getFileSuffix(String name) {        int pos = name.lastIndexOf('.');        if (pos > 0)            return name.substring(pos + 1);        return ""; // 无后缀文件    }    // 获取文件名前缀    public String getFileFirstName(String name) {        int pos = name.lastIndexOf('.');        if(pos > 0) {            return name.substring(0, pos);        }        return "";    }}
package sample.readUtils;import javafx.collections.FXCollections;import javafx.collections.ObservableList;import javafx.scene.control.ListCell;/* * 左侧的文件列表 */import javafx.scene.control.ListView;import javafx.util.Callback;public class FileListView extends ListView<FileItem> {    private ObservableList<FileItem> listData = FXCollections.observableArrayList();    // 构造函数    public FileListView() {        setItems(listData);        // 设置单元格生成器 (工厂)        setCellFactory(new Callback<ListView<FileItem>, ListCell<FileItem>>() {            @Override            public ListCell<FileItem> call(ListView<FileItem> param){                return new MyListCell();            }        });    }    // 获取数据源    public ObservableList<FileItem> data() {        return listData;    }    // 设置单元格显示    static class MyListCell extends ListCell<FileItem> {        @Override        protected void updateItem(FileItem item, boolean empty) {            // FX框架要求必须先调用 super.updateItem()            super.updateItem(item, empty);            // 自己的代码            if (item == null) {                this.setText("");            } else {                this.setText(item.fileName);            }        }    }}
package sample.readUtils;import javafx.scene.image.Image;import javafx.scene.image.ImageView;import javafx.scene.layout.Pane;/* * 用于显示图片的工具类 * 封装成一个容器 * 这个容器显示整张图片 * 适应父窗口 */public class MyImagePane extends Pane {    ImageView imageView = new ImageView();    Image image;    public MyImagePane() {        // 添加图片        getChildren().add(imageView);    }    public void showImage(Image image) {        this.image = image;        imageView.setImage(image);        layout();    }    @Override    protected void layoutChildren() {        double w = getWidth();        double h = getHeight();        // 对ImageView进行摆放,使其适应父窗口        imageView.resizeRelocate(0, 0, w, h);        imageView.setFitWidth(w);        imageView.setFitHeight(h);        imageView.setPreserveRatio(true);    }}
package sample.readUtils;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;public class TextFileUtils {    public static String read(File f, String charset) throws Exception{        FileInputStream fstream = new FileInputStream(f);        try {            int fileSize = (int)f.length();            if(fileSize > 1024*512)                throw new Exception("File too large to read! size=" + fileSize);            byte[] buffer = new byte[fileSize];            // 读取到字符数组里            fstream.read(buffer);            return new String(buffer, charset);        }finally {            try{                fstream.close();            }catch(Exception e) {}        }    }    public static void write(File f, String text, String charset) throws Exception{        FileOutputStream fstream = new FileOutputStream(f);        try{            fstream.write( text.getBytes( charset ));        }finally        {            fstream.close();        }    }}
package sample.readUtils;import java.io.File;import javafx.application.Application;import javafx.collections.ObservableList;import javafx.stage.Stage;import javafx.scene.Node;import javafx.scene.Scene;import javafx.scene.control.Tab;import javafx.scene.control.TabPane;import javafx.scene.control.TextArea;import javafx.scene.image.Image;import javafx.scene.input.MouseButton;import javafx.scene.input.MouseEvent;import javafx.scene.layout.BorderPane;public class Main extends Application {    FileListView fileList = new FileListView();    TabPane tabPane = new TabPane();    @Override    public void start(Stage primaryStage) {            // 加载左侧文件列表            initFileList();            BorderPane root = new BorderPane();            root.setLeft(fileList);            root.setCenter(tabPane);            Scene scene = new Scene(root,800,500);            primaryStage.setTitle("文件浏览器");            primaryStage.setScene(scene);            primaryStage.show();    }    public void initFileList(){        fileList.setPrefWidth(200);        // 左侧加载小仙女目录下的文件        File dir = new File("C:\Users\Administrator\Desktop\demo");        File[] files = dir.listFiles();        for(File f : files) {            FileItem fitem = new FileItem(f);            // 添加到左侧列表中            fileList.data().add(fitem);        }        // 列表是鼠标事件响应        fileList.setOnMouseClicked((MouseEvent event)->{            // 如果左键单击的话            if(event.getClickCount() == 1 && event.getButton() == MouseButton.PRIMARY) {                oneClicked();            }        });    }    // 单击处理    public void oneClicked() {        // 获取列表选中模块,获取索引        int index = fileList.getSelectionModel().getSelectedIndex();        FileItem fitem = fileList.data().get(index);        try {            openFile(fitem);        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    // 打开左侧文件    public void openFile(FileItem fitem) throws Exception{        // 查看选项卡是否打开        Tab tab = findTab(fitem);        if(tab != null) {            // 设置为选中的选项卡            // int pos = tabPane.getTabs().indexOf(tab);  // 获取id            tabPane.getSelectionModel().select(tab);            return;        }        // 打开一个新的选项卡并选中        Node currentView = null;        if(fitem.type == FileItem.TEXT) {            // 文本文件处理            String str = TextFileUtils.read(fitem.file, "UTF-8");            TextArea t = new TextArea();            t.setText(str);            currentView = t;        }else if(fitem.type == FileItem.IMAGE) {            // 图片文件处理            // 获取文件的本地路径            Image image = new Image(fitem.file.toURI().toString());            MyImagePane t = new MyImagePane();            t.showImage(image);            currentView = t;        }else throw new Exception("不支持打开该格式");        // 创建新的选项卡并选中        tab = new Tab();        tab.setText(fitem.firstName);        tab.setContent(currentView);        tabPane.getTabs().add(tab);        tabPane.getSelectionModel().select(tab);    }    // 查看在右侧选项卡是否打开    public Tab findTab(FileItem fitem) {        ObservableList<Tab> tabs = tabPane.getTabs();        for(Tab tab : tabs) {            if(tab.getText().equals(fitem.firstName)) {                return tab;            }        }        return null;    }    public static void main(String[] args) {        launch(args);    }}

javaFx 安全开发 三

案例 目录浏览器

打开一个目录 显示内文件名 大小 修改时间

package sample.file;import java.io.File;public class FileInfo {    public File file;    public String name; // 文件名    public long lastModified; // 最后修改时间    public long size;     // 文件大小    public boolean isDir = false;   // 判断目录    public FileInfo() {    }    public FileInfo(File f) {        // 获取文件的一些属性        this.file = f;        name = f.getName();        size = f.length();        lastModified = f.lastModified();        isDir = f.isDirectory();    }}
package sample.file;import java.text.SimpleDateFormat;import java.util.List;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 FileBrowser extends TreeTableView<FileInfo> {    // 根节点    TreeItem rootItem = new TreeItem(new FileInfo());    // 列    TreeTableColumn<FileInfo, FileInfo> columns[] = new TreeTableColumn[3];    public FileBrowser() {        // 初始化列的设置        initColumns();        // 扁平化显示, 不显示根节点, 但必须要有根节点        this.setRoot( rootItem );        this.setShowRoot(false);    }    // 清空    public void clear() {        rootItem.getChildren().clear();    }    // 添加    public void add(List<FileInfo> datalist) {        for(FileInfo fi : datalist) {            TreeItem item = new TreeItem(fi);            rootItem.getChildren().add(item);        }    }    @Override    protected void layoutChildren() {        super.layoutChildren();        // 动态设置列宽        double w = this.getWidth();        double w0 = w * 0.4;        double w1 = w * 0.2;        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("name");        });        columns[1].setCellFactory((param)->{            return new MyTreeTableCell("size");        });        columns[2].setCellFactory((param)->{            return new MyTreeTableCell("lastModified");        });    }    // 单元格的显示    static class MyTreeTableCell extends TreeTableCell<FileInfo,FileInfo> {        static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        String columnID;        public MyTreeTableCell(String columnID) {            this.columnID = columnID;        }        @Override        protected void updateItem(FileInfo item, boolean empty) {            super.updateItem(item, empty);            if (empty || item == null) {                setText(null);                setGraphic(null);            } else {                setGraphic(null);                if(columnID.equals("name")) {                    this.setText(String.valueOf(item.name));                }                else if(columnID.equals("size")) {                    if(item.isDir)  // 如果是目录则不显示大小                        setText("目录");                    else                        setText(String.valueOf(item.size));                }                else if(columnID.equals("lastModified")) {                    this.setText(sdf.format(item.lastModified)); // 格式化为年月日时分秒                }            }        }    }}
package sample.file;import java.io.File;import java.util.ArrayList;import javafx.application.Application;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.stage.DirectoryChooser;import javafx.stage.Stage;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.layout.BorderPane;public class Main extends Application {    Stage stage; // 主窗口    // 文件浏览功能    FileBrowser fileBrowser = new FileBrowser();    @Override    public void start(Stage primaryStage) {        this.stage = primaryStage;            // 面板            BorderPane root = new BorderPane();            root.setCenter(fileBrowser);            primaryStage.setTitle("目录练习");            primaryStage.setScene( new Scene(root, 600, 400));            primaryStage.show();            // 按钮添加            Button btnOpen = new Button("打开目录");            root.setTop(btnOpen);            btnOpen.setOnAction(new EventHandler<ActionEvent>() {                @Override                public void handle(ActionEvent event) {                    // 当我点击按钮 打开窗口                    openFolder();                }            });    }    // 打开目录    private void openFolder() {        // 选择一个目录        DirectoryChooser chooser = new DirectoryChooser();        chooser.setTitle("打开目录");        // 展示目录        File dir = chooser.showDialog(stage);        // dir是用户选中的目录        if (dir != null) {            showFiles(dir);        }    }    // 显示目录下的文件    private void showFiles(File dir) {        File[] files = dir.listFiles();        if(files == null || files.length == 0){            return;        }        ArrayList<FileInfo> datalist = new ArrayList<FileInfo>();        for(File f : files) {            datalist.add(new FileInfo( f));        }        // 显示这些文件/目录的列表        fileBrowser.clear();        fileBrowser.add( datalist );    }    public static void main(String[] args) {        launch(args);    }}

javaFx 安全开发 三

原文始发于微信公众号(轩公子谈技术):javaFx 安全开发 三

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月26日01:57:39
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   javaFx 安全开发 三https://cn-sec.com/archives/810767.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息