Интеграция Swing в простую текстовую приключенческую игру
=========================================================

Я довольно плохо знаком с некоторыми промежуточными понятиями в Java. Недавно я создал текстовую приключенческую игру под названием DazzleQuest, которая полностью работает в консоли разработчика / терминале. В нем участвуют мои друзья в качестве персонажей, поэтому я хотел показать им это и получить опыт работы с Java, передав функциональность командной строки и вывод с консоли на простой интерфейс Swing, состоящий из`JTextArea` чтобы показать результат игры и`JTextField`, с`ActionListener`, чтобы обрабатывать команды от пользователя.

Мой основной`DazzleQuest` класс содержит методы, называемые`run()` а также`handleCommand()`Я считаю, что мне нужно интегрировать с моим`Frame` класс и его подкласс`TextFieldHandler` [который расширяется`ActionListener`].**Мне вообще интересно, как лучше интегрировать эти методы и классы.** Мои нынешние попытки сбивают с толку, и, хотя у меня есть базовые знания о том, как заставить различные классы и методы общаться, это является предварительным.

Извиняюсь за многословность и отсутствие конкретики. Я хотел бы поделиться своим кодом, но не уверен, сколько и что именно дать. Если вы думаете, что можете ответить на мой вопрос, но вам нужен пример того, что у меня есть, скажите, пожалуйста. Даже псевдокод в качестве ответа был бы оценен. Спасибо! Понимание этого может быть очень полезным для моего образования в качестве программиста.

РЕДАКТИРОВАТЬ: Вот упрощенные примеры моего кода из версии игры, которая полностью работает в консоли разработчика. Это мой основной класс`DazzleQuest`:

А вот мой ток`JFrame` настройки, в`Frame` учебный класс:

Я знаю, как распечатать вывод на`JTextArea` вместо консоли. Моя проблема в том, как именно получить`handleCommand()` работать с`actionPerformed()` в`Frame` класс, или я должен установить слушателя действия в основном классе или что-то в этом роде. Любые примеры реализации будут с благодарностью.

Еще раз спасибо за все, что вы можете сказать мне!

<https://stackoverflow.com/help/mcve> о том, как помочь нам помочь вам.

Теперь, учитывая, что вы не предоставили никакого кода (пока!), Дающего советы о том, как вы должны структурировать свою программу, это немного сложно. Но я все равно попробую и, возможно, отредактирую ответ, когда вы предоставите MWE.

В твоем случае,`JTextArea` это действительно просто фантазия`System.out.print` так как вы будете использовать его только для отображения текста, который выводит ваша приключенческая игра (если я вас правильно понимаю). Таким образом, вы можете написать метод, который принимает строку, и этот метод добавит эту строку к вашему`JTextArea`, Затем просто замените ваши текущие выходные строки этим методом.

Тогда у вас есть`JTextField` который вы хотите заменить своим (я предполагаю)`Scanner(System.in)` с. Я предполагаю, что вы знаете, как настроить слушатель действия, который отвечает на`Enter` или`submit`-кнопка. Как это настроить, не так уж и странно, и многие гиды рассказывают, как это сделать.<https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html> дает хороший пример.

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

Итак, применимо к именам методов, которые вы разместили. Я предполагаю`run()` это то, где вы начинаете. Поскольку у вас есть вывод, который вы всегда хотите отобразить, вы можете передать`interface` здесь есть метод`print(string)` (или тому подобное), который должен быть методом, который печатает текст на любом текстовом элементе, используемом для отображения текста, будь то`System.out` или же`JTextArea`,`run()` метод никогда не должен знать.`handleCommand()` также следует просто принять значение (я предполагаю строку) и обработать его так, как оно должно, независимо от того, кто или что вызвал его.

У меня проблемы с тем, чтобы дать вам больше советов без кода. Но моя общая рекомендация: не смешивайте логику представления с бизнес-логикой. И предоставьте каждому методу как можно меньше информации, потому что предоставление им большего, чем им действительно нужно, обычно приводит к менее гибкому процессу и структуре.

РЕДАКТИРОВАТЬ теперь, когда был добавлен некоторый код.

Я знаю, как распечатать вывод на JTextArea, а не на консоль. Моя проблема заключается в том, как именно заставить handleCommand () работать с actionPerformed () в классе Frame

Перейти с`actionPerformed()` подход. Я рекомендую это, потому что вам не придется так сильно беспокоиться, если вы решите`Thread` Ваше приложение когда-нибудь в будущем (мультиплеер?).<https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html> дает хорошую информацию о том, как написать своему слушателю. Но я также дам вам код предложения.

А потом переписать свой`run()` метод

Так что теперь у вас очень маленький`run()` метод, который не имеет реальной привязки ни к логике, ни к дисплею.`ui.print(str)` это метод, который ваш`UI` учебный класс (`Frame` в вашем случае), который просто добавляет то, что когда-либо строка отправляется в его область рисования, будь то`System.out` или`JTextArea`.

`commandHandler` новый. Вот где должна быть ваша игровая логика. У него есть метод`handle(string)` какой твой старый`handleCommand(string)`, Оно имеет`continue()` метод, который возвращает логическое значение. Логическое значение должно быть установлено в true, когда вы хотите, чтобы история продолжалась, например, когда пользователь вводит команду. И наконец`events()` (что является плохим именем), которое возвращает то, что произошло с момента отправки последней команды, и дает пользователям варианты того, что делать дальше. Я не реализовал это, так как просто хочу дать вам концепцию. Пользовательский интерфейс не выполняет никакой логической обработки.`run()` метод ничего не ожидает, он просто проверяет,`continue()` правда.`commandHandler` там, где все бизз.

Теперь у вас есть бесконечный цикл. Так что, если у вас возникнут проблемы с производительностью, вы можете изучить`Thread`, Эта модель должна поддерживать переход к ней.