Передача ввода от JButton к консоли - PullRequest
2 голосов
/ 13 ноября 2011
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 в 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 ]

4 голосов
/ 13 ноября 2011

Относительно

Я пытаюсь превратить свое консольное приложение в приложение с графическим интерфейсом без изменения исходного консольного приложения ... "

Мой совет прост: "не делай этого".

Два приложения имеют совершенно разную структуру, одно из которых является линейным, другое - управляемым событиями и не может быть напрямую переведено друг в друга. Лучше создать новую программу с графическим интерфейсомс нуля. Теперь, если ваше не-GUI-приложение содержит некоторые хорошо структурированные и поведенческие объектно-ориентированные классы, то непременно используйте эти классы в разделе «модель» или логике вашего GUI, но не пытайтесь напрямую перевестипоток программ одного типа приложения к другому.

Редактировать
В зависимости от опубликованных вами требований:

"Вы должны иметь возможность играть на своемМорской бой через ваш графический интерфейс.Кроме того, текстовый интерфейс, который вы написали для проекта 1, все еще должен «работать» и быть пригодным для игры ».

Поправьте меня, если я ошибаюсь, но держу пари, что у вас естьздесь задействовано несколько классов, и только один из них является «текстовым интерфейсом». Если это так, то используйте не входные классы в качестве модели вашего графического интерфейса, как я предлагал выше, но не используйте текстовый интерфейс.основанный интерфейс для всего, что связано с GUI, и не пытайтесь эмулировать его в вашем GUI.

3 голосов
/ 13 ноября 2011

Я согласен с комментарием Hovercrafts (изменен на ответ).

Но в целом для подобных проблем я бы изменил сигнатуру метода вашего gameLoop ().Я бы использовал:

public void gameLoop(Reader reader)

Тогда вы можете передавать различные типы считывателей в цикл в зависимости от требований.

Для консоли вы можете сделать что-то вроде:

gameloop( new InputStreamReader( System.in ) );

Для графического интерфейса вы можете сделать что-то вроде:

gameLoop ( new StringReader("some text") );

Редактировать:

Без изменения сигнатуры метода вы можете перенаправить System.in для получения из String, полученной 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() );
    }
}
3 голосов
/ 13 ноября 2011

Попросите консольное приложение создать экземпляр кнопки ActionListener и передать ее в пользовательский интерфейс. Когда событие action сработает, слушатель сообщит консольному приложению, что это произошло. Метод в ActionListener скажет ему, что делать.

1 голос
/ 13 ноября 2011

Если у вас есть что-то вроде этого:

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();
             ...
        }); 
}
...