statsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
//Return the string "stats" to gameLoop() as cmd
}
});
public void gameLoop(){
Scanner lineScanner = new Scanner(System.in);
cmd = "";
System.out.print(getBoard().printBoard(false));
while (!cmd.equals("quit")) {
System.out.print(">");
Scanner wordScanner = new Scanner(lineScanner.nextLine());
if (wordScanner.hasNext()) {
cmd = wordScanner.next();
if (cmd.equals("board")) {
System.out.print(getBoard().printBoard(false));
} else if (cmd.equals("ships")) {
System.out.print(getBoard().printBoard(true));
} else if (cmd.equals("help")) {
printHelp();
} else if (cmd.equals("stats")) {
printStats();
} else if (cmd.equals("fire")) {
if(fire(wordScanner)) {
printStats();
cmd = "quit";
}
} else if (cmd.equals("quit")) {
} else if (!cmd.equals("")) {
System.out.println(ILLEGAL_COMMAND);
}
}
}
}
Что я пытаюсь сделать, так это то, что когда пользователь нажимает кнопку statsButton, String cmd в gameLoop будет изменен на «stats». statsButton и gameLoop() находятся в двух разных классах. Кто-нибудь может дать мне представление, как это сделать? (Я пробовал pipedreader/pipedwriter), и я просто не могу понять это правильно.
* В основном я пытаюсь превратить свое консольное приложение в приложение с графическим интерфейсом, не меняя исходное консольное приложение.
Изменить: что я пробовал
Class textBased
PipedInputStream in = new PipedInputStream()
public void gameLoop(){
try{
in.connect(GUIclass.out);
Scanner lineScanner = new Scanner(in);`
Class GUIclass
PipedOutputStream out = new PipedOutputStream();
PrintWriter writer;
public GUIclass(){
final PrintWriter writer = new PrintWriter(out);
statsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
writer.println("stats");
}
});
Это то, что я пытался написать, но это, похоже, не работает.
4 ответа
Что касается
В основном я пытаюсь превратить свое консольное приложение в приложение с графическим интерфейсом, не меняя исходное консольное приложение..."
Мой совет прост: «Не делай этого».
Два приложения имеют совершенно разную структуру: одно линейное, другое управляемое событиями, и их нельзя напрямую перевести друг в друга. Лучше создать новую программу с графическим интерфейсом с нуля. Теперь, если ваше приложение без графического интерфейса содержит некоторые хорошо структурированные и управляемые объектно-ориентированные классы, то во что бы то ни стало используйте эти классы в разделе «модель» или логика вашего графического интерфейса, но не пытайтесь напрямую преобразовать поток программы одного типа. применения к другому.
Изменить
На основании ваших опубликованных требований:
«Вы должны иметь возможность играть в свою игру Battleship через свой графический интерфейс. Кроме того, текстовый интерфейс, который вы написали для проекта 1, должен по-прежнему «работать» и быть играбельным».
Поправьте меня, если я ошибаюсь, но держу пари, что здесь задействовано несколько классов, и только один из них — «текстовый интерфейс». Если это так, то используйте не интерфейсные классы в качестве модели вашего графического интерфейса, как я предложил выше, но не используйте текстовый интерфейс для чего-либо, связанного с графическим интерфейсом, и не пытайтесь эмулировать его в своем графическом интерфейсе.
Попросите консольное приложение создать экземпляр кнопки ActionListener и передать его пользовательскому интерфейсу. Когда событие действия запускается, слушатель сообщит консольному приложению, что это произошло. Метод в ActionListener скажет ему, что делать.
Я согласен с комментарием Hovercrafts (изменен на ответ).
Но в целом для подобных проблем я бы изменил сигнатуру метода вашего gameLoop(). Я хотел бы использовать:
public void gameLoop(Reader reader)
Затем вы можете передавать в цикл разные типы считывателей в зависимости от требований.
Для консоли вы можете сделать что-то вроде:
gameloop( new InputStreamReader( System.in ) );
Для графического интерфейса вы можете сделать что-то вроде:
gameLoop ( new StringReader("some text") );
Редактировать:
Не изменяя сигнатуру метода, вы можете перенаправить System.in на строку, полученную с помощью ActionListener:
public class Test
{
public static void main(String args[]) throws Exception
{
String text = "some text";
System.setIn( new ByteArrayInputStream( text.getBytes() ) );
// gameloop();
Scanner lineScanner = new Scanner(System.in);
System.out.println( lineScanner.nextLine() );
}
}
Если у вас что-то вроде этого:
class B {
public void gameLoop(){
..
}
}
А также
class A{
statsButton.addActionListener(new ActionListener() {
...
});
}
Вы можете объявить ссылку на B в A с помощью final . В этом случае он будет виден во внутреннем классе ActionListener
.
class A{
final B b = ...; //final variable is visible in inner class
statsButton.addActionListener(new ActionListener() {
b.gameLoop();
...
});
}
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.