2013-12-14 2 views
0

Любой может сказать мне, почему TryGraphic заморозить JFrame со сканером в первом main()? Если я удалю Scanner или если я выполняю код напрямую, все работает. (Оригинал «Try» класс, очевидно, сделать много разных вещей, которые я написал эти классы, чтобы сделать это просто..)JFrame заморозить с различными System.in

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

Это графическая реализация:

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

ответ

1

Вы преграждать Дискуссионный поток событий. Вам нужно создать отдельный поток, чтобы ждать ввода, чтобы вы могли реагировать на ваш графический интерфейс.

Вы уже поступаете правильно, создав SwingWorker для обработки ввода-вывода в вашем классе TryGraphic. Вы должны сделать что-то подобное, чтобы переместить вызов Try.main(new String[]{""}); из потока событий, который будет блокировать ваш JFrame.

+0

Я знал, что EDT блокирует, но я не знаю, как я могу перемещать 'Try.main (String [] args)' из 'actionPerformed'. Нужно ли создавать отдельный поток для каждой функции? – Stereo89

+0

@ Stereo89 - вам нужно переместить любые потенциально блокирующие вычисления с EDT. Почему вы все равно блокируете чтение 'System.in' в GUI-приложении? Если вы получили вход через GUI, вы могли бы избежать этого вообще. – DaoWen

+0

Мне нужно расширить существующий класс, который уже выполняет «материал», например, запросить «String name», поэтому я не могу переместить запрос в графическом интерфейсе. Мне нужно спросить ввод, когда 'main()' запрашивает его. Но вы можете помочь мне со значением «двигаться»? Мне нужно создать 'новый Thread()', 'новый SwingWorker()'? Странно то, что если я исполняю код напрямую без 'JButton', который запускает выполнение, все работает нормально. Я знаю, что проблема заключается в 'actionPerformed' (' JButton execute'), потому что ему нужен другой 'actionPerformed' (' JTextField tfIn'), но я не знаю, как это сделать. – Stereo89

Смежные вопросы