前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用javafx框架tornadofx做了个天气预报的程序

用javafx框架tornadofx做了个天气预报的程序

原创
作者头像
用户6167008
修改2019-10-16 18:56:29
1.9K1
修改2019-10-16 18:56:29
举报

此实例用到了rest api,tableview,listview,linechart、ItemViewModel等知识,演示了动态加载数据的方法.

用到了jsonpath库,在build.gradle依赖中需添加 implementation("com.jayway.jsonpath:json-path:2.4.0")

代码语言:txt
复制
class WeatherApp : App(WeatherView::class)
class WeatherView : View("十五天天气预报") {
    val weatherVM: WeatherViewModel by inject()
    val controller: WeatherController by inject()
    var hdata: XYChart.Series<String, Number> by singleAssign()
    var ldata: XYChart.Series<String, Number> by singleAssign()
    override val root = borderpane {

        bottom = hbox(4) {
            progressbar(controller.taskProgress)
            label(controller.taskMessage)
            visibleWhen { controller.taskRunning }
            paddingAll = 4
        }
        left = vbox(4) {
//            button("refresh") {
//                action {
//                    controller.refresh()
//                }
//            }
            textfield(weatherVM.city)
            listview(controller.cities) {
                bindSelected(weatherVM.city)
                cellFormat {
                    // 只显示城市名称,不显示城市ID
                    text=it.split(",").first()
                }
                onUserSelect(1) {
                    controller.refresh()
                }
            }
        }
        center = tableview(controller.weathers) {
            column("date", Weather::dateProperty)
            column("type", Weather::typeProperty)
            column("高温℃", Weather::highProperty)
            column("低温℃", Weather::lowProperty)
            column("风向", Weather::fxProperty)
            bindSelected(weatherVM)
            smartResize()
        }
        right = linechart("十五天天气预报", CategoryAxis(), NumberAxis()) {
            id="lc"
            prefWidth=600.0

            // 设置成false可避免在第一次显示数据时,x轴的下标堆积在一起
            animated=false

            series("高温") {
                hdata = this
            }
            series("低温") {
                ldata = this
            }
        }
    }
}


class WeatherController : Controller() {
    val api: Rest by inject()
    val weathers = observableListOf<Weather>()
    val cities = observableListOf<String>()
    val weatherVM: WeatherViewModel by inject()
    val v: WeatherView by inject()
    val taskRunning = booleanProperty()
    val taskMessage = stringProperty()
    val taskProgress = doubleProperty()

    fun refresh() {
        v.title = weatherVM.city.value.split(",").first().plus(" 未来十五天天气预报")
        val t = task {
            loadWeathers(weatherVM.city.value.toString().split(",").last())
            updateMessage("Loading weathers")
            updateProgress(0.4, 1.0)
        }
        t.run()

        taskRunning.bind(t.runningProperty())
        taskMessage.bind(t.messageProperty())
        taskProgress.bind(t.progressProperty())
    }

    // 文件中读取城市列表
//    fun loadCities1() = GlobalScope.launch {
//        cities.clear()
//        // 使用hutool的FileUtil工具类,可正常读取resources下的资源文件
////        FileUtil.readLines("city.csv", "gbk").forEach {
////            cities.add(it)
////        }
//
//        // 使用tornadofx框架的resources无法读取文件内容,原因不明
////        File(resources.url("city.csv").toExternalForm()).readLines().forEach {
////            cities.add(it)
////        }
//
//        File(javaClass.getResource("/city.csv").toURI()).readLines().forEach {
//            cities.add(it)
//        }
//    }

    // 从文件中读取城市名称及其代码数据,填充到listview中
    fun loadCities() {
        cities.clear()
        run {
            File(javaClass.getResource("/city.csv").toURI()).readLines().forEach {
                cities.add(it)
            }
        }
    }


    // citykey:城市ID,如:"101030100"
    fun loadWeathers(citykey: String) {
        // 更新前清空数据
        weathers.clear()
        v.hdata.data.clear()
        v.ldata.data.clear()

//        安徽 101030100
        val json = api.get(citykey).one()
        val dates = JsonPath.read(json.toString(), "$.data.forecast[*].ymd") as List<String>
        val types = JsonPath.read(json.toString(), "$.data.forecast[*].type") as List<String>
        val city = JsonPath.read(json.toString(), "$.cityInfo.city") as String
        val time = JsonPath.read(json.toString(), "$.time") as String
        val quality = JsonPath.read(json.toString(), "$.data.quality") as String
        val wendu = JsonPath.read(json.toString(), "$.data.wendu") as String
        val shidu = JsonPath.read(json.toString(), "$.data.shidu") as String
        val pm25 = JsonPath.read(json.toString(), "$.data.pm25") as Double
        val pm10 = JsonPath.read(json.toString(), "$.data.pm10") as Double
        val highs = JsonPath.read(json.toString(), "$.data.forecast[*].high") as List<String>
        val lows = JsonPath.read(json.toString(), "$.data.forecast[*].low") as List<String>
        val fxs = JsonPath.read(json.toString(), "$.data.forecast[*].fx") as List<String>
        dates.indices.forEach {
            val w = Weather()
            w.date = dates[it]
            w.type = types[it]
            w.fx = fxs[it]
            w.city = city
            w.quality = quality
            w.time = time
            w.high = highs[it].split(" ").last().trimEnd('℃')
            w.low = lows[it].split(" ").last().trimEnd('℃')
            weathers.add(w)


            val date = dates[it].split("-").drop(1).joinToString("/")
            v.hdata.data(date, w.high.toInt()) {
                node.add(Text(w.high))
                node.tooltip(w.type)
//                Tooltip.install(node, Tooltip(w.high))
            }
            v.ldata.data(date, w.low.toInt()) {
                node.add(Text(w.low))
            }
        }
        // 通过控件id 找到要操作的控件
        (primaryStage.scene.lookup("#lc") as LineChart<String,Number>).title=v.title
//        (v.root.right as LineChart<String,Number>).title=v.title
        v.title+="  当前天气:$quality,  更新时间:$time,  温度:$wendu,  湿度:$shidu,  pm25:$pm25,  pm10:$pm10"

//        read(json, "$.store.book[*].author")
//        val d=json.get("data")
//       val forecast= JSONUtil.parseObj(d).get("forecast")
//        println(forecast.toString())
//        println(JSONUtil.parseObj().get("ymd"))
//        weathers.addAll(api.get("101030100").list().toModel())
    }


    fun loadWeathers1(citykey: String) {
        weathers.clear()
        // 此方法无法正确得到想要的数据
        weathers.addAll(api.get(citykey).list().toModel())
    }

    init {
        api.baseURI = "http://t.weather.sojson.com/api/weather/city/"
        loadCities()
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档