# JavaPickerDialog ## Обзор компонента `Minecraft_launcher` — десктопный лаунчер Minecraft на Qt Quick. Разным версиям игры нужны разные версии Java, и лаунчер умеет скачивать их сам: официальные сборки Mojang и сборки Temurin в двух вариантах — JDK и JRE. Держать в голове, какая Java нужна какой версии игры, пользователь не обязан. `JavaPickerDialog` — окно выбора сборки Java: слева типы сборок, справа сами версии с поиском. Устроено так же, как [VersionPickerDialog](VersionPickerDialog.md), с одним принципиальным отличием: выбранное здесь ещё и качается. У версий игры загрузку начинает сама сборка, а сборка Java, которой нет на диске, запуску ничем не поможет — поэтому кнопка подтверждения при необходимости сразу ставит выбранную сборку в очередь на скачивание. Окно также показывает, какая версия Java нужна выбранной версии игры, помечает сборки, которые для неё слишком старые, и позволяет удалять скачанное прямо из списка. ## Место в проекте и зависимости В начале файла объявлена `pragma ComponentBehavior: Bound`. Импортирует `QtQuick`, `QtQuick.Controls 2.15` и `QtQuick.Layouts 2.15`. Работает с C++-типом `LauncherBackend` (`launcherbackend.h`, `QML_ELEMENT` в модуле `Minecraft_launcher`), передаваемым снаружи в свойство `backend`. Читает свойства `javaCatalog` и `javaCatalogLoading`, вызывает `refreshJavaCatalog()`, `installJavaRuntime()` и `removeJavaRuntime()`. Объявлен в `QML_FILES` модуля (`CMakeLists.txt`); использует ресурс `images/Trash.svg`. Инстанцируется в диалоге настроек внутри [Main](Main.md) — сборка Java выбирается один раз для всего лаунчера, а не отдельно для каждой сборки Minecraft. Каталог приходит из C++ уже отсортированным — новые сверху, скачанные первыми, — поэтому окно только отбирает записи и порядок не трогает. Запись каталога содержит поля `id`, `label`, `kind` (тип сборки), `major` (мажорная версия Java числом), `installed`, `downloadable`, `lts`, `sizeMb`, `detail`, `coverage` и `search`. ## Иерархия и роль Корневой тип — `Dialog`: модальный, 720×480 px, нулевой внутренний отступ, закрывается по Escape и щелчку мимо, оформление тёмное со скруглением и акцентной рамкой. Содержимое — `RowLayout` из колонки типов шириной 170 px и области версий, разделённых линией. Каждый пункт колонки типов показывает название и пояснение мелким шрифтом, а под списком типов — подсказка о требовании выбранной версии игры, видимая только когда это требование известно. Область версий повторяет устройство окна выбора версии Minecraft: поле поиска сверху, флажок «Только скачанные» снизу, `ListView` между ними. Строка списка выше обычной (44 px), потому что содержит две строки текста: подпись сборки с меткой LTS и строку подробностей, где через точку собраны описание, покрытие версий игры, размер в мегабайтах и — при необходимости — предупреждение о том, что сборки не хватит. Пустое состояние объясняется текстом по центру и различает загрузку каталога, отсутствие соединения и пустой результат поиска. ## Свойства | Свойство | Тип | По умолчанию | Обязательное | Описание | |----------|-----|--------------|--------------|----------| | `backend` | `var` | — | **Да** | Экземпляр `LauncherBackend` — источник каталога Java, исполнитель установки и удаления. | | `selectedId` | `string` | `""` | Нет | Идентификатор выбранной сборки. Окно открывается с текущей сборкой, и по «Отмене» выбор возвращается к ней. | | `category` | `string` | `"java"` | Нет | Ключ активного типа сборок. Допустимые значения: `java` (сборки Mojang), `jdk` (Temurin с инструментами), `jre` (Temurin, только запуск). | | `filterText` | `string` | `""` | Нет | Текст поиска; сравнивается в нижнем регистре с полем `search` записи внутри активного типа. | | `installedOnly` | `bool` | `false` | Нет | Показывать только скачанные сборки. | | `requiredMajor` | `int` | `0` | Нет | Мажорная версия Java, ниже которой выбранной версии игры не запуститься. Значение `0` означает, что версия игры не выбрана и предупреждать не о чем: подсказка в колонке типов скрывается, пометка «слишком старая» не ставится. | | `categories` | `var` (только чтение) | список из трёх записей | Нет | Описание колонки типов: массив объектов с полями `key`, `title` и `hint`. Задаёт порядок пунктов и набор допустимых значений `category`. | | `visibleEntries` | `var` (только чтение) | вычисляется | Нет | Отобранные строки каталога: записи активного типа, прошедшие флажок «только скачанные» и текст поиска. Модель списка. | | `selectedEntry` | `var` (только чтение) | вычисляется | Нет | Полная запись выбранной сборки из каталога или `null`, если ничего не выбрано. Ищется по всему каталогу, а не по видимым строкам, поэтому выбор не теряется при смене фильтра. От неё зависят подпись в подвале и надпись на кнопке подтверждения. | ## Сигналы #### runtimeChosen(string runtimeId) Сборка Java подтверждена — кнопкой, двойным щелчком по строке или клавишей Enter в поле поиска. В параметре приходит идентификатор сборки. Обработчик записывает выбранную сборку в настройки лаунчера — сборка Java общая для всех сборок Minecraft, а требование конкретной версии игры влияет только на пометки в списке. Сигнал испускается и для ещё не скачанной сборки — загрузка при этом начинается сама, и обработчику ждать её завершения не нужно. ## Методы #### openFor(string runtimeId, int required) : void Открывает окно на переданной сборке. Запоминает её в `selectedId`, выставляет `requiredMajor` из второго аргумента (отсутствующее или нулевое значение означает «требование неизвестно»), очищает поиск, переключается на тип именно этой сборки, просит бэкенд обновить каталог и прокручивает список к выбранной строке. #### categoryOf(string runtimeId) : string Возвращает тип сборки по каталогу; для неизвестного идентификатора — `java`. #### indexOfSelected() : int Позиция выбранной сборки в `visibleEntries` или `-1`, если под текущим фильтром её не видно. #### revealSelected() : void Выставляет текущий индекс списка на выбранную сборку и прокручивает список так, чтобы строка оказалась по центру. #### acceptSelection() : void Подтверждает выбор. Ничего не делает, если `selectedEntry` пуст. Иначе испускает `runtimeChosen()`, а затем — если сборка не установлена, но доступна для скачивания, — вызывает `installJavaRuntime()` у бэкенда и закрывает окно. Именно поэтому кнопка подтверждения называется «Скачать» для отсутствующей сборки и «Выбрать» для уже скачанной. ## Взаимодействие с другими компонентами **Со стороны родителя.** Вызывающий код задаёт `backend`, открывает окно вызовом `openFor()` с текущей сборкой и требуемой мажорной версией Java (её отдаёт `requiredJavaMajor()` бэкенда) и подписывается на `runtimeChosen()`. **Со стороны бэкенда.** `javaCatalog` и `javaCatalogLoading` — привязки, пересчитывающие модель и текст пустого состояния при каждом обновлении каталога. `refreshJavaCatalog()` вызывается при открытии окна, `installJavaRuntime()` — при подтверждении отсутствующей сборки, `removeJavaRuntime()` — по щелчку на корзине в строке. Ход самой загрузки окно не показывает: за это отвечает плашка [ProgressPanel](ProgressPanel.md) в главном окне. **Удаление.** Корзина в строке доступна только у скачанных сборок; сборки весят по двести мегабайт, и удалять их нужно прямо здесь, иначе папка лаунчера растёт молча. Если удалена была выбранная сборка, выбор снимается. **Слишком старые сборки.** Сборка ниже требования игры остаётся доступной для выбора, но помечается в строке подробностей: она может пригодиться для другой сборки Minecraft. ## Пример использования ```qml JavaPickerDialog { id: javaPicker x: (window.width - width) / 2 y: (window.height - height) / 2 backend: launcherBackend onRuntimeChosen: (runtimeId) => settingsDialog.javaRuntimeId = runtimeId } MouseArea { anchors.fill: javaField onClicked: javaPicker.openFor(settingsDialog.javaRuntimeId, launcherBackend.requiredJavaMajor(launcherBackend.activeBuildIndex)) } ``` --- При создании этого документа использовался ИИ.