Jtree (node rendering + Resource Manager) (2)

Source: Internet
Author: User
Tags comparable

The last time we created a relatively simple Resource Manager, this time we talked about the above resource manager problems, and we should try to be close to the Windows Resource Manager.

This simple Resource Management tree is complete. Let's talk about its problems:

① There is a gap between pictures and appearance and windows

We can solve this problem by setting L & F and setting a new image like Renderer.

② When there are many files in the folder, the meeting is very slow and the interface will be suspended

In this case, we can write a slow loading treenode to inherit from defaultmutabletreenode, define the loading ID in it, and then use swingworker or multithreading to load the tree smoothly, though it is troublesome, but it can also be solved.

③ When a tree click is suspended, the user will think that there is a problem. Multiple events will be loaded when a random click occurs.

This problem is actually a problem of the swing event mechanism, but it cannot be solved because there will always be time-consuming operations and it is impossible not to wait. but we can do a better user experience to avoid this problem. The solution here is to draw a layer of glason the tree, block all events, and prompt users. After loading is complete, cancel the glasspane interface.

④ There are only basic files on my computer and no network neighbors.

This problem is very difficult to solve. The network problem exists when it comes to network neighbors, and network connection and scanning are also required. My idea is to use the commons-client of Apache, later, we found that some people have provided a better way to use Java's jfilechooser class. Java has implemented a lot of things we need to implement.

⑤ Sub-directories of the obtained Resource Management tree are out of order

This is a good solution, so that our treenode can implement the comparable interface.

To solve these five problems, we have made the release version:

First, let's solve problem 1 and look at our code:

We can set the Renderer for node image styles, and because these images can be obtained in the jfilechooser UI, we will first create a FileView class by referring to the jfilechooser UI:

//***********************

// * FileView operations *

//***********************

ProtectedClassBasicfileviewExtendsFileView {

Method to rewrite it:

@ Override

PublicString getname (file F ){

// Note: returns display name rather than file name

String filename =Null;

If(F! =Null){

Filename = chooser. getfilesystemview (). getsystemdisplayname (f );

}

ReturnFilename;

}

This is the display name.

@ Override

PublicString getdescription (file F ){

ReturnF. getname ();

}

This is the description

@ Override

PublicString gettypedescription (file F ){

String type = chooser. getfilesystemview (). getsystemtypedescription (

F );

If(Type =Null){

If(F. isdirectory ()){

Type = directorydescriptiontext;

}Else{

Type = filedescriptiontext;

}

}

ReturnType;

}

This is the file type.

@ Override

PublicIcon getIcon (file F ){

This is an image representation.

In this way, the image and name we need after building this FileView can be obtained.

Then there is our Renderer:

PrivateClassFilesystemtreerendererExtendsDefaulttreecellrenderer {

Rewrite its method, set the image and name we get from FileView:

@ Override

PublicComponent gettreecellrenderercomponent (jtree tree, object value,BooleanSel,BooleanExpanded,BooleanLeaf,IntRow,

BooleanHasfocus ){

Settext (getfileview (chooser). getname (node. GetFile ()));

Seticon (getfileview (chooser). getIcon (node. GetFile ()));

Then set it to the tree:

Tree. setcellrenderer (NewFilesystemtreerenderer ());

See the results:

Is it very close to Windows? Set L & F, for example:

Uimanager.Setlookandfeel(Uimanager.Getsystemlookandfeelclassname());

Then solve problem 2. We cannot use the original node of the tree. We construct it ourselves and inherit from it:

PublicAbstractClassLazymutabletreenodeExtendsDefaultmutabletreenode {

Add an attribute:

/** Is node load .*/

PrivateBooleanLoaded =False;

Provide a virtual method for subclass implementation:

ProtectedAbstractVoidLoadchildren ();

Then our implementation:

PrivateClassFiletreenodeExtendsLazymutabletreenode {

Rewrite its method. loading is not allowed for non-load:

@ Override

PublicBooleanIsleaf (){

If(! Isloaded ()){

ReturnFalse;

}Else{

ReturnSuper. Isleaf ();

}

}

And its real name:

@ Override

PublicString tostring (){

ReturnChooser. getfilesystemview (). getsystemdisplayname (

(File) getuserobject ());

}

Implementation of Virtual Methods:

@ Override

ProtectedVoidLoadchildren (){

Filetreenode [] nodes = getchildren ();

For(IntI = 0, c = nodes. length; I <C; I ++ ){

Add (nodes [I]);

}

}

In this way, problem 2 is solved, and problem 5 can also be solved here, so that our treenode implements the comparable interface:

PrivateClassFiletreenodeExtendsLazymutabletreenodeImplements

Comparable <Object> {

Then the implementation method is as follows:

@ Override

PublicIntCompareto (Object O ){

If(! (OInstanceofFiletreenode )){

Return1;

}

ReturnGetFile (). compareto (filetreenode) O). GetFile ());

}

Finally, in our use:

// Sort directories, filetreenode implements comparable

Filetreenode [] result = (filetreenode []) nodes

. Toarray (NewFiletreenode [0]);

Arrays.Sort(Result );

Nodes. Add (NewFiletreenode (result [I]);

In this way, all the node folders we add are sorted.

Then, let's solve problem 4. Three is more difficult to stay at the end:

When building this component, we first build jfilechooser

Jfilechooser chooser =NewJfilechooser ();

Add listeners:

ProtectedVoidInstalllisteners (){

Tree. addtreeselectionlistener (NewSelectionlistener ());

Chooser. getactionmap (). Put ("refreshtree ",NewUpdateaction ());

Chooser. getinputmap (jcomponent.When_ancestor_of_focused_component). Put (

Keystroke.Getkeystroke("F5"), "refreshtree ");

Chooser. addpropertychangelistener (NewChangelistener ());

}

When expanding the tree in the listener, use the jfilechooser method:

/**

* Tree node select change.

*/

PrivateClassSelectionlistenerImplementsTreeselectionlistener {

@ Override

PublicVoidValuechanged (treeselectionevent e ){

Getapproveselectionaction ()

. Setenabled (tree. getselectioncount ()> 0 );

Setselectedfiles ();

// The current directory is the one currently selected

Treepath currentdirectorypath = tree. getselectionpath ();

If(Currentdirectorypath! =Null){

File currentdirectory = (filetreenode) currentdirectorypath

. Getlastpathcomponent (). GetFile ();

Chooser. setcurrentdirectory (currentdirectory );

}

}

}

In this way, we do not need to construct all our directory structures cyclically. We can use jfilechooser to provide us with a good solution. For example, there are network neighbors. Problem 4 is completed:

Finally, let's solve problem 3. Why is it suspended? It is caused by many folders or slow network speeds. The solution is of course multithreading, but multithreading is prone to thread insecurity in swing, because it is not on the ADT, here we use swingworker to listen to the expand event of the tree:

Tree. addtreeexpansionlistener (NewTreeexpansion ());

Process it:

PrivateClassTreeexpansionImplementsTreeexpansionlistener {

@ Override

PublicVoidTreecollapsed (treeexpansionevent event ){

}

@ Override

PublicVoidTreeexpanded (treeexpansionevent event ){

// Ensure children gets expanded later

If(Event. getpath ()! =Null){

Object lastelement = event. getpath (). getlastpathcomponent ();

If(LastelementInstanceofFiletreenode & usenodequeue)

If(Filetreenode) lastelement). isloaded ()){

Slow processing is mainly here. We put it in swingworker:

NewWorkerqueue (node, tree, glasspane0000.exe cute ();

Then let's look at this class:

PrivateStaticFinalClassWorkerqueueExtends

Swingworker <void, filetreenode> {

Rewrite its method to handle the event added to our treenode:

@ Override

ProtectedVoid doinbackground ()ThrowsException {

Glasspanel. setvisible (True);

For(Enumeration <?> E = node. Children (); E. hasmoreelements ();){

Publish (filetreenode) E. nextelement ());

}

ReturnNull;

}

@ Override

ProtectedVoidProcess (list <filetreenode> chunks ){

For(Filetreenode: chunks ){

Filetreenode. getchildcount ();

}

}

@ Override

ProtectedVoidDone (){

Glasspanel. setvisible (False);

Tree. repaint ();

}

Then we will block all mouse clicks and give the user a prompt when expanding the node. Here we will draw a component and set it to glasspane to block all events:

/**

*/

PublicClassGlasspaneExtendsJcomponent {

All events are blocked and only focus is obtained:

// Blocks all user input

Addmouselistener (NewMouseadapter (){

});

Addmousemotionlistener (NewMousemotionadapter (){

});

Addkeylistener (NewKeyadapter (){

});

Setfocustraversalkeysenabled (False);

Addcomponentlistener (NewComponentadapter (){

PublicVoidComponentshown (componentevent EVT ){

Requestfocusinwindow ();

}

});

Then draw:

@ Override

ProtectedVoidPaintcomponent (Graphics g ){

First, draw the overall background:

// Gets the current clipping Area

Rectangle clip = G. getclipbounds ();

// Sets a 65% translucent Composite

Alphacomposite alpha = alphacomposite.Srcover. Derive (0.65f );

Composite composite = g2.getcomposite ();

G2.setcomposite (alpha );

// Fills the background

G2.setcolor (getbackground ());

G2.fillrect (clip. X, Clip. Y, Clip. Width, Clip. Height );

G2.setcomposite (composite );

Then I drew a prompt image. I wanted to draw a scroll wait icon, but I was not in the mood to write it. I put a picture on Google.

If(Image =Null){

Try{

Image = ImageIO.Read(Getclass (). getresource ("wait2.jpg "));

}Catch(Ioexception ex ){

Ex. printstacktrace ();

}

}

G. drawimage (image, getwidth ()/2-40, getheight ()/2

-80,120,120,Null);

Set the glasspane of the screen.

Component glasspane =NewGlasspane ();

Frame. getrootpane (). setglasspane (glasspane );

------ Not completed. It will be available later. Leave a tail

Jtree (node rendering + Resource Manager) (2)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.