Java 使用不同System.in的JFrame冻结

Java 使用不同System.in的JFrame冻结,java,swing,jframe,swingworker,Java,Swing,Jframe,Swingworker,任何人都可以告诉我为什么在第一个main()中用扫描仪冻结JFrame?如果我卸下扫描仪,或者直接执行代码,所有功能都可以正常工作。(最初的“Try”类显然做了很多不同的事情。我编写这些类是为了让它变得简单。) 这是图形实现: import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; impor

任何人都可以告诉我为什么在第一个
main()
中用扫描仪冻结
JFrame
?如果我卸下
扫描仪
,或者直接执行代码,所有功能都可以正常工作。(最初的“Try”类显然做了很多不同的事情。我编写这些类是为了让它变得简单。)

这是图形实现:

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();
    }
}
导入java.awt.BorderLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.io.IOException;
导入java.io.PipedInputStream;
导入java.io.PipedOutputStream;
导入java.io.PrintStream;
导入java.io.PrintWriter;
导入java.util.Scanner;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTextArea;
导入javax.swing.JTextField;
导入javax.swing.SwingWorker;
公共类TryGraphic扩展JFrame{
/**
* 
*/
私有静态最终长serialVersionUID=7491282237007954227L;
私有JButton execute=新JButton(“Esegui”);
private PipedInputStream inPipe=new PipedInputStream();
private PipedInputStream outPipe=new PipedInputStream();
私有JTextField tfIn=新JTextField();
私有JTextArea outputArea=新JTextArea();
私人印刷作家;
公共图形学(){
超级(“尝试”);
系统设置(输入管道);
试一试{
系统放样(新打印流(新管道输出流(输出管),真));
inWriter=新的PrintWriter(新的管道输出流(inPipe),true);
}捕获(ioe异常ioe){
ioe.printStackTrace();
}               
addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件){
String text=tfIn.getText();
tfIn.setText(“”);
inWriter.println(文本);
}
});
添加(执行,BorderLayout.SOUTH);
add(新的JScrollPane(outputArea),BorderLayout.CENTER);
添加(tfIn,BorderLayout.NORTH);
execute.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
SwingWorker worker=新SwingWorker(){
受保护的Void doInBackground()引发异常{
扫描仪s=新扫描仪(输出管);
而(s.hasNextLine()){
字符串行=s.nextLine();
出版(行);
}
返回null;
} 
@凌驾
受保护的无效进程(java.util.List块){
对于(字符串行:块){
outputrea.append(line+System.lineSeparator());
outputArea.validate();
} 
} 
};
worker.execute();
Try.main(新字符串[]{”“});
}
});
这个。设置大小(300300);
此.setVisible(true);
此.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
公共静态void main(字符串[]args){
新的TryGraphic();
}
}

您正在阻止GUI事件调度线程。您需要生成一个单独的线程来等待输入,这样您就可以保持GUI的响应性


通过创建
SwingWorker
来处理
TryGraphic
类中的I/O,您已经做了正确的事情。您应该执行类似于移动
Try.main(新字符串[]{”“})的操作
取消事件调度线程,这将阻止JFrame锁定。

我知道EDT正在阻塞,但我不知道如何将
Try.main(String[]args)
移出
actionPerformed
。我是否需要为每个函数创建单独的线程?@Stereo89-您需要将任何可能阻塞的计算从EDT中移出。你为什么要在GUI应用程序中阻止读取
System.in
?如果您通过GUI获得输入,您可以完全避免这种情况。我需要扩展一个现有的类,该类已经在做“东西”,比如请求
字符串名
,这样我就无法在GUI中移动请求。当
main()
请求输入时,我需要请求输入。但是你能帮我理解“搬家”的意思吗?我需要创建一个
新线程()
,一个
新SwingWorker()
?奇怪的是,如果我在没有启动执行的
JButton
的情况下直接执行代码,那么一切都正常。我知道问题是
actionPerformed
JButton execute
),因为它需要另一个
actionPerformed
JTextField tfIn
),但我不知道如何解决。@Stereo89-是的,您应该创建一个新的
线程。你应该让你的
Try.main(新字符串[]{”“})
调用这个新线程,这样它就不会阻塞EDT。当您在“不使用按钮”的情况下运行它时,这会起作用,因为您从主线程而不是EDT调用
Try.main
。它会阻塞主线程,但由于它与EDT是分开的,因此不会导致GUI锁定。因此,如果我在
可运行的
中移动
actionPerformed
的每条指令,您认为一切都正常吗?我会试试的,我会让你知道的。非常感谢。
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();
    }
}