jTextArea作为IO控制台

如何将用户输入(仅用户输入)发送到输出流?

我目前正在使用密钥列表,

jTextArea console = new jTextArea; console.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent e){ //save the last lines for console to variable input if(e.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER){ try { int line = console.getLineCount() -2; int start = console.getLineStartOffset(line); int end = console.getLineEndOffset(line); input = console.getText(start, end - start); send = true; } catch (Exception e1) { e1.printStackTrace(); } } } });` 

如您所见,当用户按下Enter键时,控制台的整个最后一行是textarea。

我想要发生的是,只发送用户输入,而不是整个最后一行。 任何帮助将不胜感激。

好的,这是我的想法……

基本思想是我们想要跟踪“用户”输入和“处理”输出。

基本上我所做的就是设置它,这样当进程终止时,我们计算文档中插入符号的当前位置,并将其标记为用户输入的起始位置。

此示例不包括将输出写入进程,您可以将其滑入;)

 import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.text.BadLocationException; import org.w3c.dom.ls.LSException; public class QuickTerminal { public static void main(String[] args) { new QuickTerminal(); } public QuickTerminal() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new ConsolePane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public interface CommandListener { public void commandOutput(String text); public void commandCompleted(String cmd, int result); public void commandFailed(Exception exp); } public class ConsolePane extends JPanel implements CommandListener { private JTextArea textArea; private int userInputStart = 0; private Command cmd; public ConsolePane() { cmd = new Command(this); setLayout(new BorderLayout()); textArea = new JTextArea(20, 30); add(new JScrollPane(textArea)); textArea.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { int range = textArea.getCaretPosition() - userInputStart; try { String text = textArea.getText(userInputStart, range).trim(); System.out.println("[" + text + "]"); userInputStart += range; if (!cmd.isRunning()) { cmd.execute(text); } else { } } catch (BadLocationException ex) { Logger.getLogger(QuickTerminal.class.getName()).log(Level.SEVERE, null, ex); } } else { // if (!cmd.isRunning()) { // cmd.send(...); // } } } }); } @Override public void commandOutput(String text) { SwingUtilities.invokeLater(new AppendTask(textArea, text)); } @Override public void commandFailed(Exception exp) { SwingUtilities.invokeLater(new AppendTask(textArea, "Command failed - " + exp.getMessage())); } @Override public void commandCompleted(String cmd, int result) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { int pos = textArea.getCaretPosition(); System.out.println("pos = " + pos + "; length = " + textArea.getText().length()); textArea.setCaretPosition(textArea.getText().length()); userInputStart = pos; } }); } } public class AppendTask implements Runnable { private JTextArea textArea; private String text; public AppendTask(JTextArea textArea, String text) { this.textArea = textArea; this.text = text; } @Override public void run() { textArea.append(text); } } public class Command { private CommandListener listener; private ProcessRunner runner; public Command(CommandListener listener) { this.listener = listener; } public boolean isRunning() { return runner != null && runner.isAlive(); } public void execute(String cmd) { if (!cmd.trim().isEmpty()) { List values = new ArrayList<>(25); if (cmd.contains("\"")) { while (cmd.contains("\"")) { String start = cmd.substring(0, cmd.indexOf("\"")); cmd = cmd.substring(start.length()); String quote = cmd.substring(cmd.indexOf("\"") + 1); cmd = cmd.substring(cmd.indexOf("\"") + 1); quote = quote.substring(0, cmd.indexOf("\"")); cmd = cmd.substring(cmd.indexOf("\"") + 1); if (!start.trim().isEmpty()) { String parts[] = start.trim().split(" "); values.addAll(Arrays.asList(parts)); } values.add(quote.trim()); } if (!cmd.trim().isEmpty()) { String parts[] = cmd.trim().split(" "); values.addAll(Arrays.asList(parts)); } for (String value : values) { System.out.println("[" + value + "]"); } } else { if (!cmd.trim().isEmpty()) { String parts[] = cmd.trim().split(" "); values.addAll(Arrays.asList(parts)); } } runner = new ProcessRunner(listener, values); } } public void send(String cmd) { // Send user input to the running process... } } public class ProcessRunner extends Thread { private List cmds; private CommandListener listener; public ProcessRunner(CommandListener listener, List cmds) { this.cmds = cmds; this.listener = listener; start(); } @Override public void run() { try { System.out.println("cmds = " + cmds); ProcessBuilder pb = new ProcessBuilder(cmds); pb.redirectErrorStream(); Process p = pb.start(); StreamReader reader = new StreamReader(listener, p.getInputStream()); // Need a stream writer... int result = p.waitFor(); // Terminate the stream writer reader.join(); listener.commandCompleted(null, result); } catch (Exception exp) { exp.printStackTrace(); } } } public class StreamReader extends Thread { private InputStream is; private CommandListener listener; public StreamReader(CommandListener listener, InputStream is) { this.is = is; this.listener = listener; start(); } @Override public void run() { try { int value = -1; while ((value = is.read()) != -1) { listener.commandOutput(Character.toString((char) value)); } } catch (IOException exp) { exp.printStackTrace(); } } } } 

PS-我在我的Mac上运行它,所以你可能需要为Windows调用“cmd”…;)

PPS-这是一个不完整的例子,如果它不是凌晨1点我可能填写它,但是,这并不能阻止用户按下超出最后已知用户输入位置的空格。 如果我要修复此问题,我会使用DocumentFilter并在用户位置之前简单地“保护”所有文本,禁止用户将其删除

更新了“Protected DocumentFilter”示例

DocumentFilter的受保护区域添加了“受保护” DocumentFilter ,不再允许用户编辑该区域。

 import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.text.AbstractDocument; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.DocumentFilter; public class QuickTerminal { public static void main(String[] args) { new QuickTerminal(); } public QuickTerminal() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new ConsolePane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public interface CommandListener { public void commandOutput(String text); public void commandCompleted(String cmd, int result); public void commandFailed(Exception exp); } public class ConsolePane extends JPanel implements CommandListener, UserInput { private JTextArea textArea; private int userInputStart = 0; private Command cmd; public ConsolePane() { cmd = new Command(this); setLayout(new BorderLayout()); textArea = new JTextArea(20, 30); ((AbstractDocument)textArea.getDocument()).setDocumentFilter(new ProtectedDocumentFilter(this)); add(new JScrollPane(textArea)); textArea.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { int range = textArea.getCaretPosition() - userInputStart; try { String text = textArea.getText(userInputStart, range).trim(); System.out.println("[" + text + "]"); userInputStart += range; if (!cmd.isRunning()) { cmd.execute(text); } else { } } catch (BadLocationException ex) { Logger.getLogger(QuickTerminal.class.getName()).log(Level.SEVERE, null, ex); } } else { // if (!cmd.isRunning()) { // cmd.send(...); // } } } }); } @Override public void commandOutput(String text) { SwingUtilities.invokeLater(new AppendTask(textArea, text)); } @Override public void commandFailed(Exception exp) { SwingUtilities.invokeLater(new AppendTask(textArea, "Command failed - " + exp.getMessage())); } @Override public void commandCompleted(String cmd, int result) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { int pos = textArea.getCaretPosition(); System.out.println("pos = " + pos + "; length = " + textArea.getText().length()); textArea.setCaretPosition(textArea.getText().length()); userInputStart = pos; } }); } @Override public int getUserInputStart() { return userInputStart; } } public interface UserInput { public int getUserInputStart(); } public class AppendTask implements Runnable { private JTextArea textArea; private String text; public AppendTask(JTextArea textArea, String text) { this.textArea = textArea; this.text = text; } @Override public void run() { textArea.append(text); } } public class Command { private CommandListener listener; private ProcessRunner runner; public Command(CommandListener listener) { this.listener = listener; } public boolean isRunning() { return runner != null && runner.isAlive(); } public void execute(String cmd) { if (!cmd.trim().isEmpty()) { List values = new ArrayList<>(25); if (cmd.contains("\"")) { while (cmd.contains("\"")) { String start = cmd.substring(0, cmd.indexOf("\"")); cmd = cmd.substring(start.length()); String quote = cmd.substring(cmd.indexOf("\"") + 1); cmd = cmd.substring(cmd.indexOf("\"") + 1); quote = quote.substring(0, cmd.indexOf("\"")); cmd = cmd.substring(cmd.indexOf("\"") + 1); if (!start.trim().isEmpty()) { String parts[] = start.trim().split(" "); values.addAll(Arrays.asList(parts)); } values.add(quote.trim()); } if (!cmd.trim().isEmpty()) { String parts[] = cmd.trim().split(" "); values.addAll(Arrays.asList(parts)); } for (String value : values) { System.out.println("[" + value + "]"); } } else { if (!cmd.trim().isEmpty()) { String parts[] = cmd.trim().split(" "); values.addAll(Arrays.asList(parts)); } } runner = new ProcessRunner(listener, values); } } public void send(String cmd) { // Send user input to the running process... } } public class ProcessRunner extends Thread { private List cmds; private CommandListener listener; public ProcessRunner(CommandListener listener, List cmds) { this.cmds = cmds; this.listener = listener; start(); } @Override public void run() { try { System.out.println("cmds = " + cmds); ProcessBuilder pb = new ProcessBuilder(cmds); pb.redirectErrorStream(); Process p = pb.start(); StreamReader reader = new StreamReader(listener, p.getInputStream()); // Need a stream writer... int result = p.waitFor(); // Terminate the stream writer reader.join(); listener.commandCompleted(null, result); } catch (Exception exp) { exp.printStackTrace(); } } } public class StreamReader extends Thread { private InputStream is; private CommandListener listener; public StreamReader(CommandListener listener, InputStream is) { this.is = is; this.listener = listener; start(); } @Override public void run() { try { int value = -1; while ((value = is.read()) != -1) { listener.commandOutput(Character.toString((char) value)); } } catch (IOException exp) { exp.printStackTrace(); } } } public class ProtectedDocumentFilter extends DocumentFilter { private UserInput userInput; public ProtectedDocumentFilter(UserInput userInput) { this.userInput = userInput; } public UserInput getUserInput() { return userInput; } @Override public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { if (offset >= getUserInput().getUserInputStart()) { super.insertString(fb, offset, string, attr); } } @Override public void remove(FilterBypass fb, int offset, int length) throws BadLocationException { if (offset >= getUserInput().getUserInputStart()) { super.remove(fb, offset, length); //To change body of generated methods, choose Tools | Templates. } } @Override public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { if (offset >= getUserInput().getUserInputStart()) { super.replace(fb, offset, length, text, attrs); //To change body of generated methods, choose Tools | Templates. } } } } 

我建议当释放任何其他键时,如果starflag = true,则存储start,并按照你的说法将startflag设置为false,当实际按下“enter”时,你可以执行startflag = true; 并将结尾存储为getCaretPosition()。

我对你的意图的理解有点模糊,但这里有我的想法:如果你在控制台中进行了整个“对话”,并且你想要所有的用户条目,那么你可以简单地使用一个ArrayList userinputs ,而不是start = console.getCaretPosition(),你可以做userinputs.add(new Point(console.getCaretPosition(), – 1)); 然后当用户结束他的输入时(或在STDOUT发送输入之前),执行userinputs.get(userinputs.size() – 1).y = console.getCaretPosition()(或者你可以存储一个临时点,并且只添加指出它已经完成 – 当它也结束时。)

如果您在按下回车键时将用户输入发送到输出,那么我看不出还需要什么,而不是上面的简单代码,基本上这样工作:

 public void keyReleased(KeyEvent e){ if(e.getKeyCode() == KeyEvent.VK_ENTER){ startflag = true; //Just get the text from the start(stored below), and up until where the caret is now, as the users output. }else{ if(startflag){ start = console.getCaretPosition() startflag = false; } } }