【问题标题】:Writing to System.in from swing ui and reading the input with Scanner从 swing ui 写入 System.in 并使用 Scanner 读取输入
【发布时间】:2022-10-12 22:45:10
【问题描述】:

所以,我想知道Scanner 是否可以从System.in 读取,它是从JFrame 设置的。这就是我的意思。

这是我的WriteToSystemInJFrame 类),它是程序的 GUI 部分。

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;

public class WriteToSystemIn extends JFrame {
    private static class ChangeNumber implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            ByteArrayInputStream s = null;
            try {
                s = new ByteArrayInputStream("1\n".getBytes("UTF-8"));
            } catch (UnsupportedEncodingException ex) {
                throw new RuntimeException(ex);
            }
            System.setIn(s);

        }
    }
    WriteToSystemIn() {
        JButton button = new JButton("try click it m8");
        button.addActionListener(new ChangeNumber());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(button);
        this.setVisible(true);
        this.pack();
    }
}

这就是程序的Main 函数。

import java.util.Scanner;

public class Main {
    private static class MainRunnable implements Runnable {

        @Override
        public void run() {
            new WriteToSystemIn();
        }
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new MainRunnable());

        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        System.out.println(s);

        System.out.println("ended");
    }
}

因此,当从WriteToSystemIn 按下按钮时,它应该将“1\n”写入System.in 以供Scanner 读取。

但是,它没有这样做。它不会读取任何内容。打印到System.out 没有问题,所以我认为这不是问题,但显然我错了。所以,我在这里想知道,我在这里做错了什么吗?或者,我是否正在尝试做一些不可能的事情?

【问题讨论】:

    标签: java swing java.util.scanner system.in


    【解决方案1】:

    当您调用new Scanner(System.in); 时,您为扫描仪提供了对当前设置为System.in 的流的引用。当您稍后调用System.setIn(s); 时,您只需更改存储在System.in 中的值。已经提供给扫描仪的引用没有改变,它仍然指向原始的System.in

    您需要确保在初始化扫描仪之前调用了System.setIn(s);。您可以向这两个语句添加调试打印以验证它们的执行顺序。这在您学习多线程编程时会很有帮助。

    System.out.println("Resetting System.in");
    System.setIn(s);
    
    ...
    
    System.out.println("Creating scanner");
    Scanner scanner = new Scanner(System.in);
    

    【讨论】:

      【解决方案2】:

      从@Torben 的answer 继续,您需要创建类Main wait 直到单击JButton(在类WriteToSystemIn)。单击JButton 后,您可以通过notify Main 停止等待并继续执行。

      班级Main

      import java.util.Scanner;
      
      public class Main {
          private static class MainRunnable implements Runnable {
              private Main main;
      
              public MainRunnable(Main main) {
                  this.main = main;
              }
      
              @Override
              public void run() {
                  new WriteToSystemIn(main);
              }
          }
      
          public static void main(String[] args) {
              Main main = new Main();
              javax.swing.SwingUtilities.invokeLater(new MainRunnable(main));
              synchronized (main) {
                  try {
                      main.wait();
                      Scanner scanner = new Scanner(System.in);
                      String s = scanner.nextLine();
                      System.out.println(s);
                  }
                  catch (InterruptedException x) {
                      x.printStackTrace();
                  }
              }
              System.out.println("ended");
          }
      }
      

      班级WriteToSystemIn

      import javax.swing.*;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.io.ByteArrayInputStream;
      import java.io.UnsupportedEncodingException;
      
      public class WriteToSystemIn extends JFrame {
      
          private static class ChangeNumber implements ActionListener {
              private Main main;
      
              public ChangeNumber(Main main) {
                  this.main = main;
              }
      
              @Override
              public void actionPerformed(ActionEvent e) {
                  ByteArrayInputStream s = null;
                  try {
                      s = new ByteArrayInputStream("1
      ".getBytes("UTF-8"));
                      System.setIn(s);
                      synchronized (main) {
                          main.notifyAll();
                      }
                  } catch (UnsupportedEncodingException ex) {
                      throw new RuntimeException(ex);
                  }
              }
          }
      
          WriteToSystemIn(Main main) {
              JButton button = new JButton("try click it m8");
              button.addActionListener(new ChangeNumber(main));
              this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              this.add(button);
              this.setVisible(true);
              this.pack();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-12-17
        • 2013-04-04
        • 2014-10-08
        • 1970-01-01
        • 2017-04-06
        • 2015-01-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多