# JTree Datei Icons ?



## Steffan (12. Mrz 2004)

Ich hab einen JTree jedoch zeigt er mir nur bei Verzeichnissen ein Icon vor den Namen an. Bei Daten ist nur so ein Kreis. Es Gab doch eine Klasse/Methode die automatisch vor jede Datei das richtige icon setzt (txt, zip, ....).

Hier noch mein TreeModel Code.

```
class FileTreeModel
	  implements TreeModel {

	protected myFile root; // Wurzel
	
	
	public void erneuerTree(){
		
	}
	
	public FileTreeModel(myFile root) {
	  this.root = root;
	}

	public void setroot(myFile pathnamer) {
	  this.root = pathnamer;
	}

	public Object getRoot() {
	  return root;
	} // Liefert die Wurzel des Funktionsbaumes

	public boolean isLeaf(Object node) {
	  return ( (myFile) node).isFile();
	} // ist es ein Blatt oder nicht

	private Vector listeners = new Vector();

	public int getChildCount(Object parent) { //bekommt object Eltern und soll Anzahl Kind-Knoten dieses Knotens liefern
	  String[] children = ( (myFile) parent).list(); //gibt String Liste von parent
	  if (children == null)return 0; //wenn keine children dann 0
	  return children.length; // sonst Länge der Kinder zurückgeben
	}

	public Object getChild(Object parent, int index) { // bekommt parent und Index des gesuchten Kind-Knotens und liefert Object Kind-Knoten
	  String[] children = ( (myFile) parent).list(); //gibt String Liste von parent
	  if ( (children == null) || (index >= children.length))return null;
	  return new myFile( (myFile) parent, children[index]);
	}

	public int getIndexOfChild(Object parent, Object child) { //bekommt parent und object Kind
	  String[] children = ( (myFile) parent).list();
	  if (children == null)return -1; //wenn kinder 0 dann ende -1
	  String childname = ( (myFile) child).getName(); //String name des Kindes ist
	  //childname = childname.substring(0,6);
	  for (int i = 0; i > children.length; i++) {
		if (childname.equals(children[i]))return i;
	  }
	  return -1;
	}

	public void valueForPathChanged(TreePath path, Object newvalue) {} // Wird aufgerufen, wenn der Wert für den Pfad geändert wurde.

	public void addTreeModelListener(TreeModelListener l) {
	  listeners.add(l);
	} 

	public void removeTreeModelListener(TreeModelListener l) {} // Entfernt den Listener        

  }
```

und so wird mein JTree erzeugt

```
myFile root = new myFile(System.getProperty("file.separator"));
final FileTreeModel model = new FileTreeModel(root);
jTree = new javax.swing.JTree(model);
```


----------



## Beni (12. Mrz 2004)

Stimmt, die gab es: javax.swing.filechooser.FileSystemView.getSystemIcon( File file );

Allerdings musst Du noch einen eigenen TreeCellRenderer implementieren. Schau die den DefaultTreeCellRenderer an, den kannst du recht einfach erweitern.


----------



## steffan (17. Mrz 2004)

Also ich muss erst eine neue Klasse erstellen die DefaultTreeCellRenderer erweitert:


```
class Renderer extends DefaultTreeCellRenderer{
```

dann fehlt ja noch mein Konstruktor:

```
private FileSystemView system;

    public Renderer(){
      system = FileSystemView.getFileSystemView();
    }
```

was fehlt da jetzt noch?

muss ich dann die Instanz der Klasse im TreeModel aufrufen und dann mein File übergeben was ich im TreeModel erhalte? 


```
setIcon( system.getSystemIcon( file ) );
```


----------



## Beni (17. Mrz 2004)

Den Renderer übergibst du dem JTree. JTree.setCellRenderer. Danach wird der JTree die Methode getTreeCellRendererComponent aufrufen, die du noch erweitern musst:


```
public class Renderer extends DefaultTreeCellRenderer{
  public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus){
    super.getTreeCellRendererComponent( tree, value, selected, expanded, leaf, row, hasFocus );

    setIcon( // Das Icon das zu value gehört );

    return this;
  }
}
```


----------



## steffan (17. Mrz 2004)

Das bedeutet doch aber das ich bei setIcon vorgeben muss für welche Datein er ein Icon setzten soll oder? Kann ich nicht einfach angeben das er für alle Datein Icons setzten soll egal wechle Endung sie haben?

Und im HauptProgramm müßte doch dann der Aufruf so sein:

```
tree.setCellRenderer(new Renderer());
```


----------



## Beni (17. Mrz 2004)

Der Aufruf muss da sein, ja.

Also: der JTree kann nicht alles. Er bietet eine Grundkonstruktion, die du mit "Plugins" erweitern musst.
Die Plugins musst du selber schreiben.

In deinem Fall ist _value_ ein _myFile_, zusammen mit meiner ersten Antwort sollte es dir doch möglich sein, das Icon (passend zum Dateityp) innert einer Zeile herauszufinden!

mfg Beni


----------



## Guest (17. Mrz 2004)

Könnte ich das so aufbauen? Jedoch gibs in der Klasse File eine Methode die meine Endung vergleicht?


```
public class Renderer extends DefaultTreeCellRenderer{ 
	public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus){ 
	  super.getTreeCellRendererComponent( tree, value, selected, expanded, leaf, row, hasFocus ); 
	  myFile f = (myFile)value;
	  if (bestimmte Eigenschaften von f){
	  	 this.setIcon(new ImageIcon("wasmanwill.jpg|gif|png(?)")); 
	  }
	  return this; 
	} 
  }
```


----------



## Beni (17. Mrz 2004)

Ich kenne keine Vergleichsmethode, muss man wohl selber schreiben.

Aber ein Tipp: speichere die Images, wenn du sie jedesmal neu lädts ( new... ) wird dein Progi _sehr _langsam.


----------



## Craven (17. Mrz 2004)

Hallo Leute!
Also ich habe auch genau dieses Problem! Folgenden Vorschlag hab ich gefunden:


```
public class FileTreeCellRenderer extends JLabel
                                                implements TreeCellRenderer 
{
  public Component getTreeCellRenderer Component ( JTree tree, Object value, [und Zeugs] ) {
    File f = (File)value;
    this.setText(f.getName());
    if ( bestimmte Eigenschaft von f ) {
      this.setIcon(new ImageIcon("....jpg|gif|png"));
    }
    return this;
  }
}
```


im Hauptprogramm:


```
JTree tree = new JTree();
tree.setCellRenderer( new FileTreeCellRenderer() );
```

Das Problem dabei ist, daß egal was ich probiert habe, das Teil funktioniert nicht. Vielleicht kann sich jemand die Mühe machen und ein komplettes Beispiel stricken?! Das wär echt toll!

Gruß
Craven


----------



## steffan (17. Mrz 2004)

Ja genau das gleiche hab ich auch gefunden.

ich verstehe auch nicht was ich da reinschreiben muss?

```
ImageIcon(""));
```

kann man denn das so schreiben dann?

```
ImageIcon("jpg|gif")
```


----------



## Beni (17. Mrz 2004)

Woher auch immer ihr dieses Beispiel habt, es ist schlecht.

1. Schaut doch mal hier nach, was ImageIcon für ein Argument benötigt. Ein korrekter Pfad zu einer existierenden Datei.

2. Speichert die ImageIcons irgendwo ausserhalb der Methode. Mit tausenden _new ImageIcon_ verschwendet ihr soviel Ressourcen...

Eine Hashtable bietet sich an:
	
	
	
	





```
Hashtable icons = new Hashtable();

// so füllen
icons.put( "txt", new ImageIcon( "data/txt_icon.png" ) );

// so lesen
Icon icon = (Icon)icons.get( "txt" );
```


----------



## steffan (17. Mrz 2004)

Ach so man muss das Icon Symbol selber haben? Ich dachte Java hat die Icon Symbole schon.


----------



## Craven (17. Mrz 2004)

Das mit


```
ImageIcon("jpg|gif");
```

funktioniert so selbstverstänlich nicht! Der "|" steht für "oder"!

Und daß man die einzelnen Icons erzeugen muß ist denk ich mal auch klar!

Allerdings, wie läßt sich das alles zusammenfügen?!

Vielleicht kann jemand ein komplettes Beispiel posten. 

Gruß
Craven


----------



## Beni (17. Mrz 2004)

Dass ich mich mal selber zitieren muss, hätte ich nicht gedacht 



			
				Beni hat gesagt.:
			
		

> Stimmt, die gab es: javax.swing.filechooser.FileSystemView.getSystemIcon( File file );
> 
> Allerdings musst Du noch einen eigenen TreeCellRenderer implementieren. Schau die den DefaultTreeCellRenderer an, den kannst du recht einfach erweitern.





			
				Beni hat gesagt.:
			
		

> In deinem Fall ist value ein myFile, zusammen *mit meiner ersten Antwort* sollte es dir doch möglich sein, das Icon (passend zum Dateityp) innert einer Zeile herauszufinden!





			
				steffan hat gesagt.:
			
		

> Ach so man muss das Icon Symbol selber haben? Ich dachte Java hat die Icon Symbole schon.



Nur genauer lesen :wink:
Das mit dem ImageIcon kommt von dem (deinem?) Vorschlag: "Könnte ich das auch so aufbauen...". Da bin ich umgeschwenkt.

mfg Beni


----------



## Craven (17. Mrz 2004)

Ich glaub, ich hab ein komplettes Beispiel gefunden! Hab aber keine Bilder hier!

Kann das Beispiel mal jemand ausprobieren und das Ergebnis posten?!


```
// Imports
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;

class RenderTreeExample
		extends 	JFrame
 {
	// Instance attributes used in this example
	private	JPanel		topPanel;
	private	JTree		tree;
	private	JScrollPane scrollPane;

	// Constructor of main frame
	public RenderTreeExample()
	{
		// Set the frame characteristics
		setTitle( "Custom Rendered Tree Application" );
		setSize( 300, 200 );
		setBackground( Color.gray );

		// Create a panel to hold all other components
		topPanel = new JPanel();
		topPanel.setLayout( new BorderLayout() );
		getContentPane().add( topPanel );

		// Create data for the tree
		DefaultMutableTreeNode root
					= new DefaultMutableTreeNode( "Deck" );

		DefaultMutableTreeNode itemClubs
					= new DefaultMutableTreeNode( "Clubs" );
		addAllCard( itemClubs );
		root.add( itemClubs );

		DefaultMutableTreeNode itemDiamonds
					= new DefaultMutableTreeNode( "Diamonds" );
		addAllCard( itemDiamonds );
		root.add( itemDiamonds );

		DefaultMutableTreeNode itemSpades
					= new DefaultMutableTreeNode( "Spades" );
		addAllCard( itemSpades );
		root.add( itemSpades );

		DefaultMutableTreeNode itemHearts
					= new DefaultMutableTreeNode( "Hearts" );
		addAllCard( itemHearts );
		root.add( itemHearts );

		// Create a new tree control
		DefaultTreeModel treeModel = new DefaultTreeModel( root );
		tree = new JTree( treeModel );

        // Tell the tree it is being rendered by our application
        tree.setCellRenderer( new CustomCellRenderer() );

		// Add the listbox to a scrolling pane
		scrollPane = new JScrollPane();
		scrollPane.getViewport().add( tree );
		topPanel.add( scrollPane, BorderLayout.CENTER );
	}

	// Helper method to write an enitre suit of cards to the
	// current tree node
	public void addAllCard( DefaultMutableTreeNode suit )
	{
		suit.add( new DefaultMutableTreeNode( "Ace" ) );
		suit.add( new DefaultMutableTreeNode( "Two" ) );
		suit.add( new DefaultMutableTreeNode( "Three" ) );
		suit.add( new DefaultMutableTreeNode( "Four" ) );
		suit.add( new DefaultMutableTreeNode( "Five" ) );
		suit.add( new DefaultMutableTreeNode( "Six" ) );
		suit.add( new DefaultMutableTreeNode( "Seven" ) );
		suit.add( new DefaultMutableTreeNode( "Eight" ) );
		suit.add( new DefaultMutableTreeNode( "Nine" ) );
		suit.add( new DefaultMutableTreeNode( "Ten" ) );
		suit.add( new DefaultMutableTreeNode( "Jack" ) );
		suit.add( new DefaultMutableTreeNode( "Queen" ) );
		suit.add( new DefaultMutableTreeNode( "King" ) );
	}

	// Main entry point for this example
	public static void main( String args[] )
	{
		// Create an instance of the test application
		RenderTreeExample mainFrame	= new RenderTreeExample();
		mainFrame.setVisible( true );
	}
}

The code listing for CustomCellRenderer.java is: 


// Imports
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;

public class CustomCellRenderer
		extends		JLabel
		implements	TreeCellRenderer
{
   private ImageIcon		deckImage;
   private ImageIcon[]		suitImages;
   private ImageIcon[]		cardImages;
	private boolean			bSelected;


	public CustomCellRenderer()
	{
		// Load the images
		deckImage = new ImageIcon( "deck.gif" );

		suitImages = new ImageIcon[4];
		suitImages[0] = new ImageIcon( "clubs.gif" );
		suitImages[1] = new ImageIcon( "diamonds.gif" );
		suitImages[2] = new ImageIcon( "spades.gif" );
		suitImages[3] = new ImageIcon( "hearts.gif" );

		cardImages = new ImageIcon[13];
		cardImages[0] = new ImageIcon( "ace.gif" );
		cardImages[1] = new ImageIcon( "two.gif" );
		cardImages[2] = new ImageIcon( "three.gif" );
		cardImages[3] = new ImageIcon( "four.gif" );
		cardImages[4] = new ImageIcon( "five.gif" );
		cardImages[5] = new ImageIcon( "six.gif" );
		cardImages[6] = new ImageIcon( "seven.gif" );
		cardImages[7] = new ImageIcon( "eight.gif" );
		cardImages[8] = new ImageIcon( "nine.gif" );
		cardImages[9] = new ImageIcon( "ten.gif" );
		cardImages[10] = new ImageIcon( "jack.gif" );
		cardImages[11] = new ImageIcon( "queen.gif" );
		cardImages[12] = new ImageIcon( "king.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 text
		DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
		String	labelText = (String)node.getUserObject();

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

		// Determine the correct icon to display
		if( labelText.equals( "Deck" ) )
			setIcon( deckImage );
		else if( labelText.equals( "Clubs" ) )
			setIcon( suitImages[0] );
		else if( labelText.equals( "Diamonds" ) )
			setIcon( suitImages[1] );
		else if( labelText.equals( "Spades" ) )
			setIcon( suitImages[2] );
		else if( labelText.equals( "Hearts" ) )
			setIcon( suitImages[3] );
		else if( labelText.equals( "Ace" ) )
			setIcon( cardImages[0] );
		else if( labelText.equals( "Two" ) )
			setIcon( cardImages[1] );
		else if( labelText.equals( "Three" ) )
			setIcon( cardImages[2] );
		else if( labelText.equals( "Four" ) )
			setIcon( cardImages[3] );
		else if( labelText.equals( "Five" ) )
			setIcon( cardImages[4] );
		else if( labelText.equals( "Six" ) )
			setIcon( cardImages[5] );
		else if( labelText.equals( "Seven" ) )
			setIcon( cardImages[6] );
		else if( labelText.equals( "Eight" ) )
			setIcon( cardImages[7] );
		else if( labelText.equals( "Nine" ) )
			setIcon( cardImages[8] );
		else if( labelText.equals( "Ten" ) )
			setIcon( cardImages[9] );
		else if( labelText.equals( "Jack" ) )
			setIcon( cardImages[10] );
		else if( labelText.equals( "Queen" ) )
			setIcon( cardImages[11] );
		else if( labelText.equals( "King" ) )
			setIcon( cardImages[12] );

		// Add the text to the cell
		setText( labelText );

		return this;
	}

	// This is a hack to paint the background.  Normally a JLabel can
	// paint its own background, but due to an apparent bug or
	// limitation in the TreeCellRenderer, the paint method is
	// required to handle this.
	public void paint( Graphics g )
	{
		Color		bColor;
		Icon		currentI = getIcon();

		// Set the correct background color
		bColor = bSelected ? SystemColor.textHighlight : Color.white;
		g.setColor( bColor );

		// Draw a rectangle in the background of the cell
		g.fillRect( 0, 0, getWidth() - 1, getHeight() - 1 );

		super.paint( g );
	}

}
```

Chiao
Craven


----------



## Craven (17. Mrz 2004)

Ich glaub, ich hab ein komplettes Beispiel gefunden! Hab aber keine Bilder hier!

Kann das Beispiel mal jemand ausprobieren und das Ergebnis posten?!


```
// Imports
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;

class RenderTreeExample
		extends 	JFrame
 {
	// Instance attributes used in this example
	private	JPanel		topPanel;
	private	JTree		tree;
	private	JScrollPane scrollPane;

	// Constructor of main frame
	public RenderTreeExample()
	{
		// Set the frame characteristics
		setTitle( "Custom Rendered Tree Application" );
		setSize( 300, 200 );
		setBackground( Color.gray );

		// Create a panel to hold all other components
		topPanel = new JPanel();
		topPanel.setLayout( new BorderLayout() );
		getContentPane().add( topPanel );

		// Create data for the tree
		DefaultMutableTreeNode root
					= new DefaultMutableTreeNode( "Deck" );

		DefaultMutableTreeNode itemClubs
					= new DefaultMutableTreeNode( "Clubs" );
		addAllCard( itemClubs );
		root.add( itemClubs );

		DefaultMutableTreeNode itemDiamonds
					= new DefaultMutableTreeNode( "Diamonds" );
		addAllCard( itemDiamonds );
		root.add( itemDiamonds );

		DefaultMutableTreeNode itemSpades
					= new DefaultMutableTreeNode( "Spades" );
		addAllCard( itemSpades );
		root.add( itemSpades );

		DefaultMutableTreeNode itemHearts
					= new DefaultMutableTreeNode( "Hearts" );
		addAllCard( itemHearts );
		root.add( itemHearts );

		// Create a new tree control
		DefaultTreeModel treeModel = new DefaultTreeModel( root );
		tree = new JTree( treeModel );

        // Tell the tree it is being rendered by our application
        tree.setCellRenderer( new CustomCellRenderer() );

		// Add the listbox to a scrolling pane
		scrollPane = new JScrollPane();
		scrollPane.getViewport().add( tree );
		topPanel.add( scrollPane, BorderLayout.CENTER );
	}

	// Helper method to write an enitre suit of cards to the
	// current tree node
	public void addAllCard( DefaultMutableTreeNode suit )
	{
		suit.add( new DefaultMutableTreeNode( "Ace" ) );
		suit.add( new DefaultMutableTreeNode( "Two" ) );
		suit.add( new DefaultMutableTreeNode( "Three" ) );
		suit.add( new DefaultMutableTreeNode( "Four" ) );
		suit.add( new DefaultMutableTreeNode( "Five" ) );
		suit.add( new DefaultMutableTreeNode( "Six" ) );
		suit.add( new DefaultMutableTreeNode( "Seven" ) );
		suit.add( new DefaultMutableTreeNode( "Eight" ) );
		suit.add( new DefaultMutableTreeNode( "Nine" ) );
		suit.add( new DefaultMutableTreeNode( "Ten" ) );
		suit.add( new DefaultMutableTreeNode( "Jack" ) );
		suit.add( new DefaultMutableTreeNode( "Queen" ) );
		suit.add( new DefaultMutableTreeNode( "King" ) );
	}

	// Main entry point for this example
	public static void main( String args[] )
	{
		// Create an instance of the test application
		RenderTreeExample mainFrame	= new RenderTreeExample();
		mainFrame.setVisible( true );
	}
}

The code listing for CustomCellRenderer.java is: 


// Imports
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;

public class CustomCellRenderer
		extends		JLabel
		implements	TreeCellRenderer
{
   private ImageIcon		deckImage;
   private ImageIcon[]		suitImages;
   private ImageIcon[]		cardImages;
	private boolean			bSelected;


	public CustomCellRenderer()
	{
		// Load the images
		deckImage = new ImageIcon( "deck.gif" );

		suitImages = new ImageIcon[4];
		suitImages[0] = new ImageIcon( "clubs.gif" );
		suitImages[1] = new ImageIcon( "diamonds.gif" );
		suitImages[2] = new ImageIcon( "spades.gif" );
		suitImages[3] = new ImageIcon( "hearts.gif" );

		cardImages = new ImageIcon[13];
		cardImages[0] = new ImageIcon( "ace.gif" );
		cardImages[1] = new ImageIcon( "two.gif" );
		cardImages[2] = new ImageIcon( "three.gif" );
		cardImages[3] = new ImageIcon( "four.gif" );
		cardImages[4] = new ImageIcon( "five.gif" );
		cardImages[5] = new ImageIcon( "six.gif" );
		cardImages[6] = new ImageIcon( "seven.gif" );
		cardImages[7] = new ImageIcon( "eight.gif" );
		cardImages[8] = new ImageIcon( "nine.gif" );
		cardImages[9] = new ImageIcon( "ten.gif" );
		cardImages[10] = new ImageIcon( "jack.gif" );
		cardImages[11] = new ImageIcon( "queen.gif" );
		cardImages[12] = new ImageIcon( "king.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 text
		DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
		String	labelText = (String)node.getUserObject();

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

		// Determine the correct icon to display
		if( labelText.equals( "Deck" ) )
			setIcon( deckImage );
		else if( labelText.equals( "Clubs" ) )
			setIcon( suitImages[0] );
		else if( labelText.equals( "Diamonds" ) )
			setIcon( suitImages[1] );
		else if( labelText.equals( "Spades" ) )
			setIcon( suitImages[2] );
		else if( labelText.equals( "Hearts" ) )
			setIcon( suitImages[3] );
		else if( labelText.equals( "Ace" ) )
			setIcon( cardImages[0] );
		else if( labelText.equals( "Two" ) )
			setIcon( cardImages[1] );
		else if( labelText.equals( "Three" ) )
			setIcon( cardImages[2] );
		else if( labelText.equals( "Four" ) )
			setIcon( cardImages[3] );
		else if( labelText.equals( "Five" ) )
			setIcon( cardImages[4] );
		else if( labelText.equals( "Six" ) )
			setIcon( cardImages[5] );
		else if( labelText.equals( "Seven" ) )
			setIcon( cardImages[6] );
		else if( labelText.equals( "Eight" ) )
			setIcon( cardImages[7] );
		else if( labelText.equals( "Nine" ) )
			setIcon( cardImages[8] );
		else if( labelText.equals( "Ten" ) )
			setIcon( cardImages[9] );
		else if( labelText.equals( "Jack" ) )
			setIcon( cardImages[10] );
		else if( labelText.equals( "Queen" ) )
			setIcon( cardImages[11] );
		else if( labelText.equals( "King" ) )
			setIcon( cardImages[12] );

		// Add the text to the cell
		setText( labelText );

		return this;
	}

	// This is a hack to paint the background.  Normally a JLabel can
	// paint its own background, but due to an apparent bug or
	// limitation in the TreeCellRenderer, the paint method is
	// required to handle this.
	public void paint( Graphics g )
	{
		Color		bColor;
		Icon		currentI = getIcon();

		// Set the correct background color
		bColor = bSelected ? SystemColor.textHighlight : Color.white;
		g.setColor( bColor );

		// Draw a rectangle in the background of the cell
		g.fillRect( 0, 0, getWidth() - 1, getHeight() - 1 );

		super.paint( g );
	}

}
```

Chiao
Craven


----------



## Beni (17. Mrz 2004)

Ich mach mal ein Beispiel.

:!: Aber: dieses Beispiel funktioniert nur, wenn die Dateien (die angezeigt werden) tatsächlich existieren.
Darum darf man nicht 
	
	
	
	





```
File file = ...
File[] childs = file.listFiles();
```
 verwenden, sondern muss 
	
	
	
	





```
FileSystemView system = ... // siehe Konstruktor von Renderer
File file = ...
File[] childs = view.getFiles( file, true );
```
benutzen  :!:

Das ist der CellRenderer 
	
	
	
	





```
public class Renderer extends DefaultTreeCellRenderer{
    private FileSystemView system; // die brauchen wir für die Icons

    public Renderer(){
      // Der Konstruktor
      system = FileSystemView.getFileSystemView();
    }

    public Component getTreeCellRendererComponent(JTree tree, Object value,
        boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus){

      super.getTreeCellRendererComponent( tree, "", selected, expanded, leaf, row, hasFocus );

      File file = (File)value

      // Diese beiden Zeilen funktionieren nur, wenn die Datei offiziel existiert. !!!
      setIcon( system.getSystemIcon( file ));
      setText( system.getSystemDisplayName( file ));

      return this;
    }
  }
}
```

[Edit: jetzt war jemand schneller :wink: ]

mfg Beni


----------



## Guest (18. Mrz 2004)

Das bedeutet aber nun das ,man nur icons nutzen kann die man selber auf den rechner als z.B. jpg oder gif datei hat. z.B. folder.gif


----------



## steffan (18. Mrz 2004)

Nein glaub das kann nicht sein. In dem Code werden auch keine gif oder jpg Datei benutzt und trotzdem zeigt er für jede Datei das richtige Icon an.


```
import java.io.*; 

import java.awt.*; 
import javax.swing.*; 
import javax.swing.event.*; 
import javax.swing.filechooser.*; 
import javax.swing.tree.*; 

public class lernen extends JTree{ 
  public static void main( String[] args ){ 
	JFrame frame = new JFrame(); 
	frame.getContentPane().add( new JScrollPane( new lernen() ) ); 
	frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 
	frame.pack(); 
	frame.setLocationRelativeTo( null ); 
	frame.setVisible( true ); 
  } 

  private static FileSystemView SYSTEM = FileSystemView.getFileSystemView(); 

  public lernen(){ 
	setModel( new FileTreeModel() ); 
	setCellRenderer( new FileTreeCellRenderer() ); 
  } 

  private class FileTreeCellRenderer extends DefaultTreeCellRenderer{ 
	public FileTreeCellRenderer(){ 
      
	} 

	public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean exp, boolean leaf, int row, boolean focus ){ 
	  super.getTreeCellRendererComponent( tree, value, sel, exp, leaf, row, focus ); 
          
	  File file = (File)value; 
      
	  setIcon( SYSTEM.getSystemIcon( file ) ); 
	  setText( SYSTEM.getSystemDisplayName( file )); 
      
	  return this; 
	} 
  } 

  private class FileTreeModel implements TreeModel { 
	public FileTreeModel() { 

	} 

	public Object getRoot() { 
	  return SYSTEM.getHomeDirectory();   // <<<<<<<<<<<<<<<<<<<<<<< Der ist wichtig 
	} 

	public int getChildCount(Object parent) { 
	  return SYSTEM.getFiles( (File) parent, true). 
		  length; 
	} 

	public boolean isLeaf(Object node) { 
	  return ( (File) node).isFile(); 
	} 

	public void addTreeModelListener(TreeModelListener l) { 
	} 

	public void removeTreeModelListener(TreeModelListener l) { 
	} 

	public Object getChild(Object parent, int index) { 
	  return FileSystemView.getFileSystemView().getFiles( (File) parent, true)[ 
		  index]; 
	} 

	public int getIndexOfChild(Object parent, Object child) { 
	  File[] files = SYSTEM.getFiles( (File) parent, true); 

	  for (int i = 0; i < files.length; i++) 
		if (files[i] == child) 
		  return i; 

	  return -1; 
	} 

	public void valueForPathChanged(TreePath path, Object newValue) { 
	} 
  } 
}
```


----------



## Beni (18. Mrz 2004)

Anonymous hat gesagt.:
			
		

> Das bedeutet aber nun das ,man nur icons nutzen kann die man selber auf den rechner als z.B. jpg oder gif datei hat. z.B. folder.gif


Irgendwo müssen diese Bilder schon sein ...
... aber Du musst nicht wissen wo.

Die beiden Progis finden die benötigten Bilder, passend zum System (wenn auf deinem PC *.java Dateien mit einem grünen Kreis angezeigt werden, werden auch diese Progis grüne Kreise zeichnen!)


----------



## Guest (18. Mrz 2004)

Ah so ok. Obowhl ich zwar ein etwas anderes TreeModel habe müßte ich doch aber folgendes benutzten können oder?

Die RendererKlasse

```
private class FileTreeCellRenderer extends DefaultTreeCellRenderer{ 
   public FileTreeCellRenderer(){ 
      
   } 

   public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean exp, boolean leaf, int row, boolean focus ){ 
     super.getTreeCellRendererComponent( tree, value, sel, exp, leaf, row, focus ); 
          
     File file = (File)value; 
      
     setIcon( SYSTEM.getSystemIcon( file ) ); 
     setText( SYSTEM.getSystemDisplayName( file )); 
      
     return this; 
   } 
  }
```

dann noch 

```
private static FileSystemView SYSTEM = FileSystemView.getFileSystemView();
```

und an den Tree muss ich noch ranhängen

```
jTree.setCellRenderer( new FileTreeCellRenderer() );
```

und dann müßte es doch eigentlich gehen


----------



## Beni (18. Mrz 2004)

Theoretisch: ja.
Praktisch: Must du als Nodes Instancen von File benutzen (Da sonst _Object value_ kein File ist). Und du musst darauf achten, dass diese Files auch existieren (File.exists() ), weil sonst SYSTEM.getXXX eine Exception wirft.


----------



## Steffan (18. Mrz 2004)

Ja es geht. Gott Dank euch Java Profis


----------



## Craven (18. Mrz 2004)

Problem daran dürfe allerdings sein, daß es nur unter Windows funktioniert!


----------



## Steffan (18. Mrz 2004)

siehste ich wollt nachher mal testen was auf einen Linux rechner passiert. Hmm er erkennt doch dort auch das System. warum sollte es dort nicht auch gehen?


----------



## Beni (18. Mrz 2004)

Craven hat gesagt.:
			
		

> Problem daran dürfe allerdings sein, daß es nur unter Windows funktioniert!


Hallo! Java ist plattform*un*abhaengig   :!: 

Auch wenns bei Linux nicht so schoen aussieht, funktionieren wird es (machen wir eine Wette?)   

mfg Beni


----------



## Craven (18. Mrz 2004)

Beni hat gesagt.:
			
		

> Craven hat gesagt.:
> 
> 
> 
> ...



Schon! Allerdings werden unter Linux wohl die Dateisymbole fehlen!


----------



## Guest (18. Mrz 2004)

hat linux keine eigenen Symbole für verschiedene daten? wenn ja müßten die dann erscheinen.


----------



## Craven (18. Mrz 2004)

Das hast Du jetzt gut erkannt! Das Problem kann man aber umgehen, indem man anstatt Swing, SWT benutzt! Schließlich benutzt SWT das native Toolkit, welches lokal installiert ist! In dem Fall Gnome


----------

