Java 将输入从JButton传递到控制台

Java 将输入从JButton传递到控制台,java,swing,user-interface,console-application,actionlistener,Java,Swing,User Interface,Console Application,Actionlistener,我试图做的是,当用户单击statsButton时,gameLoop中的字符串cmd将更改为“stats”。statsButton和gameLoop()位于两个不同的类中。谁能告诉我怎么做?(我尝试了pipedreader/pipedwriter),但我似乎做不好 *我基本上是想把我的控制台应用程序变成一个GUI应用程序,而不改变原来的控制台应用程序 编辑:我试过的 statsButton.addActionListener(new ActionListener() { p

我试图做的是,当用户单击statsButton时,gameLoop中的字符串cmd将更改为“stats”。statsButton和gameLoop()位于两个不同的类中。谁能告诉我怎么做?(我尝试了pipedreader/pipedwriter),但我似乎做不好

*我基本上是想把我的控制台应用程序变成一个GUI应用程序,而不改变原来的控制台应用程序

编辑:我试过的

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

        }
    }

这就是我试图写的,但似乎不起作用

让控制台应用程序实例化按钮ActionListener并将其传递给UI。当触发操作事件时,侦听器将告诉控制台应用程序它发生了。ActionListener中的方法将告诉它该做什么。

我基本上是想把我的控制台应用程序变成一个GUI应用程序,而不改变原来的控制台应用程序……”

我的建议很简单:“不要这样做”

这两个应用程序具有完全不同的结构,一个是线性的,另一个是事件驱动的,并且不能直接相互转换。最好从头开始创建一个新的GUI程序。现在,如果您的非GUI应用程序包含一些结构良好、行为良好的面向对象类,请务必在中使用这些类GUI的“模型”或逻辑部分,但不要试图直接将一种应用程序的程序流转换为另一种

编辑
根据您发布的要求:


“您应该能够通过GUI界面玩战舰游戏。此外,您为project 1编写的基于文本的前端应该仍然“工作”并且可以播放。”


如果我错了,请纠正我,但我打赌这里涉及到几个类,其中只有一个是“基于文本的前端”“。如果是这样,那么按照我上面的建议,使用非前端类作为GUI的模型,但不要将基于文本的前端用于任何与GUI相关的内容,也不要尝试在GUI中模拟它。

如果您有类似的功能:

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");
             }
          }); 

您可以使用final声明对A中B的引用。在这种情况下,它将在内部类
ActionListener
中可见

class A{

  statsButton.addActionListener(new ActionListener() {
            ...
        }); 
}

我同意气垫船的评论(改为回复)

但一般来说,对于这样的问题,我会更改gameLoop()的方法签名。我将使用:

class A{
  final B b = ...; //final variable is visible in inner class
  statsButton.addActionListener(new ActionListener() {
            b.gameLoop();
             ...
        }); 
}
然后,您可以根据需要将不同类型的读取器传递给循环

对于控制台,您可以执行以下操作:

public void gameLoop(Reader reader)
gameloop( new InputStreamReader( System.in ) );
对于GUI,您可以执行以下操作:

public void gameLoop(Reader reader)
gameloop( new InputStreamReader( System.in ) );
编辑:

在不更改方法签名的情况下,您可以重定向System.in,使其来自ActionListener检索到的字符串:

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

我不太明白,你能用一些简单的例子解释一下吗?此外,我认为这将修改我不想做的原始类。“不应该做”-为什么不?“您应该能够通过GUI界面玩战舰游戏。此外,您为project 1编写的基于文本的前端应该仍然“工作”并且可以玩。“基于文本的UI和GUI UI需要分开。”。我想你应该能够在两者之间做出选择。这将意味着对原作的修改。你的教授想让你把游戏逻辑和演讲完全分开。你的游戏逻辑应该被传递给它所需要的东西。它不必知道是文本还是GUI得到了它。我理解不这样做,我也更习惯不这样做。然而,在这种情况下,规范中规定我必须这样做。“你应该能够通过GUI界面玩你的战舰游戏。此外,你为项目1编写的基于文本的前端应该仍然可以“工作”并且可以玩。”@user1043625:请参阅上面对我答案的更新。此外,考虑编辑你的个人资料,并给自己一个不太通用的论坛名称,希望有一个比我更好。我有几个类,所有的输出都由一个类处理。但是,我们被告知将输入从GUI传递到控制台,而不是创建任何单独的内容。@user1043625:不,如果您收到的是这些指令,您没有被告知将输入从GUI传递到控制台。它所说的一切都是通过GUI玩游戏,这意味着使用可用的类,并且控制台游戏应该仍然可以玩。这意味着您不应该以使控制台接口无法运行的方式更改非控制台类。这是一个很大的区别。我仍然坚持我在回答中所说的。我确实有一些类似于你所写的东西。但问题是,当我单击按钮时,如何更改字符串cmd?b、 gameLoop().cmd不起作用,我也不认为我应该这样做。我在上面添加了一些东西来向您展示我所做的尝试,但似乎对我不起作用。不知道我做错了什么。@user1043625,我不明白你的意思。你为什么不试试我的建议,因为它的工作代码。我没有建议使用管道流,所以我不知道你的代码有什么问题