Toon posts:

[java][JTree] Custom DefaultMutableTreeNode

Pagina: 1
Acties:

Verwijderd

Topicstarter
Beste GoT'ers,

Ik ben bezig met het maken van een FileExplorer object, dat met behulp van een JTree een file explorer weergeeft. Nu wil ik per node een icon afhankelijk van het bestandstype (gewoon bestand of map). Elke node is FileNode (static class binnen FileExplorer class). Het file object behorend bij elk bestand/map in de tree wordt opgeslagen in het userObject van de node.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    static class FileNode extends DefaultMutableTreeNode 
    {
        private boolean childrenLoaded = false;
        private int childrenCount = 0;
        private FileFilter fileFilter;
    
        FileNode(File file, FileFilter fileFilter)
        {
            super(file);
            
            this.fileFilter = fileFilter;
        }

        public File getFile() 
        {
            return (File)userObject;
        }

        public boolean areChildrenLoaded() {}

        public int getChildCount()  {}

        public Enumeration children()  {}

        public boolean isLeaf() {}

        private void populateChildren()  {}

        public String toString() 
        {
            return fsv.getSystemDisplayName(getFile());
        }

        public boolean equals(Object o)  {}

    }

Bij het renderen van de tree wil ik mbv een getFile().isDirectory() bepalen of er een map icoon gebruikt moet worden of niet. Het renderen gebeurt met FileExplorerCellRenderer:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class FileExplorerCellRenderer extends JLabel implements TreeCellRenderer
{
    private Icon folderIcon;
    private Icon fileIcon;
    private boolean bSelected;

    public FileExplorerCellRenderer() {
        folderIcon = new ImageIcon(this.getClass().getClassLoader().getResource("folder.gif"));
        fileIcon = new ImageIcon(this.getClass().getClassLoader().getResource("file.gif"));
    }

    public Component getTreeCellRendererComponent( JTree tree,
        Object value, boolean bSelected, boolean bExpanded,
        boolean bLeaf, int iRow, boolean bHasFocus )
    {
        // Find out which node we are rendering and get its file object
        FileExplorer.FileNode node = (FileExplorer.FileNode)value;

        this.bSelected = bSelected;
        
        // Set the correct foreground color
        if( !bSelected )
            setForeground( Color.black );
        else
            setForeground( Color.white );

        if (node.getFile().isDirectory())
        {
            setIcon( folderIcon );
        } 
        else 
        {
            setIcon( fileIcon );
        }

        // Add the text to the cell
        setText( node.toString() );

        return this;
    }

    public void paint( Graphics g ) {}

}


Nu gaat het fout bij de volgende regel:
Java:
1
        FileExplorer.FileNode node = (FileExplorer.FileNode)value;

Java geeft de volgende error:
code:
1
java.lang.ClassCastException: javax.swing.tree.DefaultMutableTreeNode
value is kennelijk om de een of andere reden een DefaultMutableTreeNode. Iemand enig idee waarom, of hoe ik op een andere manier het file object op kan halen uit de node?

Bvd.

[ Voor 29% gewijzigd door Verwijderd op 03-05-2005 17:51 . Reden: eea ingekort ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Value!=node :) Ik geloof dat de value het ding is dat je defaultmutabletreenode als value in zich heeft (hij heeft namelijk ook een getUserObject methode). Ik weet het niet zeker meer aangezien het al jaren geleden is dat ik iets met de JTree heb gedaan.

Een ongelovelijk minpunt aan de classcast exception is dat hij niet zegt wat de orginele class is.

[ Voor 19% gewijzigd door Alarmnummer op 03-05-2005 17:39 ]


Verwijderd

Topicstarter
Alarmnummer schreef op dinsdag 03 mei 2005 @ 17:36:
Value!=node :) Ik geloof dat de value het ding is dat je defaultmutabletreenode als value in zich heeft (hij heeft namelijk ook een getvalue methode).

Een ongelovelijk minpunt aan de classcast exception is dat hij niet zegt wat de orginele class is.
Maar als ik ervan maak:
code:
1
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
dan werkt het wel, maar heb ik dus geen fileobject meer :). Dit staat ook veel @ voorbeeldcode @ internet.

Erg vreemd, want als ik een String in de userObject stop van de node, kan ik die vervolgens wel met
code:
1
2
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
String mystring = (String)node.getUserObject();

ophalen. Dus op de een of andere manier is mijn FileNode dan een DefaultMutableTreeNode geworden. Geen punt op zich, als ik mijn file ding dan op dezelfde manier uit het userObject te halen, maar dan begint ie te miepen dat ie een String niet naar File kan casten. /me confuzzled.

[ Voor 33% gewijzigd door Verwijderd op 03-05-2005 17:42 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Hmm tja.. dan weet ik het ook niet meer :) Ik vond zelf die JTree nogal gecompliceerd en werk zelf liever via treemodels.

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 07-05 19:18

Robtimus

me Robtimus no like you

Is ELKE node een FileNode? Want als er ook maar 1 node van een andere class is gaat dit fout.

Verder kun je natuurlijk ook gewoon je file als userobject gebruiken en dan de userobject naar file casten in je cellrenderer:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    public Component getTreeCellRendererComponent( JTree tree, 
        Object value, boolean bSelected, boolean bExpanded, 
        boolean bLeaf, int iRow, boolean bHasFocus ) 
    { 
        // Find out which node we are rendering and get its file object 
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
        File f = (File)node.getUserObject();

        this.bSelected = bSelected; 
         
        // Set the correct foreground color 
        if( !bSelected ) 
            setForeground( Color.black ); 
        else 
            setForeground( Color.white ); 

        if (f != null && f.isDirectory())
        { 
            setIcon( folderIcon ); 
        }  
        else  
        { 
            setIcon( fileIcon ); 
        } 

        // Add the text to the cell 
        setText( fsv.getSystemDisplayName(f) ); 

        return this;
    }

Verder tot slot even een opmerking dat ik dit wel werkend heb gekregen, zij het met een check:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        String stringValue = tree.convertValueToText(
            value, isSelected, expanded, leaf, row, hasFocus
        );
        setEnabled(tree.isEnabled());
        if (value instanceof CheckNode)
        {
            CheckNode cnode = (CheckNode)value;
            check.setSelected(cnode.isSelected());
            Object data = cnode.getUserObject();
            // do stuff with data
        }
        else
        {
            label.setText(stringValue);
        }
En ook ik heb dit van internet gehaald ;)

[ Voor 48% gewijzigd door Robtimus op 03-05-2005 18:00 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

Topicstarter
IceManX: \o/ Het lijkt nu inderdaad te werken door die check in te bouwen. Tnx _/-\o_.

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 07-05 19:18

Robtimus

me Robtimus no like you

Komt omdat je met die check weet dat ie van dat type is. Vergeet alleen niet de else, voor als het toch geen FileNode is.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

Topicstarter
IceManX schreef op dinsdag 03 mei 2005 @ 20:09:
Komt omdat je met die check weet dat ie van dat type is. Vergeet alleen niet de else, voor als het toch geen FileNode is.
Inderdaad gedaan. Volgens mij gooit die JTree zichzelf automatisch vol met allerlei vreemde DefaultMutableNodes (Colors -> Green, Blue, etc) als er nog geen model geselecteerd is. En dat probeert hij dan dus ook al te renderen.
Pagina: 1