#java #swing #user-interface #console-application #actionlistener
#java #swing #пользовательский интерфейс #консольное приложение #actionlistener
Вопрос:
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, строка cmd в gameLoop будет изменена на «статистика». 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");
}
});
это то, что я пытался написать, но, похоже, это не работает.
Комментарии:
1. перекрестная публикация daniweb.com/software-development/java/threads/393562
Ответ №1:
Что касается
По сути, я пытаюсь превратить свое консольное приложение в приложение с графическим интерфейсом без изменения исходного консольного приложения … «
Мой совет прост: «не делай этого».
Два приложения имеют совершенно разную структуру, одно линейное, другое управляемое событиями, и не могут быть напрямую переведены друг в друга. Лучше создать новую программу с графическим интерфейсом с нуля. Теперь, если ваше приложение без графического интерфейса содержит несколько хорошо структурированных и управляемых объектно-ориентированных классов, то непременно используйте эти классы в разделе «модель» или логика вашего графического интерфейса, но не пытайтесь напрямую транслировать программный поток одного типа приложений в другой.
Редактировать
На основе ваших опубликованных требований:
«Вы должны иметь возможность играть в свою игру Battleship через свой графический интерфейс. Кроме того, текстовый интерфейс, который вы написали для project 1, все еще должен «работать» и быть воспроизводимым.»
Поправьте меня, если я ошибаюсь, но держу пари, что здесь задействовано несколько классов, и только один из них — «интерфейс на основе текста». Если это так, то используйте не интерфейсные классы в качестве модели вашего GUI, как я предложил выше, но не используйте текстовый интерфейс для всего, что связано с GUI, и не пытайтесь эмулировать его в вашем GUI.
Комментарии:
1. Я понимаю, что не нужно этого делать, я также больше привык этого не делать. Однако в этом случае в спецификации указано, что я должен это сделать.
2. «Вы должны иметь возможность играть в свою игру Battleship через свой графический интерфейс. Кроме того, текстовый интерфейс, который вы написали для project 1, все еще должен «работать» и быть воспроизводимым.»
3. @user1043625: пожалуйста, смотрите обновление к моему ответу выше. Также рассмотрите возможность редактирования своего профиля и присвоения себе менее общего названия форума, надеюсь, лучшего, чем мое. 🙂
4. У меня действительно есть несколько классов, и все выходные данные обрабатываются одним классом. Однако нам говорят передавать входные данные из графического интерфейса пользователя в консоль вместо создания чего-либо отдельного.
5. @user1043625: нет, вам не говорили передавать входные данные из графического интерфейса пользователя в консоль, если вы получили именно такие инструкции. Все, что в нем указано, это играть в игру через графический интерфейс пользователя, то есть использовать доступные вам классы, и в консольную игру все равно можно играть. Это означает, что вы не должны изменять неконсольные классы таким образом, чтобы сделать интерфейс консоли неиграбельным. Это большая разница. Я по-прежнему придерживаюсь того, что я заявляю в своем ответе.
Ответ №2:
Попросите консольное приложение создать экземпляр button ActionListener и передать его в пользовательский интерфейс. При запуске события action прослушиватель сообщит консольному приложению, что это произошло. Метод в ActionListener подскажет ему, что делать.
Комментарии:
1. Я действительно не понимаю, можете ли вы объяснить на нескольких простых примерах? Кроме того, я думаю, что это привело бы к изменению исходного класса, чего я не предполагаю делать.
2. «Не предполагается выполнять» — почему бы и нет?
3. «Вы должны иметь возможность играть в свою игру Battleship через свой графический интерфейс. Кроме того, текстовый интерфейс, который вы написали для project 1, все еще должен «работать» и быть воспроизводимым.»
4. Ваши текстовые интерфейсы и пользовательский интерфейс GUI должны быть разделены. Я предполагаю, что вы должны иметь возможность выбирать между этими двумя. Это будет означать модификацию оригинала. То, что ваш профессор пытается сделать, это заставить вас полностью отделить игровую логику от презентации. Логика вашей игры должна быть передана так, как ей нужно. Ему не обязательно знать, получает ли это текст или графический интерфейс пользователя.
Ответ №3:
Я согласен с комментарием 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() );
}
}
Комментарии:
1. Я добавил кое-что выше, чтобы показать вам, что я пробовал, похоже, у меня не работает. Не уверен, что я делаю неправильно.
2. @user1043625, я не понимаю вашего комментария. Почему бы вам не попробовать то, что я предложил, начиная с его рабочего кода. Я не предлагал использовать конвейерный поток, поэтому я не знаю, что не так с вашим кодом.
Ответ №4:
Если у вас есть что-то вроде этого :
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();
...
});
}
Комментарии:
1. У меня действительно есть нечто похожее на то, что вы написали. Но проблема в том, как мне изменить строку cmd при нажатии кнопки? b.gameLoop().cmd не будет работать, и я не думаю, что мне все равно следует это делать.