So I've been trying to work with the code in this post for making a console window in a JTextArea. That code seems to be functioning with mine, but I'm running into an odd problem.
My program: I'm basically building a quick and dirty gui for a command line tool I made recently. The only thing that the gui contains is a button that says "Start Automation Engine" and then it has a JTextArea
that is supposed to display any text my program sends to System.out.println()
.
At the moment it displays nothing, though the program itself is running and working (and should be displaying output as a result.) I have noticed that when I click the button on my gui the button stays depressed while the program runs. This has lead me to believe that the JFrame
is not updating while the program is running, thus the JTextArea
, as it's child, is not updating. This is not so good...
Is there a way to get that JTextArea
to update while the program is running in the background?
Here's my code for the JFrame
, btw, if you'd like to look at it to get a better idea of what I'm talking about. It was mostly constructed in WindowBuilder in Eclipse. The only thing I did was add a button listener to startAutmoatorEngineButton
and then add the last few lines of the initalize()
method to set the JTextArea
(engineOutput
) as the 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);
}
}
It's hard to tell for sure because I don't know what your AutomationLoop and TextAreaOutputStream classes do, but it sounds like a threading problem.
All your Swing code needs to execute in the Event Dispatch Thread. If you have a long running code that is not updating the GUI, then you probably want it running another thread, otherwise the GUI doesn't get a chance to update. From your behavior, it sounds like theLoop.startLoop() is running in the Event Dispatch Thread, and so the GUI never gets a chance to update itself.
Does theLoop.startLoop() start a new thread? If not it probably should; otherwise until that code finishes executing, your GUI will not update.