2015-05-13 3 views
3

Я пытаюсь получить вывод в TextField в графическом интерфейсе, но все, что я получаю, это информация о потоке. Это всего лишь небольшой набор из полного кода, но полная версия имеет ту же проблему. Полная версия имеет 5 различных потоков, работающих одновременно. Любая помощь или совет будут оценены.Выходной поток в текстовое поле GUI

public class O21 implements Runnable { 
@Override 
public void run() { 

    try { 
     Scanner O1 = new Scanner(new File("O21.txt")); 
     O1.useDelimiter(","); 
     while (O1.hasNext()) { 
      String a = O1.next(); 
      int aa = Integer.parseInt(a); 
      Thread.sleep(500); // Time delay to sync output 
      if (a.trim().isEmpty()) { 
       continue; 
      } 
      System.out.println(a); 
     } 
    } catch (Exception f) { 
     f.printStackTrace(); 
    }}} 

Это главный.

public class Window { 
    private JFrame frmTest; 
    private JTextField txtTank1; 
    private JTextField textField_4; 
    static String o1; 

/** 
* Launch the application. 
*/ 
public static void main(String[] args) throws Exception { 

    Thread a = new Thread(new O21()); 
    a.start(); 

    o1= a.toString(); 

    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       Window window = new Window(); 
       window.frmTest.setVisible(true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 

    }); 
} 

/** 
* Create the application. 
*/ 
public Window() { 
    initialize(); 
} 

/** 
* Initialize the contents of the frame. 
*/ 
private void initialize() { 
    frmTest = new JFrame(); 
    frmTest.setAlwaysOnTop(true); 
    frmTest.setResizable(false); 
    frmTest.setBounds(100, 100, 350, 400); 
    frmTest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frmTest.getContentPane().setLayout(null); 

    txtTank1 = new JTextField(); 
    txtTank1.setText("Tank1"); 
    txtTank1.setFont(new Font("Tahoma", Font.PLAIN, 20)); 
    txtTank1.setEditable(false); 
    txtTank1.setColumns(10); 
    txtTank1.setBounds(10, 60, 150, 50); 
    frmTest.getContentPane().add(txtTank1); 

    textField_4 = new JTextField(); 
    textField_4.setEditable(true); 
    textField_4.setText(o1); 
    textField_4.setFont(new Font("Tahoma", Font.PLAIN, 20)); 
    textField_4.setColumns(10); 
    textField_4.setBounds(170, 60, 150, 50); 
    frmTest.getContentPane().add(textField_4); 
}} 
+0

См. правки для ответа, включая код. –

ответ

3

Вы пишете o1 один раз, и только получать по умолчанию toString() из потока, так что я не удивлен, что вы не видите ничего, кроме мусора. Мое предложение:

  • Создать SwingWorker<Void, String> внутри вашего GUI
  • Запустите долго выполняющиеся кода из doInBackground в SwingWorker в
  • Публикация любых строк, которые требуются GUI, вызвав publish(...), передавая String.
  • Показать их в графическом интерфейсе с использованием метода SwingWorker process(...).
  • Не используйте статическую переменную как kludge для связи между потоками. Это очень легко разрушаемое не-решение.
  • Избегайте звонить setBounds() в графическом интерфейсе Swing. Хотя нулевые макеты и setBounds() могут показаться новичкам Swing, как самый простой и лучший способ создания сложных графических интерфейсов, чем больше Swing GUI вы создадите более серьезные трудности, с которыми вы столкнетесь при их использовании. Они не будут изменять размеры ваших компонентов при изменении размера графического интерфейса, они являются королевской ведьмой для улучшения или поддержки, они полностью не выполняются при размещении в scrollpanes, они выглядят ужасно ужасно при просмотре на всех платформах или разрешениях экрана, отличных от исходного , Вместо этого узнайте и используйте менеджеров компоновки.
  • Посмотрите на: Tutorial: Concurrency in Swing.

например, что-то вроде,

import java.io.File; 
import java.util.List; 
import java.util.Scanner; 

import javax.swing.*; 

public class SwingThreadingEg extends JPanel implements MyAppendable { 
    private JTextArea area = new JTextArea(30, 50); 

    public SwingThreadingEg() { 
     JScrollPane scrollPane = new JScrollPane(area); 
     scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
     add(scrollPane); 
    } 

    @Override 
    public void append(String text) { 
     area.append(text); 
    } 

    private static void createAndShowGui() { 
     SwingThreadingEg mainPanel = new SwingThreadingEg(); 
     MyWorker myWorker = new MyWorker(mainPanel); 
     // add a Prop Change listener here to listen for 
     // DONE state then call get() on myWorker 
     myWorker.execute(); 

     JFrame frame = new JFrame("SwingThreadingEg"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

class MyWorker extends SwingWorker<Void, String> { 
    private MyAppendable myAppendable; 

    public MyWorker(MyAppendable myAppendable) { 
     this.myAppendable = myAppendable; 
    } 

    @Override 
    protected Void doInBackground() throws Exception { 
     try (Scanner O1 = new Scanner(new File("O21.txt"))) { 

     O1.useDelimiter(","); 
     while (O1.hasNext()) { 
      String a = O1.next(); 
      int aa = Integer.parseInt(a); 
      Thread.sleep(500); // Time delay to sync output 
      if (a.trim().isEmpty()) { 
       continue; 
      } 
      System.out.println(a); 
      publish(a); 
     } 
     } catch (Exception f) { 
     f.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void process(List<String> chunks) { 
     for (String text : chunks) { 
     myAppendable.append(text + "\n"); 
     } 
    } 
} 

interface MyAppendable { 
    public void append(String text); 
} 
+0

Почему OP 'window.frmTest.setVisible (true);' не бросает 'NPE'? –

+0

@ PM77-1: понятия не имею. Я отказался от подробного изучения его кода, как только увидел, что он вызывает 'toString()' в потоке! –

+0

Спасибо, это было именно то, что мне нужно. Я не мог правильно выводить строки. И * window.frmTest.setVisible (true); * был автогенерирован конструктором окон. – Ben

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