【问题标题】:Scanner(JTextfield) rather than Scanner(System.in)Scanner(JTextfield) 而不是 Scanner(System.in)
【发布时间】:2017-11-27 01:17:24
【问题描述】:

我想要一个 inputStream,它接受 JTextbox 的值并将其传递给 Scanner 对象。

       Scanner scan = new Scanner (System.in);
        String input = scan.nextLine();
        if (input.equalsIgnoreCase("New Match")) {
            try {
                newMatch(scan);
            } catch (FileNotFoundException e) {
                System.out.println("failed to load");
            } catch (ArithmeticException e) {

            }
        }
        if (input.equalsIgnoreCase("Load Match 1") || input.matches("1")){
            try {
                loadMatch(scan, "One");
            } catch (FileNotFoundException e) {
                System.out.println("failed to load");
            } catch (ArithmeticException e) {

            }
        }
    }

【问题讨论】:

  • idownvotedbecau.se/nocode 这感觉就像XY Problem。你为什么想做你想做的事?
  • "对不起,如果我的问题有点混乱。" -- 不要道歉,而是通过显示您的minimal reproducible example 代码并使其更加具体来“消除混淆”问题。
  • 添加了一小段代码。 @D B。感谢您的投票而不是帮助。希望有人在这里提供帮助。
  • 很抱歉您的时间有限,但这并不意味着您的问题很容易理解或符合本网站的指导方针。我正在尝试帮助您创建一个可以回答的更好的问题。攻击试图帮助你的人对你没有任何好处。
  • 我在 @D.B.并且不知道...我不知道您要解决什么问题或要问什么,所以也许他们是对的,也许是时候改进这个问题了感觉别人或删除它。 ...而且我认为自己在 Swing 方面的知识也相当丰富。

标签: java swing stream


【解决方案1】:

您可以使用PipedOutputStream (doc) 和PipedInputStream (doc) 创建单向管道,然后您可以使用该管道将输入从文本字段路由到Scanner。但是您仍然需要弄清楚如何捕获所有将发送到System.out 的输出并将其显示到您的 GUI,并与来自您的文本字段的“回显”输入很好地交织在一起。

不过,对于它的价值,我将分享一半解决方案的一点概念验证。该程序从JTextFieldScanner 读取“命令”,并对它们产生模拟“响应”; JTextArea 保留模拟“对话”的记录。输入的“命令”会自动记录到JTextArea,就像来自System.in 的输入会自动回显到System.out,我也明确地将它们回显到System.out。但是,我模拟的“响应”不是发给 System.out,而是直接发给 JTextArea`。

package test;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Scanner;
import javax.swing.JTextField;

public class PipeTest extends javax.swing.JFrame {

    public PipedInputStream pi; 
    private PipedOutputStream po;

    public PipeTest()
    {
        try {
            pi = new PipedInputStream();      // You write data into this end...
            po = new PipedOutputStream(pi);   // ,,, and read it back out at this end.
        } catch (IOException ioe) {
            System.out.println("Failed to initialize pipe: " + ioe.toString());
        }
        initComponents();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents()
    {

        jScrollPane1 = new javax.swing.JScrollPane();
        historyText = new javax.swing.JTextArea();
        jTextField1 = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        historyText.setColumns(20);
        historyText.setRows(5);
        jScrollPane1.setViewportView(historyText);

        jTextField1.setText("jTextField1");
        jTextField1.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                jTextField1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(21, 21, 21)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jTextField1)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 369, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 220, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 38, Short.MAX_VALUE)
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt)                                            
    {                                                
        JTextField tf = (JTextField) evt.getSource();
        String text = tf.getText();
        byte[] ca = (text + System.getProperty("line.separator")).getBytes();
        try {
            po.write(ca, 0, ca.length);
        } catch (IOException ex) {
            System.out.println("Failed to write to pipe: " + ex.toString());
        }
        historyText.append(text + "\n");
        tf.setText("");
    }                                           

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) throws IOException
    {
        PipeTest pt = new PipeTest();
        java.awt.EventQueue.invokeLater(() -> {
            pt.setVisible(true);
        });
        Scanner scn = new Scanner(pt.pi);
        while (scn.hasNextLine()) {
            String line = scn.nextLine();
            System.out.println(line);
            java.awt.EventQueue.invokeLater(() ->
            {
                pt.historyText.append("Response to " + line + "\n");
            });
        }
    }
    // Variables declaration - do not modify                     
    private javax.swing.JTextArea historyText;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextField jTextField1;
    // End of variables declaration                   
}

【讨论】:

  • 谢谢,但使用了扫描仪答案,因为它对我的截止日期更灵活。 pipedStreams 的性能更好,但给我带来了一些问题,因为它必须在多个线程上。
【解决方案2】:

我解释你的问题的方式是,你有一些现有的代码是建立在通过Scanner 的实例读取用户输入的基础上的。我认为您在问是否可以从JTextField 中提取文本并将其推送到已使用的Scanner 实例中。

如果上述理解是正确的,并且您的 Scanner 实例是从代码示例中的 System.in 读取的,那么我的答案是否定的,您不能完全做你想做的事.

但是,您可以在某种程度上接近您想要的。

这里有一些代码,每次调用actionPerformed 方法时都会创建一个新的Scanner,并将来自JTextField 的数据推送到Scanner,只需将文本字段中的文本传递到扫描仪的构造函数中即可。

public void actionPerformed(java.awt.event.ActionEvent evt) {
    scanner.close(); //Don't forget to close your scanner before you reassign it
    String data = jTextField1.getText();        
    scanner = new Scanner(data);
    //Just to illustrate the results I added a println here
    System.out.println(scanner.nextLine());               
}

【讨论】:

  • 嗯,我不太确定,因为他提到了有关“InputStream”的内容,这让我想知道他是否正在尝试重定向标准 I/O。好吧,我们将看看 OP 怎么说。
  • 另外我不同意您的 ActionPerformed 关闭扫描仪。打开它的代码块应该是负责关闭它的代码块。
  • 我同意通常打开块应该关闭它,但我觉得扫描仪处于更高/更大的范围内并且应该保持打开,以便它可以在代码的其他地方使用。
  • 那么他应该使用一个新的 Scanner 对象附加到方法-本地变量。具有此类副作用的方法可能会产生意想不到的不良后果。
  • 在我看来,扫描仪被用作传递用户输入的工具,我不喜欢这样,但考虑到 OP 希望尽量减少更改的影响,我试图离开那部分独自的。毫无疑问,这里有明确的改进/重构机会。
猜你喜欢
  • 2015-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-11
  • 2011-05-13
  • 2013-04-04
  • 1970-01-01
相关资源
最近更新 更多