Scanner not working in ActionListener

990 views Asked by At

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;
    }
}
1

There are 1 answers

0
Burak. On

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);
    }
}