2013-05-29 90 views
1

所以我一直在嘗試使用這個帖子中的代碼for making a console window in a JTextArea。該代碼似乎與我的功能,但我遇到了一個奇怪的問題。當程序運行時使用System.out更新jTextArea

我的程序:我基本上是爲我最近製作的一個命令行工具創建一個快速和髒的gui。 gui包含的唯一一個按鈕是「Start Automation Engine」,然後它有一個JTextArea,它應該顯示我的程序發送到System.out.println()的任何文本。

目前它什麼也沒有顯示,儘管程序本身正在運行並正在運行(並且應該顯示輸出結果)。我注意到,當我點擊我的gui上的按鈕時,按鈕在程序運行時保持壓低狀態。這使我相信JFrame在程序運行時沒有更新,因此JTextArea,因爲它是小孩,沒有更新。這是不是很好...

有沒有辦法讓JTextArea更新,而程序在後臺運行?

這是我的代碼JFrame,順便說一句,如果你想看看它,以更好地瞭解我在說什麼。它主要是在Eclipse的WindowBuilder中構建的。我做的唯一的事情是將一個按鈕偵聽器添加到startAutmoatorEngineButton,然後添加initalize()方法的最後幾行以將JTextAreaengineOutput)設置爲System.out

public class EngineGUI { 

private JFrame frmAutomatorEngine; 
private File logPath = new File("<redacted>", "<redacted>"); 
private File masterFile = new File("<redacted>", "<redacted>"); 

/** 
* Launch the application. 
*/ 
public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       EngineGUI window = new EngineGUI(); 
       window.frmAutomatorEngine.setVisible(true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

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

/** 
* Initialize the contents of the frame. 
*/ 
private void initialize() { 
    frmAutomatorEngine = new JFrame(); 
    frmAutomatorEngine.setType(Type.UTILITY); 
    frmAutomatorEngine.setResizable(false); 
    frmAutomatorEngine.setTitle("Automator Engine"); 
    frmAutomatorEngine.setBounds(100, 100, 636, 335); 
    frmAutomatorEngine.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    JMenuBar menuBar = new JMenuBar(); 
    frmAutomatorEngine.setJMenuBar(menuBar); 

    JMenu mnEngine = new JMenu("Engine"); 
    menuBar.add(mnEngine); 

    JMenuItem mntmLoadMasterFile = new JMenuItem("Load Master File..."); 
    mnEngine.add(mntmLoadMasterFile); 

    JMenuItem mntmExit = new JMenuItem("Exit"); 
    mnEngine.add(mntmExit); 
    frmAutomatorEngine.getContentPane().setLayout(null); 

    JTextArea engineOutput = new JTextArea(); 
    engineOutput.setBounds(10, 48, 600, 217); 
    frmAutomatorEngine.getContentPane().add(engineOutput); 

    JButton startAutomatorEngineButton = new JButton("Start Automator Engine"); 
    startAutomatorEngineButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 

      MasterFile master = null; 
      try { 
       master = new MasterFile(masterFile, logPath); 
      } catch (FileNotFoundException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 

      AutomationLoop theLoop = new AutomationLoop(master); 
      theLoop.startLoop(); 

     } 
    }); 
    startAutomatorEngineButton.setBounds(441, 11, 169, 23); 
    frmAutomatorEngine.getContentPane().add(startAutomatorEngineButton); 

    //Set up textArea to be used as output stream for program 
    TextAreaOutputStream outputStream = new TextAreaOutputStream(engineOutput); 
    PrintStream printStream = new PrintStream(outputStream); 
    System.setOut(printStream); 
    //System.setErr(printStream); 

} 

}

回答

1

很難確切地回答,因爲我不知道你AutomationLoop和TextAreaOutputStream類的事情,但它聽起來像一個線程的問題。

您的所有Swing代碼需要在事件派發線程中執行。如果你有一個長時間運行的代碼沒有更新GUI,那麼你可能希望它運行另一個線程,否則GUI沒有機會更新。從您的行爲看,聽起來像Loop.startLoop()正在Event Dispatch Thread中運行,所以GUI永遠沒有機會自行更新。

theLoop.startLoop()是否啓動一個新線程?如果不是,它可能應該;否則,直到該代碼完成執行,您的GUI將不會更新。

+0

不,它不會啓動一個新的線程...你知道任何好的教程把它扔到另一個線程嗎? –

+1

你可以試試Oracle/Sun: http://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html –

+0

是的,你是對的。我做了一個單獨的線程來運行我的循環,現在主窗口正在更新。非常感謝你的幫助! –

相關問題