关于制作表的学习:https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TableView.html
<S>表中对象的类
先构造对象:
public class Student {
public int id;
public int age;
public String name;
public String gender;
public Student(int id, int age, String name, String gender) {
this.id = id;
this.age = age;
this.name = name;
this.gender = gender;
}
}
然后在Main方法中的可视化代码的结构中添加表
这样就把表的结构建立好了:
接下来就是往表中添加内容:
点击一下,往表里面添加一行数据,
发生了点击事件,然后从输入框读取文字,然后调用addStudent,读取的内容为学生姓名,id自增,年龄,性别,随机生成。只有主线程执行,不需要考虑线程安全问题,最终拿到tableView.getItems,也就是学生的所有项,用尾插的方式往表里添加就可以了。
tableView是创建的时候赋值的,可以认为是拿到真实的tableView。
内容已经添加进去,但是没有显示:
原因就是缺少映射关系:每个对象的属性所对应的表头。TableView不能自己处理,需要手动添加一一映射关系。
所以现在要令表中数据显示出来,对表中数据添加映射关系:
其他三列数据同理,结果就可以看到表中数据了:
数据的可视化代码优化:把数据处理放在Student(模型层)中,可以减少代码,令代码更具有条理
以上是代码方式,fxml方式比较简单,单排查问题难:
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<GridPane fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml"
alignment="center"
hgap="10"
vgap="10">
<TextField fx:id="inputField" GridPane.rowIndex="0" GridPane.columnIndex="0" />
<Button text="点击我" GridPane.rowIndex="1" GridPane.columnIndex="0" onMouseClicked="#点击事件"/>
<Label fx:id="outputLabel" GridPane.rowIndex="2" GridPane.columnIndex="0" prefWidth="200" style="-fx-border-color: black; -fx-border-width: 1; -fx-border-radius: 5" />
<TableView fx:id="tableView" GridPane.rowIndex="3" GridPane.columnIndex="0">
<columns>
<TableColumn text="#ID">
<cellValueFactory>
<PropertyValueFactory property="id"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="姓名">
<cellValueFactory>
<PropertyValueFactory property="name"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="年龄">
<cellValueFactory>
<PropertyValueFactory property="age"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="性别">
<cellValueFactory>
<PropertyValueFactory property="gender"/>
</cellValueFactory>
</TableColumn>
</columns>
</TableView>
</GridPane>
至此,项目前期的如何制作界面的内容准备好了。
开始后端逻辑的处理:
选择一个文件夹作为根文件夹,根据文件名搜索该文件下的符合条件的文件;
文件夹路径 -> List<文件路径>
文件系统是树形结构组织
给定根节点,遍历以该节点为跟的树。
遍历问题:深度优先遍历、广度优先遍历
文件=元信息+内容
=Meta(文件名/文件路径/文件大小/权限/属性)+Content
java.io.File类
三种遍历方法:
深度优先遍历:
广度优先遍历:
//广度优先 -层序遍历-队列
private static void traversalBroadcast(File root) {
//所有文件都放入队列
Queue<File> queue = new LinkedList<>();
queue.offer(root);//先把root放进去
while (!queue.isEmpty()) {
File file = queue.poll();
boolean directory = file.isDirectory();
if (directory) {
System.out.println("文件夹:" + file);
}else {
System.out.println("普通文件:" + file);
}
File[] files = file.listFiles();
if (files == null) {
continue;
}
if (files.length == 0) {
continue;
}
for (File child : files) {
queue.offer(child);
}
}
}
实际项目中用哪个都可以,找东西层序遍历(广度优先遍历)比较好。
然后在fxml里添加对话框,以供用户选择文件夹进行索引。
在Controller中实现
此时就可以索引文件夹中的内容,在idea中出现结果,但还没有在表单中显示。
把结果放入表中:新建一个file-scan.fxml
?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<GridPane fx:controller="sample.FileScanController"
xmlns:fx="http://javafx.com/fxml"
alignment="center"
hgap="10"
vgap="10"
fx:id="rootGridPane">
<Button text="选择文件夹" GridPane.rowIndex="1" GridPane.columnIndex="0" onMouseClicked="#选择文件夹"/>
<TableView fx:id="tableView" GridPane.rowIndex="3" GridPane.columnIndex="0" prefWidth="1000">
<columns>
<TableColumn text="文件 OR 文件夹">
<cellValueFactory>
<PropertyValueFactory property="directory" />
</cellValueFactory>
</TableColumn>
<TableColumn text="路径">
<cellValueFactory>
<PropertyValueFactory property="path" />
</cellValueFactory>
</TableColumn>
</columns>
</TableView>
</GridPane>
新建一个FileScanController类与上面关联
package sample;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.TableView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.stage.DirectoryChooser;
import java.io.File;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 联想
* Date: 2021-01-19
* Time: 1:59
*/
public class FileScanController {
@FXML
public GridPane rootGridPane;
@FXML
public TableView tableView;
@FXML
public void 选择文件夹(MouseEvent mouseEvent) {
DirectoryChooser chooser = new DirectoryChooser();
File root = chooser.showDialog(rootGridPane.getScene().getWindow());
if(root == null) {
return;
}
Thread t = new Thread(() -> {
scan(root);
});
t.setDaemon(true);
t.start();
}
//调用该方法,既有文件夹,又有普通文件
private void scan(File root) {
Platform.runLater(() -> {
FileMeta fileMeta = new FileMeta(root);
tableView.getItems().add(fileMeta); // 涉及 UI 部分的,放到主线程执行
});
if (!root.isDirectory()) {
return;
}
File[] children = root.listFiles();
if (children == null) {
return;
}
for (File child : children) {
scan(child);
}
}
}
然后构建文件夹所对应的对象,现在要搜索的是文件夹而不是学生类。
package sample;
import java.io.File;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 联想
* Date: 2021-01-19
* Time: 2:03
*/
public class FileMeta {
private final File file;
public FileMeta(File file) {
this.file = file;
}
public String getDirectory() {
if (file.isDirectory()) {
return "文件夹";
}else {
return "普通文件";
}
}
public String getPath() {
return file.getAbsolutePath();
}
@Override
public String toString() {
return file.toString();
}
}
在Main方法中修改路径:
启动后就可以实现文件搜索了。