2

I’m trying to simulate a console with a JTextArea by directing user input to System.in. The test string is successfully appended to the JTextArea, and the main method’s Scanner.nextLine() successfully waits for and prints user input. The same append and scanner methods don’t work when the button is pressed. Any recommendations? Thanks.

import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class ScannerTest {
    public static void main(String[] args) throws IOException {
        PipedInputStream inPipe = new PipedInputStream();
        System.setIn(inPipe);
        PrintWriter inWriter = new PrintWriter(new PipedOutputStream(inPipe), true);

        JTextArea console = console(inWriter);
        Scanner sc = new Scanner(System.in);

        JButton button = new JButton("Button");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                console.append("button pressed\n");
                console.append("got from input: " + sc.nextLine() + "\n"); // cause of problem???
            }
        });

        JFrame frame = new JFrame("Console");
        frame.getContentPane().add(console);
        frame.getContentPane().add(button, "South");
        frame.setSize(400, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        console.append("test\n");
        console.append("got from input: " + sc.nextLine() + "\n");
    }
    public static JTextArea console(final PrintWriter in) {
        final JTextArea area = new JTextArea();
        area.addKeyListener(new KeyAdapter() {
            private StringBuffer line = new StringBuffer();
            @Override public void keyTyped(KeyEvent e) {
                char c = e.getKeyChar();
                if (c == KeyEvent.VK_ENTER) {
                    in.println(line);
                    line.setLength(0); 
                } else if (c == KeyEvent.VK_BACK_SPACE) { 
                    line.setLength(line.length() - 1); 
                } else if (!Character.isISOControl(c)) {
                    line.append(e.getKeyChar());
                }
            }
        });
        return area;
    }
}
Charuක
  • 12,229
  • 5
  • 43
  • 83
  • 1
    I think that scanner is a command line tool, not a GUI one. What do you think the trigger would be to cause the scanner to capture the next line when a _button_ is pressed? – Tim Biegeleisen Dec 22 '16 at 05:05
  • `new Scanner(System.in);` takes input from the command line. A GUI application is not guaranteed to have such command line – Scary Wombat Dec 22 '16 at 05:16
  • The input goes from the PipedInputStream to System.in when the enter key is pressed, and scanner gets its info from System.in, so the scanner should work with whatever stream is used, right? – Lucas Prescott Dec 22 '16 at 05:20
  • I think, the keyTyped(KeyEvent e) method of JTextArea is consuming the key events and thus the scanner is not really getting the input. – Hungry Coder Dec 22 '16 at 05:29

1 Answers1

0

I think you overcomplicated things. Since you wanted a console, here I present a simpler solution to you. I don't recommend using sc.nextLine() in a context like yours due to bug they lead to. That might be cause of your problem, have a look at it. You can get input in various ways. For example:

BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str = reader.readLine()

OR

String str = System.console().readLine();

Long story short, here's what I wrote. It might serve your purpose:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;

public class MyConsole {
    public static void main(String[] args) {

        JTextField field = new JTextField();
        JTextArea area = new JTextArea();

        area.setLineWrap(true);

        field.addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {

            }

            @Override
            public void keyPressed(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_ENTER)
                {
                    area.setText(area.getText() + "\n" + field.getText()); //Do whatever you like with the stirng
                    field.setText("");
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
            }

        });


        JScrollPane scPane = new JScrollPane(area);
        scPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);

        JButton button = new JButton("Button");
        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                area.setText(area.getText() + "\n" + field.getText()); //You can also use button as well
                field.setText("");
            }
        });

        JFrame frame = new JFrame("Console");

        frame.getContentPane().add(field, BorderLayout.NORTH);
        frame.getContentPane().add(button, BorderLayout.SOUTH);
        frame.getContentPane().add(scPane, BorderLayout.CENTER);
        frame.getContentPane().setPreferredSize(new Dimension(400, 400));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}
Community
  • 1
  • 1
Burak.
  • 598
  • 7
  • 19