Refreshing jFrame during the execution of the ActionListener Action Performed for a button

Posted on 2014-09-06
Last Modified: 2014-09-07
I have a jFrame, that has a jButton on it along with a jLabel that I expect to be updated on the jFrame when I push
the button. So, in the action listener action performed method I change the value to be displayed on the jLabel:

 // Change the test indicator, before the test is done, indicating test in progress
        jlblTestResultDisp.setText("<html><font color = black> TESTING</font></html>");

Open in new window

Then, I call the repaint() method on both the jLabel and the jFrame it is part of, inside the same action listener action performed method:
        this.validate();  // where 'this' refers to the jFrame

Open in new window

Nothing happens at this point!

Then from inside the button action listener I call a method that will run a script that it will take several seconds
to execute:
 Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(testScriptToRun);
 int exitVal = proc.waitFor();

Open in new window

When the exitVal comes back from the process, which several seconds later that's only when the jFrame refreshes. until then the jFrame is just 'hanging in there', after pushing the test button nothing shows up
on jFrame as far as changes.JFrame image with 'Start Standard Test' button pushed and red jLabel
Question: How do I make the JFrame refresh right after pushing the 'Start Standard Test' button and BEFORE the script is run from the action performed and the exitVal comes back ? Basically I want to show a message on the jLabel , while waiting for the script to finish running and proc.waitFor() method returns the value to let the action performed method return.

Thank you for your help.
Question by:AttilaB
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
LVL 16

Expert Comment

ID: 40307952
I've not really been able to understand your problem but it sounds like you should update the gui in its own thread.

Author Comment

ID: 40308017
"Updating the GUI in its own thread" - what does that mean, how do you do that?

That would probably help, I just don't know what exactly you are talking about?

Author Comment

ID: 40308031
The problem would be in very simple terms:

You push a button on the JFrame instance. As you process the button push you want to update the jFrame
before the method processing the button completes, because it takes several seconds to have it completed.

TESTING  ....... <several seconds>   ......TEST DONE indicated

 I want to have 2 updates essentially to the JFrame: One right after the push of the button and one at the end of the processing of the button. I am only getting this second one, not the first one.
LVL 14

Accepted Solution

CPColin earned 500 total points
ID: 40308633
Hi AttilaB,

According to the documentation, calling repaint(), triggers a repaint "as soon as possible." The "please repaint this" event gets added to the GUI event queue. There's already an event being processed, though; that's why the code is in your actionPerformed() method. The soonest your frame can be repainted is after the method completes.

What you want to do here is move that script into the run() method of a Runnable object and use SwingUtilities.invokeLater() to run it, like this:

        this.validate();  // where 'this' refers to the jFrame

        SwingUtilities.invokeLater(new Runnable()
           public void run()
              Runtime rt = Runtime.getRuntime();
              Process proc = rt.exec(testScriptToRun);
              int exitVal = proc.waitFor();

Open in new window

This will allow the repaint event to be processed before the event processing thread pauses to wait for that script to return.

Note that this is definitely not optimal. In general, you don't want long-running operations to happen on the event processing thread. This is because your application will appear to hang, since the operation is preventing event processing from continuing. Ideally, you would run the operation in its very own thread, then use SwingUtilities.invokeLater() to update your JLabel with the results of the operation.

Let me know if you have more questions. Event processing and multi-threading in GUI code is a tricky beast.

Author Comment

ID: 40309115
Well. I ended up making a mini-project out of the original jFrame with a reduced code set that worked identical to the big monster program in this respect, and used your suggestions to figure out the right code.

I paste it here for its educational value for other users, possibly:
(This code works perfectly as expected.)

package mainscreen_mini;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class MainScreen_Mini extends JFrame {
    private JLabel jlblTextLabel;
    private JButton jbtnStartTesting;
    private JScrollPane scrollPane1;
    private JList list1;
	public MainScreen_Mini() {

	private void initComponents() {
		// Component initialization 
		jlblTextLabel = new JLabel();
		jbtnStartTesting = new JButton();
		scrollPane1 = new JScrollPane();
		list1 = new JList();
	    // inner class listener for Standard test button:
	           jbtnStartTesting.addActionListener(new ActionListener() {
	               public void actionPerformed(ActionEvent evt) {

		//======== this ========
		Container contentPane = getContentPane();

		//---- jlblTextLabel ----
		jlblTextLabel.setText("Not Tested");
		jlblTextLabel.setFont(new Font("Tahoma", Font.BOLD, 22));
		jlblTextLabel.setBounds(115, 30, 150, 50);

		//---- jbtnStartTesting ----
		jbtnStartTesting.setText("Start Testing");
		jbtnStartTesting.setFont(new Font("Tahoma", Font.PLAIN, 18));
		jbtnStartTesting.setBounds(115, 75, 150, 65);

		//======== scrollPane1 ========
		scrollPane1.setBounds(25, 150, 340, scrollPane1.getPreferredSize().height);

		{ // compute preferred size
			Dimension preferredSize = new Dimension();
			for(int i = 0; i < contentPane.getComponentCount(); i++) {
				Rectangle bounds = contentPane.getComponent(i).getBounds();
				preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
				preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
			Insets insets = contentPane.getInsets();
			preferredSize.width += insets.right;
			preferredSize.height += insets.bottom;
        public static void main(String[] args) {
            MainScreen_Mini frameInstance = new MainScreen_Mini();
            frameInstance.setSize(400, 350);
            frameInstance.setSize(400, 350);
    // Action Listener for  button:
       private void jbtnStartTesting_ActionPerformed(ActionEvent evt) {
           System.out.println("Button Pressed");
           // Change the test indicator, before the test is done, indicating test in progress
           jlblTextLabel.setText("<html><font color = green>TESTING</font></html>");
           // Creating a Runnable instance here:
           javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    // TO RUN EXECUTABLE SCRIPT: 
                   runCasconScript("CASCONCMD \"/U01061074C 75X00 Pod\" \"/TInterconnection\" /R");
                    // END OF RUN EXECUTABLE SCRIPT

    // Method that runs the external program script with required parameters:
        public void runCasconScript(String testScriptToRun) {  
                try {
                    Runtime rt = Runtime.getRuntime();
                    System.out.println("Executing: " + testScriptToRun);
                    Process proc = rt.exec(testScriptToRun);

                    // any error after executing process is indicated in exitVal
                    int exitVal = proc.waitFor();
                    System.out.println("ExitValue: " + exitVal);
                    // Final label, showing that the script has completed:
                        jlblTextLabel.setText("<html><font color = blue> Test DONE</font></html>");
                    // License error:
                    if (exitVal == 11){
                                   JOptionPane.showMessageDialog(null, "License Error: Make sure that your computer is connected to ITC's network or the hardware plug is directly connected to USB.\n                     If test is still not running correctly, then contact Attila Barnai. \n\n                                                    The program will exit now. ", "License Error", JOptionPane.ERROR_MESSAGE); 
                    // exitVal value 0 -> Pass Test, value 1 - > Test Failed, otherwise test system fail
                    if (!((exitVal ==0) || (exitVal ==1))){
                                   JOptionPane.showMessageDialog(null, "Not a valid test. Please make sure USB pod is connected, re-start program or re-start computer. \n                      If test is still not running correctly, then contact Attila Barnai. \n\n                                                    The program will exit now. ", "Not a Valid Test", JOptionPane.ERROR_MESSAGE); 

                } catch (Throwable t) {
                    System.out.println("Cannot perform test: System is not set up correctly!");
                    JOptionPane.showMessageDialog(null, "Cannot perform test: System is not set up correctly!", "System Setup Error", JOptionPane.ERROR_MESSAGE);

Open in new window

Thank you for your help.


Featured Post

Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Suggested Courses

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question