Question

Anyone can tell me why TryGraphic freeze the JFrame with a scanner in the first main()? If I remove the Scanner or if I execute the code directly, all works. (The original "Try" class obviously do a lot of different stuff. I wrote these classes to make it simple.)

import java.util.Scanner;


public class Try {

    public Try(){

    }

    public static void main(String[] args){
        System.out.println("FOO");
        String s = new Scanner(System.in).nextLine();
        System.out.println(s);
    }
}

This is the graphic implementation:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Scanner;

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


public class TryGraphic extends JFrame{

    /**
     * 
     */
    private static final long serialVersionUID = 7491282237007954227L;



    private JButton execute = new JButton("Esegui");

    private PipedInputStream inPipe = new PipedInputStream(); 
    private PipedInputStream outPipe = new PipedInputStream(); 
    private JTextField tfIn = new JTextField();
    private JTextArea outputArea = new JTextArea();

    private PrintWriter inWriter;


    public TryGraphic(){
        super("TRY");

        System.setIn(inPipe); 

        try {
            System.setOut(new PrintStream(new PipedOutputStream(outPipe), true)); 
            inWriter = new PrintWriter(new PipedOutputStream(inPipe), true); 
        }catch (IOException ioe){
            ioe.printStackTrace();
        }               

        tfIn.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent event){
                    String text = tfIn.getText();
                    tfIn.setText("");
                    inWriter.println(text); 
            }
        });

        this.add(execute,BorderLayout.SOUTH);
        this.add(new JScrollPane(outputArea),BorderLayout.CENTER);
        this.add(tfIn, BorderLayout.NORTH);

        execute.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {

                SwingWorker<Void,String> worker = new SwingWorker<Void, String>() { 
                     protected Void doInBackground() throws Exception { 
                        Scanner s = new Scanner(outPipe);
                        while (s.hasNextLine()) {
                                 String line = s.nextLine();
                                 publish(line);

                        }
                        return null; 
                    } 

                     @Override 
                     protected void process(java.util.List<String> chunks) { 
                         for (String line : chunks){ 
                             outputArea.append(line+System.lineSeparator());
                             outputArea.validate();
                             } 

                     } 
                };

                worker.execute();

                Try.main(new String[]{""});
            }

        });

        this.setSize(300,300);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    }



    public static void main(String[] args){
        new TryGraphic();
    }
}
Was it helpful?

Solution

You're blocking the GUI Event Dispatch Thread. You need to spawn a separate thread to wait for input so you can keep your GUI responsive.

You're already doing the right thing by creating a SwingWorker to handle I/O in your TryGraphic class. You should do something similar to move the Try.main(new String[]{""}); call off the Event Dispatch Thread, which will keep your JFrame from locking up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top