In Java Swing programming, you often encounter the need to dynamically refresh the interface, such as dynamic refresh JLabel text, JTextField text and so on. But often did not achieve our expected effect, I believe many friends have encountered this article will say this question.
In the swing interface, we expect the text in JLabel and JTextField to change continuously and display in real time when the button is clicked.
In this example, we expect that after clicking the button, JLabel and JTextField each second to refresh the text, sequentially displaying the following text:
Button clickedstart to change text ... Then the number 1 to 10action end is displayed
Many people will implement this function as follows:
Mainframe.java
PackageCom.longyg.test;PublicClass MainFrameExtendsJavax.swing.JFrame {PublicMainFrame () {initcomponents ();} @SuppressWarnings ("Unchecked")//<editor-fold defaultstate= "collapsed" desc= "Generated Code" >PrivatevoidInitcomponents () {JLabel =NewJavax.swing.JLabel (); LabelText =NewJavax.swing.JLabel (); JTextField =NewJavax.swing.JLabel (); Fieldtext =NewJavax.swing.JTextField (); button =NewJavax.swing.JButton (); Setdefaultcloseoperation (Javax.swing.WindowConstants.EXIT_ON_CLOSE); Jlabel.settext ("JLabel:"); Labeltext.setborder (Javax.swing.BorderFactory.createEtchedBorder ()); Jtextfield.settext ("JTextField:"); Button.settext ("click"); Button.addactionlistener (NewJava.awt.event.ActionListener () {Publicvoidactionperformed (java.awt.event.ActionEvent evt) {buttonactionperformed (EVT);}}); Javax.swing.GroupLayout layout =NewJavax.swing.GroupLayout (Getcontentpane ()); Getcontentpane (). setlayout (layout); Layout.sethorizontalgroup (Layout.createparallelgroup (Javax.swing.GroupLayout.Alignment.LEADING). AddGroup ( Layout.createsequentialgroup (). Addgap (10, 10, 10). AddGroup (Layout.createparallelgroup (Javax.swing.GroupLayout.Alignment.TRAILING). addcomponent (Button). AddGroup (Layout.createsequentialgroup (). AddComponent (JLabel). Addpreferredgap ( Javax.swing.LayoutStyle.ComponentPlacement.UNRELATED). AddComponent (LabelText, Javax.swing.GroupLayout.PREFERRED _size, 127, Javax.swing.GroupLayout.PREFERRED_SIZE)). AddGroup (Layout.createsequentialgroup (). AddComponent (JTextField). Addpreferredgap (Javax.swing.LayoutStyle.ComponentPlacement.RELATED). AddComponent (Fieldtext, Javax.swing.GroupLayout.PREFERRED_SIZE, 127, Javax.swing.GroupLayout.PREFERRED_SIZE)). Addcontainergap (17, Short.max_value))); Layout.setverticalgroup (Layout.createparallelgroup (Javax.swing.GroupLayout.Alignment.LEADING). AddGroup ( Layout.createsequentialgroup (). Addgap (20, 20, 20). AddGroup (Layout.createparallelgroup (Javax.swing.GroupLayout.Alignment.LEADING). AddComponent (JLabel). AddComponent (LabelText, Javax.swing.GroupLayout.PREFERRED_SIZE, 26, Javax.swing.GroupLayout.PREFERRED_SIZE)). Addgap (18, 18, 18). AddGroup (Layout.createparallelgroup (Javax.swing.GroupLayout.Alignment.LEADING). AddComponent (JTextField). AddComponent (Fieldtext, Javax.swing.GroupLayout.PREFERRED_SIZE, Javax.swing.GroupLayout.DEFAULT_SIZE, Javax.swing.GroupLayout.PREFERRED_SIZE)). Addpreferredgap (Javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) . addcomponent (Button). Addcontainergap (Javax.swing.GroupLayout.DEFAULT_SIZE, Short.max_value)); Pack (); }//</editor-fold>PrivatevoidButtonactionperformed (java.awt.event.ActionEvent evt) {changetext ("button clicked");Try{Thread.Sleep (1000); }Catch(Interruptedexception ex) {Ex.printstacktrace ();} Changetext ("Start To change Text ...");Try{Thread.Sleep (1000); }Catch(Interruptedexception ex) {Ex.printstacktrace ();}for (int i = 0; I < 10; i++) {Changetext ((i+1) + "");Try{Thread.Sleep (1000); }Catch(Interruptedexception ex) {Ex.printstacktrace ();} } changetext ("Action End"); }PrivatevoidChangetext (String text) {labeltext.settext (text); Fieldtext.settext (text);}/***@paramArgs the command line arguments*/PublicStaticvoidMain (String args[]) {Java.awt.EventQueue.invokeLater (NewRunnable () {Publicvoid run () {new MainFrame (). setvisible (true); } }); } // Variables declaration-do not modify private Javax.swing.JButton button; private Javax.swing.JTextField Fieldtext; private Javax.swing.JLabel JLabel; private Javax.swing.JLabel JTextField; private Javax.swing.JLabel LabelText; // End of variables declaration}
As you can see, in the Buttonactionperformed method, we have called settext several times to expect to change the text in JLabel and JTextField.
When we run this code, you will be very sorry to find that after clicking Click, JLabel and JTextField are not updated as we expected and display different text. Instead of clicking on the button, the interface seems to be stuck, and after a while, the last sentence of the text "Action End" is displayed.
Why would such a strange phenomenon happen?
In Java swing, interface refreshes are thread-synchronized, meaning that at the same time only one thread can execute code that refreshes the interface. If you want to refresh the interface more than once, you must call the Refresh method in multiple threads.
In this example, the SetText method is called multiple times in the Buttonactionperformed method to attempt to refresh the text of JLabel and JTextField. The Buttonactionperformed method runs in the main thread, so each call to SetText is run in the main thread and is executed sequentially. After the previous calls to SetText, the thread did not exit, so the interface refresh thread could not get an opportunity to perform the refresh. After the last settext, the thread exits before the interface can perform a refresh. So we can only see the last SetText value.
Therefore, to solve this problem, we have to put the code snippet in the Buttonactionperformed method into a separate thread to execute. This will not cause the thread to block, and after each settext, the interface refresh thread can also get the chance to execute, thus refreshing the interface.
The following is the modified code, only the code of the Buttonactionperformed method is modified, the other part of the code is exactly the same as above.
PrivatevoidButtonactionperformed (java.awt.event.ActionEvent evt) {New Thread (NewRunnable () {@OverridePublicvoidRun () {changetext ("button clicked");Try{Thread.Sleep (1000); }Catch (Interruptedexception ex) {ex.printstacktrace ();} changetext ("Start To change Text ..." ); try {thread.sleep (1000 ); } catch (Interruptedexception ex) {Ex.printstacktrace ( ); } for (int i = 0; i <; I++) {Changetext ((i+1) + "" ); try {thread.sleep (1000 ); } catch (Interruptedexception ex) {Ex.printstacktrace ( ); }} changetext ("Action End"
As we can see, the new buttonactionperformed method simply puts the entire code snippet in one thread and starts the thread.
After each settext, we sleep for 1 seconds, is to see the interface really real-time changes, if not sleep, the interface refresh will be a flash, not conducive to observation.
Running the code again will find that we finally get the effect we expect: The dynamic changes in the text in JLabel and JTextField!
Http://www.cnblogs.com/longyg/archive/2012/07/03/2575482.html
Swing interface Refresh problem (GO)