您可以使用PipedOutputStream (doc) 和PipedInputStream (doc) 创建单向管道,然后您可以使用该管道将输入从文本字段路由到Scanner。但是您仍然需要弄清楚如何捕获所有将发送到System.out 的输出并将其显示到您的 GUI,并与来自您的文本字段的“回显”输入很好地交织在一起。
不过,对于它的价值,我将分享一半解决方案的一点概念验证。该程序从JTextField 到Scanner 读取“命令”,并对它们产生模拟“响应”; 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
}