java - 从 Java 到 Kotlin

标签 java javafx kotlin

我正在尝试将用 java 编写的简单 JavaFX 计算转换为 Kotlin 代码。 https://gist.github.com/jewelsea/4344564 -> java 源代码。

这是我用 Kotlin 翻译的:

import Model.Math
import javafx.application.Application
import javafx.beans.binding.Bindings
import javafx.beans.property.*
import javafx.event.ActionEvent
import javafx.event.EventHandler
import javafx.geometry.Pos
import javafx.scene.Scene
import javafx.scene.control.*
import javafx.scene.input.KeyEvent
import javafx.scene.layout.*
import javafx.stage.Stage
import javafx.stage.StageStyle

import java.util.HashMap

// A simple Kotlin, JavaFX application
class KotlinCode : Application() {

    private val accelerators = HashMap<String, Button>()

    private val stackValue = SimpleDoubleProperty()
    private val value = SimpleDoubleProperty()

    enum class Op {
        NOOP, ADD, SUBTRACT, MULTIPLY, DIVIDE
    }

    private var curOp = Op.NOOP
    private var stackOp = Op.NOOP

    private val template = arrayOf(arrayOf("7", "8", "9", "/"), arrayOf("4", "5", "6", "*"), arrayOf("1", "2", "3", "-"), arrayOf("0", "c", "=", "+"))

    override fun start(stage: Stage) {
        val screen = createScreen()
        val buttons = createButtons()

        stage.title = "Calc"
        stage.initStyle(StageStyle.UTILITY)
        stage.isResizable = false
        stage.scene = Scene(createLayout(screen, buttons))
        stage.show()
    }

    private fun createLayout(screen: TextField, buttons: TilePane): VBox {
        val layout = VBox(20.0)
        layout.alignment = Pos.CENTER
        layout.style = "-fx-background-color: chocolate; -fx-padding: 20; -fx-font-size: 20;"
        layout.children.setAll(screen, buttons)
        handleAccelerators(layout)
        screen.prefWidthProperty().bind(buttons.widthProperty())
        return layout
    }

    private fun handleAccelerators(layout: VBox) {
        layout.addEventFilter(KeyEvent.KEY_PRESSED) { keyEvent ->
            val activated = accelerators[keyEvent.text]
            activated?.fire()
        }
    }

    private fun createScreen(): TextField {
        val screen = TextField()
        screen.style = "-fx-background-color: aquamarine;"
        screen.alignment = Pos.CENTER_RIGHT
        screen.isEditable = false
        screen.textProperty().bind(Bindings.format("%.0f", value))
        return screen
    }

    private fun createButtons(): TilePane {
        val buttons = TilePane()
        buttons.vgap = 7.0
        buttons.hgap = 7.0
        buttons.prefColumns = template[0].size
        for (r in template) {
            for (s in r) {
                buttons.children.add(createButton(s))
            }
        }
        return buttons
    }

    private fun createButton(s: String): Button {
        val button = makeStandardButton(s)

        if (s.matches("[0-9]".toRegex())) {
            makeNumericButton(s, button)
            //this.javaCode.makeNumericButton(s, button, curOp, value, stackValue, stackOp)
        } else {
            val triggerOp = determineOperand(s)
            if (triggerOp.get() != Op.NOOP) {
                //this.javaCode.makeOperandButton(button, triggerOp, this.curOp)
                makeOperandButton(button, triggerOp)
            } else if ("c" == s) {
                //this.javaCode.makeClearButton(button, value)
                makeClearButton(button)
            } else if ("=" == s) {
                makeEqualsButton(button)
            }
        }

        return button
    }

    private fun determineOperand(s: String): ObjectProperty<Op> {
        val triggerOp = SimpleObjectProperty(Op.NOOP)
        when (s) {
            "+" -> triggerOp.set(Op.ADD)
            "-" -> triggerOp.set(Op.SUBTRACT)
            "*" -> triggerOp.set(Op.MULTIPLY)
            "/" -> triggerOp.set(Op.DIVIDE)
        }
        return triggerOp
    }

    private fun makeStandardButton(s: String): Button {
        val button = Button(s)
        button.style = "-fx-base: beige;"
        accelerators.put(s, button)
        button.setMaxSize(java.lang.Double.MAX_VALUE, java.lang.Double.MAX_VALUE)
        return button
    }

    private fun makeEqualsButton(button: Button) {
        button.style = "-fx-base: ghostwhite;"
        button.setOnAction { actionEvent ->
            // On instancie notre objet Kotlin
            val math = Math()
            when (stackOp) {
                Op.NOOP -> {
                }
                Op.ADD -> value.set(math.adition(stackValue.get(), value.get()))
                Op.SUBTRACT -> value.set(math.substraction(stackValue.get(), value.get()))
                Op.MULTIPLY -> value.set(math.multiplication(stackValue.get(), value.get()))
                Op.DIVIDE -> value.set(math.division(stackValue.get(), value.get()))
            }
        }
    }

    private fun makeOperandButton(button: Button, triggerOp: ObjectProperty<Op>) {
        button.onAction = EventHandler {
            fun handle(actionEvent: ActionEvent) {
                curOp = triggerOp.get()
            }
        }
    }

    private fun makeNumericButton(s: String, button: Button) {
        button.onAction = EventHandler {
            fun handle(actionEvent: ActionEvent) {
                if (curOp == Op.NOOP) {
                    value.set(value.get() * 10 + Integer.parseInt(s))
                } else {
                    stackValue.set(value.get())
                    value.set(java.lang.Double.parseDouble(s))
                    stackOp = curOp
                    curOp = Op.NOOP
                }
            }
        }
    }

    private fun makeClearButton(button: Button) {
        button.onAction = EventHandler {
            fun handle(actionEvent: ActionEvent) {
                value.set(0.0)
            }
        }
    }

    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            launch(KotlinCode::class.java)
        }
    }
}

现在计算已启动,但没有任何操作绑定(bind)到按钮。有人知道吗?

我的猜测是,在 ma​​keOperandButtonma​​keNumericButtonma​​keClearButton 中,句柄函数永远不会被触发。但我不明白为什么。

非常感谢,祝你有美好的一天!

最佳答案

好吧,其实很简单,我猜不出来。我可以直接在 EventHandler 中运行代码。现在一切正常!

这 3 个方法应该是这样的:

private fun makeOperandButton(button: Button, triggerOp: ObjectProperty<Op>) {
    button.onAction = EventHandler {
        curOp = triggerOp.get()
    }
}

private fun makeNumericButton(s: String, button: Button) {
    button.onAction = EventHandler {
        if (curOp == Op.NOOP) {
            value.set(value.get() * 10 + Integer.parseInt(s))
        } else {
            stackValue.set(value.get())
            value.set(java.lang.Double.parseDouble(s))
            stackOp = curOp
            curOp = Op.NOOP
        }
    }
}

private fun makeClearButton(button: Button) {
    button.onAction = EventHandler {
        value.set(0.0)
    }
}

关于java - 从 Java 到 Kotlin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36516330/

相关文章:

java - 为 jenkins 配置相对于工作区的 ant 安装

kotlin - 阻塞每个方法的同步集合

kotlin - 使用 ktor 将文件上传到 telegram bot api

java - Java通用通配符打破类型界限

java - 表单生成和验证类似于java中的Symfony2?

java - 阻止程序终止的线程

java - 将自定义 uri 方案与适用于 Windows 的 Java 自包含应用程序相关联

javafx - 重启和暂停和恢复剪辑会挂起音乐播放器的gui,同时按下暂停和播放会从停止点恢复播放

java - 冲突版本警告(JavaFX、JDK、JRE)

android - java.lang.IllegalStateException : Expected BEGIN_OBJECT but was BEGIN_ARRAY Kotlin 错误