After another 12 o'clock. After a long wait for the two books I ordered in China-Pub n days ago, I finally got them today :《
Core Java, vol. 2: advanced features
And 《
Filthy rich clients
. In this year, the price of express delivery has increased. I'm a little impatient recently. It's okay. There are several days every month. Oh, don't get me wrong. I mean the physiological cycle of men.
In this tutorial, we have always only made some interfaces or components, without too much consideration for the program structure and logic. It was also stated in advance, but the interface is made, regardless of the logic. The logic can be left blank, but the structure of the program cannot be messy. Go back to tutorial 4. One of them is the initialization file tree. Let's put this section on the interface after initialization and display it, and then see how it works. In this case, we have to change it and declare defatreemodel to the jtree, A custom status bar statusbar is added (the code is placed below ):
Private defatretreemodel treemodel = new defaulttreemodel (null); <br/> private statusbar = new statusbar ();
Modify the jtree initialization part as follows:
Jtree tree = new jtree (treemodel); <br/> tree. setcellrenderer (New treerenderer (); <br/> tree. getselectionmodel (). setselectionmode (treeselectionmodel. single_tree_selection); <br/> tree. setrootvisible (true); <br/> lefttabbedpane. add ("file", new jscrollpane (tree ));
The inittree () method is also modified, and the adddir () method remains unchanged:
Private void inittree () {<br/> defaultmutabletreenode Top = new defaultmutabletreenode (null); <br/> file dir = new file ("C: /users/monitor/documents/netbeansprojects/"); <br/> adddir (top, DIR); <br/> treemodel. setroot (top); <br/>}
We want to initialize the file tree after the main interface is displayed:
Public netbeansui () {<br/> initcomponents (); <br/> setvisible (true); <br/> initdata (); <br/>}< br/> private void initdata () {<br/> statusbar. barshow (); <br/> inittree (); <br/> statusbar. barhide (); <br/>}
What will happen after running? It is expected that the progress bar will appear after the page appears. After the page is complete, the progress bar will be hidden. In essence, the file tree appears after the main interface is stuck for about 3 seconds, but no progress bar is found. When I first learned about swing, I also scolded this jprogressbar for its poor use. You need to understand the single-threaded mode of swing.
I. EDT
At any time, a swing application will automatically create three threads. First, the main thread runs the main method of the application. Second, the toolkit thread is responsible for capturing system events. It does not run application code, and the captured events are sent to the third thread EDT (event dispatch thread, event dispatching thread ).
EDT interacts closely with swing. It is responsible for distributing events to appropriate components and calling their rendering methods. This is precisely because we can see a changed interface. It can be said that AWT and anything in swing are more or less related to EDT.
Single thread, queue, are you a little confused. When we execute a time-consuming operation in the EDT, the interface cannot be refreshed because the refresh part is still waiting in queue. The above program is due to this, resulting in a 3 second card. In the past, when I looked at the javadoc of the swing component, I saw this sentence: swing is NOT thread-safe. For more information, see swing's threading
Policy
. At that time, I was so strange.
Ii. swingutilities
It is easy to understand the problem. Since time-consuming operations cannot be placed in EDT, put them in a new thread:
Private void initdata () {<br/> New thread (New runnable () {<br/> Public void run () {<br/> statusbar. barshow (); <br/> inittree (); <br/> statusbar. barhide (); <br/>}< br/> }). start (); <br/>}
The progress bar can also be displayed without any issues during running. It seems that everything is normal. However, it violates swing's single-threaded rules: modifying the component status must be performed in EDT. The test may not cause any problems, but the deadlock may occur at any time. I have a deep understanding that the logic of the self-developed editor is no problem, that is, there are some inexplicable exceptions when you are running, the error message does not seem to have any relationship with the code half-size.
Try invokelater () in the swing tool class swingutilities, which can be used to publish a new task in EDT. Generally, this method is used to initialize the swing component in the code automatically generated by netbeans. Change initdata () to the following:
Private void initdata () {<br/> New thread (New runnable () {<br/> Public void run () {<br/> swingutilities. invokelater (New runnable () {<br/> Public void run () {<br/> statusbar. barshow (); <br/> inittree (); <br/> statusbar. barhide (); <br/>}< br/>}); <br/>}< br/> }). start (); <br/>}
Iii. swingworker
Swingutilities are very useful, but it needs to create many anonymous runnable classes, but it is difficult to read and maintain the code written by swingutilities when there are many things to be done and complicated. In this case, consider swingworker, which is newly added in Java SE 6. It can run a specific task in a background thread and publish the intermediate and final results of the task on EDT. For details about swingworker usage, see javadoc, I am so sleepy. The implementation of swingworker for constructing the file tree is given below:
Package COM. monitor1394.netbeans. ui; <br/> Import COM. monitor1394.netbeans. component. statusbar; <br/> Import Java. io. file; <br/> Import Java. util. list; <br/> Import javax. swing. swingworker; <br/> Import javax. swing. tree. defaultmutabletreenode; <br/> Import javax. swing. tree. defaulttreemodel; <br/>/** <br/> * construct a file tree <br/> * @ author Monitor <br/> * created on, 23:49:40 <br/> */<br/> public class dirloadingworker extends swingworker <defaultmutabletreenode, string >{< br/> private statusbar; <br/> private defatreemodel treemodel; <br/> Public dirloadingworker (statusbar bar, defatretreemodel model) {<br/> This. bar = bar; <br/> treemodel = model; <br/> bar. barshow (); <br/>}< br/>/** assign the node to the treemodel and hide the progress bar */<br/> @ override <br/> protected void done () {<br/> try {<br/> treemodel. setroot (get (); <br/> bar. barhide (); <br/> bar. setbarinfo ("project scan completed"); <br/>} catch (exception ex) {<br/>}< br/>/** display information output in progress */<br/> @ override <br/> protected void process (list <string> messages) {<br/> for (string message: messages) {<br/> bar. setbarmsg (Message ); <br/>}< br/>/** create a root node using a folder during background processing of the task */<br/> @ override <br/> protected defaultmutabletreenode doinbackground () {<br/> defaultmutabletreenode Top = new defaultmutabletreenode (null); <br/> file dir = new file ("C:/users/monitor/documents/netbeansprojects /"); <br/> adddir (top, DIR); <br/> return top; <br/>}< br/>/** recursively convert the file (folder) node converted to jtree */<br/> private defaultmutabletreenode adddir (defaultmutabletreenode top, file) {<br/> If (file. isdirectory () {<br/> for (file F: file. listfiles () {<br/> defaultmutabletreenode T = new defaultmutabletreenode (F. getname (); <br/> Publish ("loading" + F. getname (); <br/> If (F. isdirectory () <br/> top. add (adddir (T, F); <br/> else top. add (t); <br/>}< br/>}else {<br/> top. add (New defaultmutabletreenode (file. getname (); <br/>}< br/> return top; <br/>}< br/>
To run it, change the 38 rows in the netbeansui class:
New dirloadingworker(statusbar,treemodelcmd.exe cute ();
Well, you cannot close the job. Code of the statusbar class is attached:
Package COM. monitor1394.netbeans. component; <br/> Import javax. swing. imageicon; <br/> Import javax. swing. jbutton; <br/> Import javax. swing. jlabel; <br/> Import javax. swing. jpanel; <br/> Import javax. swing. jprogressbar; <br/> Import javax. swing. jseparator; <br/>/** <br/> * Status Bar <br/> * @ author Monitor <br/> * created on 2011-2-28, 23:30:50 <br/> */<br/> public class statusbar extends jpanel {<br/> Public statusbar () {<br/> initcomponents (); <br/>}</P> <p> private void initcomponents () {<br/> jpanel Part1, Part2; <br/> setlayout (New Java. AWT. gridlayout (); <br/> Part1 = new jpanel (); <br/> part1.setlayout (New Java. AWT. flowlayout (Java. AWT. flowlayout. left); <br/> tiplabel = new jlabel (""); <br/> part1.add (tiplabel); <br/> Add (Part1 ); <br/> Part2 = new jpanel (); <br/> part2.setlayout (New Java. AWT. flo Wlayout (Java. AWT. flowlayout. right); <br/> msglabel = new jlabel ("RunTime tool (run)"); <br/> part2.add (msglabel ); <br/> bar = new jprogressbar (); <br/> part2.add (bar); <br/> separator1 = new jseparator (); <br/> separator1.setorientation (javax. swing. swingconstants. vertical); <br/> part2.add (separator1); <br/> // closebutton = new jbutton (createimageicon ("images/close.jpg ")); <br/> // part2.add (closebutton); <br /> Xlabel = new jlabel ("0"); <br/> part2.add (xlabel); <br/> ylabel = new jlabel ("0 "); <br/> part2.add (ylabel); <br/> endlabel = new jlabel ("ins"); <br/> part2.add (endlabel ); <br/> Add (Part2); <br/> barhide (); <br/>}< br/> Public void barhide () {<br/> msglabel. settext (null); <br/> bar. setvisible (false); <br/>}< br/> Public void barshow () {<br/> bar. setvisible (true); <br/> bar. setindeterminate (true); <B R/>}< br/> Public void setbarmsg (string MSG) {<br/> msglabel. settext (MSG); <br/>}< br/> Public void setbarinfo (string MSG) {<br/> tiplabel. settext (MSG); <br/>}< br/> Public void setbarindeterminate (Boolean flag) {<br/> bar. setindeterminate (FLAG); <br/>}< br/> Public void setbarvalue (INT value) {<br/> bar. setvalue (value); <br/>}< br/> Public void setbarmaximum (INT max) {<br/> bar. setmaximum (M Ax); <br/>}< br/> Private Static imageicon createimageicon (string path) {<br/> java.net. URL imgurl = statusbar. class. getresource (PATH); <br/> If (imgurl! = NULL) {<br/> return New imageicon (imgurl); <br/>}else {<br/> system. err. println ("couldn't find file:" + path); <br/> return NULL; <br/>}< br/> private jprogressbar; <br/> private jlabel tiplabel; <br/> private jlabel msglabel; <br/> private jlabel endlabel; <br/> private jlabel xlabel; <br/> private jlabel ylabel; <br/> private jseparator separator1; <br/> private jbutton closebutton; <br/>}< br/>