# Swing Element für Explorer-Fenster darstellung



## SBS (17. Sep 2006)

Hallo,

es ist schwer nach etwas zu suchen, wenn man nicht weißt wie es heißt  :shock: 

Ich möchte eine Art Explorer Fenster in meiner Gui (mit Swing) darstellen, ein Fenster links, ein Fenster rechts.
Ähnlich einer "Norton Commander" Optik - falls das noch jemandem was sagt.

Dafür gibt es doch sicher ein ...JExplorerWindow irgendwas Element, oder sowas, was dies darstellen kann, oder nicht?

Kann mir bitte kurz jemand sagen was sich eignet?
Es sollte eine ähnliche Sicht wie im Windows Explorer sein, Verzeichnisse, Dateigröße sowie Datum sind ausreichend.

Besten Dank


----------



## Illuvatar (17. Sep 2006)

Ich verstehe gerade nicht ganz, was du jetzt suchst. Ein Fenster wie im Windows-Explorer kann man sich jedenfalls z.B. aus JSplitPane, JTree und JTable zusammenbauen.


----------



## SBS (17. Sep 2006)

Hm nunja ich möchte ein kleines Explorer Fenster in meinen JFrame haben, wo ich drin rumklicken kann und die Verzeichnisse und Dateien sehe, gibt es sowas nicht bererits fertig?

//EDIT: danke vorerst, JTree scheint das zu sein, was ich gesucht habe  Dort kann ich nun weiter sehen..


----------



## Illuvatar (17. Sep 2006)

Nein, gibt es nicht. Du könntest höchstens einen JFileChooser verwenden, aber das ist nicht ganz das, was du willst.

Wenn du das selbst bauen willst: Ich könnte dir mal meinen JDirectoryChooser posten, da könntest du vielleicht bisschen was abschauen.
Edit: Auch gut


----------



## SBS (17. Sep 2006)

Gut ich versuch damit mal zurecht zu kommen, mal sehn was sich basteln lässt 

PS: FAlls es mir nicht so gelingt, dann darf ich mich sicher nochmal melden (wegen deiner JDirectoryChooser Class), in Ordnung?


----------



## Illuvatar (17. Sep 2006)

Klar, schreib dann einfach.


----------



## foobar (17. Sep 2006)

Guck dir mal den JTreeTable von SwingX an, der ist schon ziemlich nah an dem dran was du du suchst.
http://swinglabs.org/screenshots/JXTableJXTreeTable.png


----------



## SBS (17. Sep 2006)

Hm SwingX sagt mir nun grad mal nichts, und ich bin im Moment ein wenig in Zeitnöten, daher kann ich mich damit nicht befassen jetzt.

Illuvatar, könntest du bitte deinen DirectoryChooser hier präsentieren, und vielleicht ganz bündig erläutern? Wäre echt super.

Ich habe zwar einen JTree im meiner gui, allerdings möchte ich dort Zugriff auf meine Laufwerke habe, aber irgendwie sehe ich da nur einen JTree Ordner mit einigen Unterverzeichnissen.

Aber vielleicht kann man das ja auch recht einfach gestalten ohne eine komplette Klasse zu integrieren? 

Ich müsste eigentlich nur die ORdner aus meinem System auswählen können und mir die aktuelle Auswahl zurückliefern lassen können, das müsste doch recht einfach möglich sein?
Dass jemand das Verzeichnis in ein JTextField eintippt und ich es mir hole wäre ein bisschen unpraktisch denke ich :/

Meine kleine Gui in der Entwicklugnsphase 


```
package synchronize;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.tree.TreePath;

import org.apache.tools.ant.types.Path;

public class Gui extends JFrame implements AdjustmentListener
{

	/**
	 * 
	 */
	private static final long serialVersionUID = -4290702090831530326L;

	public void adjustmentValueChanged(AdjustmentEvent e) {
		// TODO Auto-generated method stub
		
	}
	
	
    
    private final String HTMLBUTTONS = "<html><font size=\"3\">";
    private final String VERSION = "alpha 0.1";
    
    private String labels[] = {HTMLBUTTONS+"Verzeichnisse Synchronisieren", HTMLBUTTONS+"Verzeichnis Archivieren", HTMLBUTTONS+"Verzeichnisse Vergleichen"};     
    private String acs[] = {"sync", "zip", "compare"};
    
    private JPanel centerPnl, eastPnl, westPnl, southPnl, eastrow, westrow, northPnl;
    
    private JLabel quelle, ziel;
    
    private JButton buttons[] = new JButton[labels.length];
    
    private JMenuBar menu;
    
    private JTree src_tree, dst_tree;
    
    private ActionListener al;
    private WindowListener wl;
    private MouseListener ml;
    private KeyListener kl;
    
    
    
    
    /*--------------------------------------------------------------------------------------------------------
    inner (sub)class of WindowAdapter, not all abstract methods of windowlistener need to be overwritten
    inner class knows all methods and attributes of its external class
   ---------------------------------------------------------------------------------------------------------*/	  
class InWindowListener extends WindowAdapter 
{                                           
	public void windowClosing(WindowEvent we)  //overwriting abstract method windowClosing
	{
			shutdown(); //calling method
	}
};
 

/*--------------------------------------------------------------------------------------------------------
    inner class implements Interface ActionListener, actionPerformed need to be overwritten
    inner class knows all methods and attributes of its external class
   ---------------------------------------------------------------------------------------------------------*/
 class InActionListener implements ActionListener
 {
         public void actionPerformed(ActionEvent ae)  //method actionPerformed gets an actionevent delivered
         { 
                 
                 if(ae.getActionCommand().equals("load2") || ae.getActionCommand().equals("filmlist"))
                 {
                        // loading("menu");
                 }
                
         }
 };
 
 
 
 
 /*--------------------------------------------------------------------------------------------------------
    inner (sub)class of MouseAdapter, not all abstract methods of mouselistener need to be overwritten
    inner class knows all methods and attributes of its external class
   ---------------------------------------------------------------------------------------------------------*/
 class InMouseListener extends MouseAdapter
 {
         public void mouseClicked(MouseEvent me) //method mouseclicked gets an mouseevent delivered
         {
                 if (me.getClickCount() == 2)  //if mousebutton is clicked twice...
                 {
                         //edit();
                 }                                      
         }
 };
 
 
 
 
 
 /*--------------------------------------------------------------------------------------------------------
    inner (sub)class of KeyAdapter, not all abstract methods of keylistener need to be overwritten
    inner class knows all methods and attributes of its external class
   ---------------------------------------------------------------------------------------------------------*/
 class InKeyListener extends KeyAdapter
 {
         public void keyPressed(KeyEvent ke)  //overwriting keyPressed method, delivereing a key event
         {
                 if(ke.getKeyCode()==KeyEvent.VK_ESCAPE) //if the specific code of a (pressed)key matches to VS_ESCAPEs, do...
                 {
                         dispose();
                 }
                 
         }
 };

 
 public Gui(String title)
 {
         super(title); //calling constructor of superiorclass...cause frame elements are needed

         initLayout(); //calling methods
 }

 
 protected void createButtons()
 {
         for (int i=0 ; i < labels.length; i++)
         {
                 buttons[i] = new JButton(labels[i]); 
                 buttons[i].setFont(new Font("Courier New", Font.BOLD, 12));
                 buttons[i].addKeyListener(kl);
                 buttons[i].addActionListener(al); 
                 buttons[i].setActionCommand(acs[i]);
                 centerPnl.add(buttons[i]); 
         }
 }
 
 
 protected int confirming(String message, String title)
 {
         int option = JOptionPane.showConfirmDialog(null,"<html><center>[b]"+message+"<center></html>",title,JOptionPane.YES_NO_OPTION);
         return option; //returning int value
 }
 
 
 protected void setStatus(String message, String title, String type)
 {
         if (type.equalsIgnoreCase("error"))
         {
                 JOptionPane.showMessageDialog(null,"<html><center>[b]"+message+"<center></html>",title,JOptionPane.ERROR_MESSAGE);
         }
         else if (type.equalsIgnoreCase("info"))
         {
                 JOptionPane.showMessageDialog(null,"<html><center>[b]"+message+"<center></html>",title,JOptionPane.INFORMATION_MESSAGE);
         }
         else if (type.equalsIgnoreCase("ask"))
         {
                 JOptionPane.showMessageDialog(null,"<html><center>[b]"+message+"<center></html>",title,JOptionPane.QUESTION_MESSAGE);
         }
 }  
 
 
 protected JFrame getJFrame()
 {
         return this;
 }
 
 
 protected void positioning()
 {
         Dimension dims = Toolkit.getDefaultToolkit().getScreenSize(); //save systems screensize to Dimension-toolkit object
         setSize((dims.width*10/13),(dims.height*10/15)); //set size of frame by using dims value
         setLocation((dims.width/9),(dims.height/9)); //set location where frame will be opened using dims value
 }
 
 protected void shutdown()
 {                
         int chose = confirming("Programm wirklich beenden?","Ende"); //chose gets int value of JOptionpane dialog

         if(chose==1) 
         {
                 getJFrame().setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); //window shut not be closed, continue running program
         }
         else
         {                
                 dispose(); //vanishing frame
                 System.exit(0); //exiting programm
         }
 }
 
 
 protected void initLayout()
 {                
    Container environment = getContentPane();  //getting contentPane into 'environment' of type container
	environment.setLayout(new BorderLayout());  //setting up layout, here borderlayout
         
    setTitle("SyncTool "+VERSION); //setting title and version
	positioning(); //calling method for positioning frame
	
	setResizable(false);  //user should not be able to change dialogs size
	//setForeground(Color.black);   //setting Foreground
	//setBackground(Color.lightGray); //setting background
         

         //creating some Listeners objects of our inner class
         ml = new InMouseListener();
         al = new InActionListener();
         wl = new InWindowListener();
         kl = new InKeyListener();
         
         addWindowListener(wl);

     
       //  menu = new HiltownMenu(al); //new menubar for contextmenu is needed
	   //setJMenuBar(menu);
         
         
         westPnl = new JPanel();
         eastPnl = new JPanel();
         eastrow = new JPanel();
         westrow = new JPanel();
         southPnl = new JPanel();
         centerPnl = new JPanel();
         northPnl = new JPanel();
     

         centerPnl.setLayout(new BorderLayout());
         westPnl.setLayout(new BorderLayout());
         eastPnl.setLayout(new BorderLayout());
         northPnl.setLayout(new BorderLayout());
         
      
	     quelle = new JLabel("<html>&nbsp[b]<font size=\"3\"<u> Quellverzeichnis auswählen</u>[/b]&nbsp"); 
         ziel = new JLabel("<html>&nbsp[b]<font size=\"3\"<u> Zielverzeichnis auswählen</u>[/b]&nbsp");
         
         src_tree = new JTree();
         dst_tree = new JTree();
         
         

         createButtons();	//now create buttons 

         eastrow.add(quelle);
         westrow.add(ziel);

         eastPnl.add("North", eastrow);
         eastPnl.add("Center", src_tree);
         
         northPnl.add("West", buttons[0]);
         northPnl.add("Center", buttons[1]);
         northPnl.add("East", buttons[2]);
         
         westPnl.add("North", westrow);
         westPnl.add("Center", dst_tree);

         
         //adding panel into Container						
         environment.add("West", westPnl);				
         environment.add("East", eastPnl);
         environment.add("North", northPnl);
         environment.add("Center", centerPnl);
         environment.add("South", southPnl);
						                
	setVisible(true);      //of course the window should be visible       
 }
 
 
 
}
```

Da möchte ich jetzt lediglich dass in dem JTree links sowie rechts, jemand Verzeichnisse aus meinem System wählen kann (wie man das im linken Fenster des Windowsexplorers machen kann) es geht lediglich um die Auswahl sowie darum dass ich mir diese dann auch irgendwie holen kann - sämtliche anderen Funktionen brauche ich eigentlich nicht.


----------



## André Uhres (17. Sep 2006)

Vielleicht kannst du hiermit was anfangen:
http://www.java-forum.org/de/viewtopic.php?p=150563


----------



## SBS (17. Sep 2006)

Hi, danke, hatte ich bereits angesehen, auch das Tutorial an sich.

Stellt sich mir die Frage, brauche ich die 3 Klassen, die dort aufgelistet sind? Brauche ich nur eine? Verstehe zwar den Code, jedoch die gesamte Struktur nicht so richtig, es kam mir ein wenig aufwendig vor, daher fragte ich mich, ob ich dies denn alles benötige  *hmpf*


----------



## André Uhres (17. Sep 2006)

Naja der renderer ist schon nicht schlecht wegen der Icons. Eine main Klasse brauchst du eh.
Bleibt nur noch der FileTree. Dort kannst du eventuell die Filter rausnehmen und den sort samt Comparator.


----------



## André Uhres (17. Sep 2006)

Hier ist ein ganz simples Beispiel, aber wenig performant.
Könnte aber unter Umständen genügen:

```
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import java.io.*;

public class SimpleTree extends JPanel {
  JTree tree;
  DefaultMutableTreeNode root;
  public SimpleTree() {
    root = new DefaultMutableTreeNode("root", true);
    getList(root, new File("c:/temp"));
    setLayout(new BorderLayout());
    tree = new JTree(root);
    tree.setRootVisible(false);
    add(new JScrollPane((JTree)tree),"Center");
    }

  public Dimension getPreferredSize(){
    return new Dimension(200, 120);
    }

  public void getList(DefaultMutableTreeNode node, File f) {
     if(!f.isDirectory()) {
         // We keep only JAVA source file for display in this HowTo
         if (f.getName().endsWith("java")) {
            System.out.println("FILE  -  " + f.getName());
            DefaultMutableTreeNode child = new DefaultMutableTreeNode(f);
            node.add(child);
            }
         }
     else {
         System.out.println("DIRECTORY  -  " + f.getName());
         DefaultMutableTreeNode child = new DefaultMutableTreeNode(f);
         node.add(child);
         File fList[] = f.listFiles();
         for(int i = 0; i  < fList.length; i++)
             getList(child, fList[i]);
         }
    }
  
  public static void main(String s[]){
    MyJFrame frame = new MyJFrame("Directory explorer");
    }
  }

class WindowCloser extends WindowAdapter {
  public void windowClosing(WindowEvent e) {
    Window win = e.getWindow();
    win.setVisible(false);
    System.exit(0);
    }
  }

class MyJFrame extends JFrame {
  JButton b1, b2, b3;
  SimpleTree panel;
  MyJFrame(String s) {
    super(s);
    panel = new SimpleTree();
    getContentPane().add(panel,"Center");
    setSize(300,300);
    setVisible(true);
    setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    addWindowListener(new WindowCloser());
    }

 }
```

Quelle: http://www.rgagnon.com


----------



## Illuvatar (17. Sep 2006)

Naja, hier mein JDirectoryChooser, ein etwas größeres Beispiel. Stellenweise ist er noch nicht ganz fertig (erkennbar an den TODO-Kommentaren)

JDirectoryChooser.java

```
package de.illu.swing;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

@SuppressWarnings("serial")
public class JDirectoryChooser extends JComponent implements ActionListener
{
    public JDirectoryChooser()
    {
        // One File Root => take that
        // More than that => take FileSystemView's root
        this(File.listRoots().length == 1 ? File.listRoots()[0]
                : FileSystemView.getFileSystemView().getHomeDirectory());
    }

    //TODO: Constructor with selected directory 
    
    protected JDirectoryChooser(File root)
    {
        if (!root.isDirectory()) {
            root = root.getParentFile();
        }
        setLayout(new BorderLayout());
        JPanel butPan = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        newFileBut = new JButton("Neues Verzeichnis");
        newFileBut.addActionListener(this);
        butPan.add(newFileBut);
        add(BorderLayout.SOUTH, butPan);

        FileSystemView fileSystemView = FileSystemView.getFileSystemView();
        tree = new JTree(new DefaultTreeModel(new FileTreeNode(
                root, fileSystemView)));
        tree.setCellRenderer(new FileTreeCellRenderer(fileSystemView));
        add(BorderLayout.CENTER, new JScrollPane(tree));
    }

    JButton newFileBut;
    private JTree tree;

    /*
     * JButton abortBut; JButton okBut;
     */

    public void setNewDirButString(String s)
    {
        newFileBut.setText(s);
    }

    public String getNewDirButString()
    {
        return newFileBut.getText();
    }

    public void actionPerformed(ActionEvent e)
    {
        if (tree.getSelectionPath() == null) return;
        FileTreeNode parentNode = (FileTreeNode) tree.getSelectionPath()
                .getLastPathComponent();
        File parent = ((FileTreeNode) parentNode).getFile();
        String str = JOptionPane.showInputDialog(this,
                "Enter the new folder name");
        if (str != null) {
            File child = new File(parent, str);
            child.mkdir();
            parentNode.reload();
            TreePath oldPath = tree.getSelectionPath();
            ((DefaultTreeModel) tree.getModel()).reload();
            tree.expandPath(oldPath);
        }
    }

    //TODO: setter
    public File getSelectedDirectory()
    {
        if (tree.getSelectionPath() == null) return null;
        return ((FileTreeNode) tree.getSelectionPath().getLastPathComponent())
                .getFile();
    }

    public JDialog getDialog(Component parent, String title)
    {
        //TODO: add ok/abort buttons
        JDialog dia;
        if (parent instanceof Frame) {
            dia = new JDialog((Frame) parent, title, true);
        } else if (parent instanceof Dialog) {
            dia = new JDialog((Dialog) parent, title, true);
        } else {
            dia = new JDialog((Frame) null, title, true);
        }
        dia.setLayout(new BorderLayout());
        dia.add(this);
        dia.pack();
        dia.setLocationRelativeTo(parent);
        return dia;
    }
}
```

FileTreeNode.java

```
package de.illu.swing;

import java.io.File;
import java.io.FileFilter;
import java.util.*;

import javax.swing.filechooser.FileSystemView;
import javax.swing.tree.TreeNode;

class FileTreeNode implements TreeNode
{
    private File myFil;
    private File[] sub;
    private FileSystemView fsv;

    public FileTreeNode(File f, FileSystemView fsv)
    {
        myFil = f;
        this.fsv = fsv;
        reload();
    }

    public void reload()
    {
        if (myFil.isDirectory()) {
            sub = myFil.listFiles();
            if (sub == null) {
                sub = new File[0];
                return;
            }
            FileFilter ff = new FileFilter() {
                public boolean accept(File pathname)
                {
                    return pathname.isDirectory();
                }
            };
            File[] newSub = new File[sub.length];
            int cnt = 0;
            for (int i = 0; i < sub.length; i++) {
                if (ff.accept(sub[i])) {
                    newSub[cnt++] = sub[i];
                }
            }
            sub = new File[cnt];
            System.arraycopy(newSub, 0, sub, 0, cnt);
            Arrays.sort(sub, new FileComparator());
        }
    }

    public TreeNode getChildAt(int childIndex)
    {
        if (myFil.isDirectory() && childIndex < getChildCount()) {
            return new FileTreeNode(sub[childIndex], fsv);
        } else {
            return null;
        }
    }

    public int getChildCount()
    {
        return myFil.isDirectory() ? sub.length : 0;
    }

    public TreeNode getParent()
    {
        return fsv.isRoot(myFil) ? null : new FileTreeNode(new File(myFil
                .getParent()), fsv);
    }

    public int getIndex(TreeNode node)
    {
        File f = ((FileTreeNode) node).myFil;
        for (int i = 0; i < getChildCount(); ++i) {
            if (sub[i].equals(f)) {
                return i;
            }
        }
        return -1;
    }

    public boolean getAllowsChildren()
    {
        return myFil.isDirectory();
    }

    public boolean isLeaf()
    {
        return !myFil.isDirectory();
    }

    public Enumeration children()
    {
        java.util.Vector<TreeNode> v = new java.util.Vector<TreeNode>();
        for (int i = 0; i < getChildCount(); ++i) {
            v.add(getChildAt(i));
        }
        return v.elements();
    }

    public File getFile()
    {
        return myFil;
    }

    private class FileComparator implements Comparator<File>
    {
        public int compare(File f1, File f2)
        {
            if (f1.isDirectory() && !f2.isDirectory()) {
                return -1;
            } else if (f2.isDirectory() && !f1.isDirectory()) {
                return 1;
            } else {
                return f1.getName().compareTo(f2.getName());
            }
        }

        public boolean equals(Object o)
        {
            return o instanceof FileComparator;
        }
    }
}
```

FileTreeCellRenderer.java

```
package de.illu.swing;

import java.awt.Component;

import javax.swing.JTree;
import javax.swing.filechooser.FileSystemView;
import javax.swing.tree.DefaultTreeCellRenderer;

@SuppressWarnings("serial")
class FileTreeCellRenderer extends DefaultTreeCellRenderer
{
    private FileSystemView fsv;

    public FileTreeCellRenderer(FileSystemView fsv)
    {
        this.fsv = fsv;
    }

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean sel, boolean expanded, boolean leaf, int row,
            boolean hasFocus)
    {
        super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
                row, hasFocus);
        FileTreeNode ftn = (FileTreeNode) value;
        setText(fsv.getSystemDisplayName(ftn.getFile()));
        setIcon(fsv.getSystemIcon(ftn.getFile()));
        return this;
    }
}
```

Erläutern: Nun ja, es wird eben ein Tree erstellt, dazu wird ein DefaultTreeModel verwendet. Dieses baut den JTree mit TreeNodes auf, hier wird die zweite Klasse verwendet, die TreeModel implementiert. Ein FileTreeNode entspricht eben immer einem bestimmten Verzeichnis (Wenn man den FileFilter ff in der reload() MEthode ändern würde, einer beliebigen Datei). Ein einzelner Ordner wird in der Renderer-Klasse angezeigt, dazu lasse ich mir das Ordner-Icon vom Betriebssystem geben.
Anschauen kannst du dir das ganze z.B. mit

```
new JDirectoryChooser().getDialog(null, "Test").setVisible (true);
```
 (der Dialog ist eben noch nicht fertig...)

Ach ja ich merke gerade: Was ich in Zeilen 37-46 von FileTreeNode mache ist Schwachfug. Aber es funktioniert


----------



## SBS (18. Sep 2006)

Hallo, vielen Dank schonmal für die Hilfe, ich sitze weiterhin dran


----------

