布局与上一个案例舒尔特基本相似,来体验一下吧,代码也在同小异,直接上代码:
重要的事情说3遍: 动手敲代码!!!动手敲代码!!!动手敲代码!!!
代码语言:javascript复制class MainAPP : App(MainView::class)
class MainView : View("把指定的图片全都给我找出来") {
private val c by inject<MainController>()
lateinit var r: GridPane
private val suerte = mutableListOf<String>()
private val nproperty = intProperty(2)//行列数
private val startTime = longProperty(0)//开始时间
private val endTime = longProperty(0)//结束时间
private val resultSize = intProperty()
private val correctSize = intProperty()
private val timeUsed = stringProperty(format(0))//使用时间
private val aniTimer = AniTimer()
private val isRun = booleanProperty(false)//标记aniTimer是否处于运行状态
private val _fontSize = intProperty(32)
private val originalContent = stringProperty("佩奇/${Random.nextInt(6)}.png")
private val titles = observableListOf<String>()
private val categories = observableListOf<String>()
private val _title = stringProperty()
private val titleMap = mutableMapOf<String, List<String>>()
private val dirName = stringProperty("佩奇")
init {
loadJsonFile(File("./content.json").toPath())
}
/**
* 加载项目根目录下的content.json文件,获取到的数据用于填充左侧的combobox和listview
*/
fun loadJsonFile(path: Path) {
categories.clear()
loadJsonArray(path).forEach {
val obj = it.asJsonObject()
val titlee = obj.getString("title").trim()
categories.add(titlee)
titleMap[titlee] = obj.getString("content").split(",").map { category ->
category.trim()
}
}
}
代码语言:javascript复制top = vbox {
hbox(10) {
paddingAll = 10.0
alignment = Pos.CENTER
button("加载文件") {
action {
_chooseFile()
}
}
combobox(_fontSize, (12..72 step 4).toList()) {
_fontSize.onChange {
refreshGrid()
}
}
button("刷新") {
action {
refreshGrid()
}
}
separator(Orientation.VERTICAL)
button("导出") {
action {
(1..c.outNums.value).map { i ->
refreshGrid()
val img = r.snapshot(SnapshotParameters(), null)
ImageIO.write(SwingFXUtils.fromFXImage(img, null), "png", File(c.outPath.value "./schulteGrid$i.png"))
}
information("恭喜!成功导出 ${c.outNums.value} 张舒尔特方格。")
}
}
separator(Orientation.VERTICAL)
togglegroup {
selectedToggleProperty().onChange {
val n = (it as RadioButton).text.toInt()
nproperty.set(n)
if (n > 1)
refreshGrid()
}
(2..8).forEach {
radiobutton(it.toString()) {
if (it == 2) isSelected = true
}
}
}
separator(Orientation.VERTICAL)
label(stringBinding(resultSize, correctSize) { "${correctSize.value}/${resultSize.value}" })
separator(Orientation.VERTICAL)
label(stringBinding(timeUsed) { "使用时间:$value" })
}
}
代码语言:javascript复制 // 刷新网格,点击单选按钮、更换listview中的选项、选择不同的单选按钮时会调用此函数,来更新gridview中的数据
private fun refreshGrid() {
timeUsed.set(format(0))
isRun.set(false)
aniTimer.stop()
r.clear()
suerte.clear()
resultSize.set(0)
val n = nproperty.value
val n2 = n * n
c.dirFiles(File("./图片/${dirName.value}"))?.let { pics ->
(1..n2).map {
suerte.add(pics.random())
}
}
originalContent.set(suerte.random())
correctSize.set(suerte.filter { it == originalContent.value }.size)
suerte.shuffle() //将list中的元素打乱顺序
val iter = suerte.iterator()
val cellSize = r.prefHeight / n //每个按钮大小
try {
(0 until n).map { i ->
(0 until n).map { j ->
r.add(button {
val imgPath = iter.next()
graphic = imageview(File(imgPath).toURI().toURL().toExternalForm()).apply {
fitHeight = cellSize - 2
fitWidth = cellSize - 2
isCache = true
}
setPrefSize(cellSize, cellSize)
isWrapText = true
action {
if (imgPath == originalContent.value) {
resultSize.set(resultSize.value 1)
}
if (resultSize < 2) {//当第一次点击时,开始计时
isRun.set(true)
startTime.set(System.currentTimeMillis())
}
if (isRun.value) {
aniTimer.start()
} else {
aniTimer.stop()
}
style {
backgroundColor = c("#99CC00")
}
if (correctSize.value == resultSize.value) {
isRun.set(false)
aniTimer.stop()
information("恭喜!成功完成本局")
}
}
style {
borderColor = box(c("red"))
borderWidth = box(1.px)
}
}, i, j)
}
}
} catch (e: Exception) {
return
}
}
inner class AniTimer : AnimationTimer() {
override fun handle(now: Long) {
runLater {
endTime.set(System.currentTimeMillis())
val totalTime = endTime.value - startTime.value //总消耗时间
timeUsed.set(format(totalTime))
}
}
}
}