Solved

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

Posted on 2014-09-06
5
763 Views
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:
        jlblTestResultDisp.validate();
        jlblTestResultDisp.repaint();
        this.validate();  // where 'this' refers to the jFrame
        this.repaint();

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.
0
Comment
Question by:AttilaB
  • 3
5 Comments
 
LVL 16

Expert Comment

by:krakatoa
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.
0
 

Author Comment

by:AttilaB
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?
0
 

Author Comment

by:AttilaB
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.
0
 
LVL 14

Accepted Solution

by:
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:

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

        SwingUtilities.invokeLater(new Runnable()
        {
           @Override
           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.
0
 

Author Comment

by:AttilaB
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() {
		initComponents();
	}

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

		//======== this ========
		Container contentPane = getContentPane();
		contentPane.setLayout(null);

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

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

		//======== scrollPane1 ========
		{
			scrollPane1.setViewportView(list1);
		}
		contentPane.add(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;
			contentPane.setMinimumSize(preferredSize);
			contentPane.setPreferredSize(preferredSize);
		}
    
		pack();
		setLocationRelativeTo(getOwner());
		
	}
        
        public static void main(String[] args) {
            MainScreen_Mini frameInstance = new MainScreen_Mini();
            frameInstance.setSize(400, 350);
            frameInstance.setVisible(true);
            frameInstance.setSize(400, 350);
        } 
        
        
    // Action Listener for  button:
       private void jbtnStartTesting_ActionPerformed(ActionEvent evt) {
           System.out.println("Button Pressed");
           
           jlblTextLabel.validate();
           jlblTextLabel.repaint();
           this.validate();
           this.repaint();
           
           // 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); 
                            System.exit(1);
                        }
                    
                    // 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); 
                            System.exit(1);
                        }

                } 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.

  Testing.png
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
stringclean challenge 26 55
parentbit challenge 3 52
countHi2 challenge 7 44
java set up 1 46
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
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 …
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

708 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now