我是编写和声明性编程的新手,我正在努力理解它.为了学习,在阅读了教程和观看了课程后,现在我正在创建我的第一个应用程序.
我正在创建一个具有Compose多平台的合成桌面应用程序,它将允许您从计算机中 Select 一个文件夹并显示该文件夹中的所有文件.我要用JFileChooser
来 Select 一个文件夹.当它被选中时,状态变量被更改,并且Box
被填充表示该文件夹中的文件名的文本.这些名称由使用JFileChooser
返回的路径的函数获得.
这款应用程序有两个奇怪的行为.首先,因为屏幕上有一个TextField
,如果我在里面写,填满文本的Box
似乎会被重新绘制,再次调用搜索文件的函数(这些文件可能是数千个,这会减缓应用程序的运行速度).
第二个奇怪的行为是,如果我再次打开JFileChooser
来更改文件夹,它会正确地重新绘制Box
,并获得该文件夹的文件名,但如果我 Select 先前 Select 的相同文件夹,Box
不会重新绘制,如果该文件夹中的文件发生更改,就会出现问题.
有没有人能帮我理解一下Compose
的这些问题?我认为这两个问题都与声明性写作逻辑有关,但不能理解哪里错了.谢谢.
这是显示JFileChooser的按钮
var listRomsState by remember { mutableStateOf(false) }
Button(onClick = {
folderChosenPath = folderChooser()
if (folderChosenPath != "")
listRomsState = true
}) {
Text(text = "List roms")
}
这是显示JFileChooser的函数
fun folderChooser(): String {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
val f = JFileChooser()
f.fileSelectionMode = JFileChooser.DIRECTORIES_ONLY
val result: Int = f.showSaveDialog(null)
if (result == JFileChooser.APPROVE_OPTION) {
return f.selectedFile.path
} else {
return ""
}
}
在显示文件 Select 器的按钮下方是包含文件名的列表:
if (listRomsState) {
RomsList(File(folderChosenPath))
}
这是RomsList函数:
@Composable
fun RomsList(folder: File) {
Box (
modifier = Modifier.fillMaxSize().border(1.dp, Color.LightGray)
) {
LazyColumn(
Modifier.fillMaxSize().padding(top = 5.dp, end = 8.dp)
){
var romsList = getRomsFromFolder(folder)
items(romsList.size) {
Box (
modifier = Modifier.padding(5.dp, 0.dp, 5.dp, 0.dp).fillMaxWidth(),
contentAlignment = Alignment.CenterStart
) {
Row (horizontalArrangement = Arrangement.spacedBy(5.dp)){
Text(text = "" + (it+1), modifier = Modifier.weight(0.6f).background(color = Color(0, 0, 0, 20)))
Text(text = romsList[it].title, modifier = Modifier.weight(9.4f).background(color = Color(0, 0, 0, 20)))
}
}
Spacer(modifier = Modifier.height(5.dp))
}
}
}
}
以下是递归获取文件夹的所有文件名的函数:
fun getRomsFromFolder(curDir: File? = File(".")): MutableList<Rom> {
var romsList = mutableListOf<Rom>()
val filesList = curDir?.listFiles()
filesList?.let {
for (f in filesList) {
if (f.isDirectory) romsList.addAll(getRomsFromFolder(f))
if (f.isFile) {
romsList.add(Rom(f.name))
}
}
}
return romsList
}