0

ユーザーの入力(ユーザー入力のみ)を出力ストリームに送信するにはどうすればよいですか?

私は現在キーリスナーを使用しています、

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が表示されます。

私がしたいのは、最後の行全体ではなく、ユーザー入力のみを送信することです。どんな助けでも大歓迎です。

4

2 に答える 2

4

さて、これが私の考えです...

基本的な考え方は、「ユーザー」入力と「プロセス」出力を追跡したいということです。

基本的に、プロセスが終了したときに、ドキュメント内のカレットの現在の位置を計算し、それをユーザー入力の開始位置としてマークするように設定しました。

この例には、プロセスへの出力の書き込みは含まれていません。スライドして;)

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<String> 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<String> cmds;
        private CommandListener listener;

        public ProcessRunner(CommandListener listener, List<String> 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、ユーザーの位置の前にあるすべてのテキストを単に「保護」し、ユーザーがテキストを削除できないようにします。

「ProtectedDocumentFilter」の例で更新

ユーザーが編集を許可されないようにDocumentFilterする保護領域に「保護」を追加しました。Document

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<String> 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<String> cmds;
        private CommandListener listener;

        public ProcessRunner(CommandListener listener, List<String> 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.
            }
        }
    }
}
于 2013-02-22T13:13:08.180 に答える
0

他のキーがリリースされたときに、starflag = trueの場合、開始を保存し、前述のようにstartflagをfalseに設定し、「Enter」が実際に押されたときに、startflag=trueを実行できることをお勧めします。最後をgetCaretPosition()として保存します。

それを超えるあなたの意図についての私の理解は少し曖昧ですが、ここに私の考えがあります:コンソールである種の「会話」全体が行われていて、すべてのユーザーエントリが必要な場合は、ArrayListユーザー入力を使用できます、および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;
    }
}
}
于 2013-02-22T05:51:18.700 に答える