обновление ярлыка с прогрессом http сообщения не работает. IllegalStateException - PullRequest
0 голосов
/ 17 мая 2019

У меня проблемы с привязкой компонента пользовательского интерфейса к наблюдаемой, которая получает обновленный прогресс из события http post.Я получаю IllegalStateException

Насколько я понимаю, проблема в том, что обновление привязки не происходит в потоке пользовательского интерфейса.Ответы, которые я прочитал, говорят, что мне нужно использовать runAsync, а затем указать блок пользовательского интерфейса для обновления компонента пользовательского интерфейса, но я не знаю, как этого добиться.

// View class
private val controller: ZumController by inject()

item("_Upload") {
    isMnemonicParsing = true
    action {
       controller.uploadToServer()
    }
}

bottom = label() {
    useMaxWidth = true
    padding = Insets(5.0, 10.0, 5.0, 10.0)
    this.bind(controller.progress)
}

// Controller class
var progress = SimpleStringProperty("Select images to upload")

fun uploadToServer() {
    images.forEach{ p ->
        Fuel.upload("http://127.0.0.1:8089")
                .add {FileDataPart(File(p), name = "file")}
                .progress { readBytes, totalBytes ->
                    progress.value = (readBytes.toFloat() / totalBytes.toFloat() * 100).toString()}
     .response { _ -> }
    }
}

Как мне поступить?удостовериться, что пользовательский интерфейс обновляется во время потока приложения, когда мне нужен прогресс перед возвратом вызова функции (uploadToServer ())?Извините, если на этот вопрос уже был дан ответ, я все еще не понимаю, что именно здесь происходит.

Ответы [ 2 ]

0 голосов
/ 18 мая 2019

TornadoFX имеет встроенный объект TaskStatus, который имеет свойства для выполнения задачи.Вы можете привязать одно или несколько свойств объекта TaskStatus к любому элементу пользовательского интерфейса и просто вызвать updateProgress из функции контроллера.Вам даже не нужно передавать объект TaskStatus, поскольку экземпляр по умолчанию будет использоваться, если вы этого не сделаете.

В рамках есть несколько тестовых приложений, которые делают это:

https://github.com/edvin/tornadofx/blob/master/src/test/kotlin/tornadofx/testapps/AsyncProgressApp.kt https://github.com/edvin/tornadofx/blob/master/src/test/kotlin/tornadofx/testapps/TaskStatusTest.kt

Тем не менее, быстрое и грязное решение для обновления пользовательского интерфейса из любого другого потока просто заключает в себе код манипуляции пользовательского интерфейса внутри runLater {}.Это будет работать одинаково хорошо, например, просто для обновления метки.

0 голосов
/ 17 мая 2019

Я решил свою проблему со следующими изменениями. Я передаю FXTask в функцию uploadToServer (). Там я обновляю сообщение () обратным вызовом хода выполнения для запроса HTTP POST. Я не могу сказать, что это лучший способ, но он работает. не стесняйтесь обновлять этот ответ более четким и кратким кодом

item("_Upload") {
    isMnemonicParsing = true
    action {
        runAsync {
            controller.uploadToServer(this)
        } ui {

        }
    }
}

fun uploadToServer(task: FXTask<*>) {
    images.forEach{ p ->
        Fuel.upload("http://127.0.0.1:8089")
                .add {FileDataPart(File(p), name = "file")}
                .progress { readBytes, totalBytes ->
                    val perComplete = readBytes.toFloat() / totalBytes.toFloat() * 100
                    task.updateMessage("Uploading $p %.2f".format(perComplete).plus("%"))
                }
                .response { _ -> }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...