Некоторые основные вопросы о Котлине - PullRequest
1 голос
/ 12 июня 2019

Я пытаюсь изучить Kotlin и TornadoFX, и я работаю с из этого репозитория

В настоящее время идея состоит в том, что приложение будет отображать три ряда по 7 кнопок. Каждая кнопка представляет букву, которая известна или неизвестна. Если буква известна, она отображается на кнопке. Если буква неизвестна, на кнопке отображается индекс (0-20).

Я сделал это, создав (с уверенностью думая о Java) глобальный массив с 21 элементом. Каждый элемент начинается с нуля. Я определил это в основном приложении, используя конструкцию компаньона:

class InteractiveClientApp : App(MainView::class) {
    companion object {
        var knownLetters = arrayOfNulls<String>(21)
    }

Затем в конструкторе приложения я инициализировал несколько случайных элементов со значениями, просто чтобы посмотреть, будет ли это работать (не работает).

override fun init() {
    knownLetters[4] = "T"
    knownLetters[9] = "G"
    knownLetters[17] = "Z"
}

Затем в LettersGridView я использую forEachIndexed для массива knownLetters, чтобы у меня был доступ к элементу из массива и индексу для него.

import jcn.deduce.client.InteractiveClientApp.Companion.knownLetters


class LettersGridView : View() {
    override val root = gridpane {

            knownLetters.forEachIndexed { index, element ->

                if (index == 0 || index % 7 == 0) {
                    row {
                        button(element?.toString() ?: index.toString()) {
                            useMaxWidth = true
                            gridpaneConstraints {
                                marginBottom = 10.0
                            }
                        }
                    }
                } else {
                    button(element?.toString() ?: index.toString()) {
                        useMaxWidth = true
                        gridpaneConstraints {
                            marginBottom = 10.0
                        }
                    }
                }
            }
        }
    }

В действительности происходит то, что вместо ожидаемой 21 появляются три кнопки, а значение на кнопке всегда является индексом, а не буквенным значением. Также показаны индексы 20, 7 и 14. Не три, которые я использовал при настройке элементов в массиве. Так что я что-то там упускаю.

Также я думаю, что не совсем правильно понял этот бит:

 button(element?.toString() ?: index.toString()) {
                        useMaxWidth = true
                        gridpaneConstraints {
                            marginBottom = 10.0
                        }
                    }

То, что я пытаюсь сказать, есть: «Если значение элемента не равно нулю, используйте значение элемента, в противном случае используйте строковое значение индекса. Это не работает, потому что кнопки имеют только индексы на них, никогда буквы.

Я замечаю, что если я отключу элемент .toString () для элемента, я получаю сообщение об ошибке, что кнопка ожидает строку, а не строку ?. Что похоже на Java и String vs Optional . Однако когда я добавляю toString (), я получаю предупреждение IDE о том, что toString () является избыточным.

Если я сниму трейлинг? В целом, я получаю чистую компиляцию, но все равно отображаются только три кнопки, и их метки являются индексными, а не элементными.

Так что я почти уверен, что где-то заблудился, может кто-нибудь объяснить, почему моя программа не работает?

Кроме того, когда я отлаживаю приложение, я всегда сталкиваюсь с двумя процессами. Я не понимаю почему, но вот как выглядит IntelliJ:

enter image description here

Это нормально?

1 Ответ

2 голосов
/ 12 июня 2019

Ваша функция инициализации работает, вы можете подтвердить это, изменив инициализацию записи 20, 7 или 14 на букву, и вы должны увидеть букву при следующем запуске.

Что касается вашей основной проблемы, то причина, по которой вы видите 20, 7, а затем 14, заключается в том, что в этом разделе:

if (index == 0 || index % 7 == 0) {
    row {
        button(element?.toString() ?: index.toString()) {
            useMaxWidth = true
            gridpaneConstraints {
                marginBottom = 10.0
            }
        }
    }
}

Вы добавляете строку с одной кнопкой, эти кнопки будут 0, 7 и 14 (так как они все == 0% 7). Это означает, что вы добавите только три строки, каждая с одной кнопкой. Вы можете быть смущены тем, почему он говорит 20 вместо 0 ... Ну, это потому, что следующий раздел:

else {
    button(element?.toString() ?: index.toString()) {
        useMaxWidth = true
        gridpaneConstraints {
            marginBottom = 10.0
        }
    }
}

Также добавляет кнопки, но не в какой-либо ряд (обратите внимание, что эти кнопки не находятся внутри ряда {} лямбда). Это означает, что все эти кнопки будут добавлены в сетку сверху друг друга, включая эту первую кнопку 0. Последняя добавленная кнопка - 20, поэтому, почему вы видите 20, она закрывает 0!

Вот пример того, как подойти к этой проблеме:

val rowSize = 7
val rows = knownLetters.toList().chunked(rowSize)
rows.forEachIndexed { rowIndex, elements ->
    row {
        elements.forEachIndexed { buttonIndex, element ->
            val displayIndex = rowSize * rowIndex + buttonIndex
            button("${element ?: displayIndex}") {
                useMaxWidth = true
                gridpaneConstraints {
                    marginBottom = 10.0
                }
            }
        }
    }
}

При этом используется метод "chunked" библиотек Kotlin, чтобы разделить массив из 21 размера на три списка размера 7. Затем вы можете выполнить цикл (вам нужно соединить вместе индексный дисплей с помощью этого подхода), создав новую строку для каждого списка (3 списка составляют 3 строки), в то же время создавая кнопки во вложенном цикле внутри лямбда-строки.

Ключевой момент, который нужно убрать, это то, что не все ваши кнопки добавляются в ряд {} лямбда.

Что касается проблемы двойного процесса, у меня нет этой проблемы, если я запускаю приложение с помощью основного метода, например так:

fun main(args: Array<String>) {
    launch<InteractiveClientApp>(args)
}

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...