Ola!
Há alguns dias meu amigo k_menna criou esse tópico pois estava com problemas em uma JTree pra seleção de diretórios, desde então fiquei trabalhando num TreeModel que resolvesse o problema. E Hoje estou aqui para disponibilizar a TreeModel que chamei de FileStructureTreeModel (nome dado por k_menna).
Vamos aos Fontes
FileStructureTreeModel (TreeModel)
[code]import javax.swing.event.EventListenerList;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
/**
- TreeModel que mostra a estrutura dos arquivos do Sistema
- @author Victor Duarte da Silva (InSeOfKn)
*/
public class FileStructureTreeModel implements TreeModel {
private NodeFile root;
protected EventListenerList listeners;
/**
*
* @param root
* o NodeFile que representa a raiz do TreeModel
*/
public FileStructureTreeModel(NodeFile root) {
listeners = new EventListenerList();
this.root = root;
}
@Override
public Object getChild(Object parent, int index) {
if (!(parent instanceof NodeFile))
throw new IllegalArgumentException();
try {
if (((NodeFile) parent).getSubFiles() == null)
return -1;
return ((NodeFile) parent).getSubFiles().get(index);
} catch (IndexOutOfBoundsException e) {
return null;
}
}
@Override
public int getChildCount(Object parent) {
if (!(parent instanceof NodeFile))
throw new IllegalArgumentException();
if (isLeaf(parent))
return 0;
return ((NodeFile) parent).getSubFiles().size();
}
@Override
public int getIndexOfChild(Object parent, Object child) {
if (!(parent instanceof NodeFile))
throw new IllegalArgumentException();
return ((NodeFile) parent).getSubFiles().indexOf(child);
}
@Override
public Object getRoot() {
return root;
}
@Override
public boolean isLeaf(Object node) {
if (!(node instanceof NodeFile))
throw new IllegalArgumentException();
if (((NodeFile) node).getSubFiles() == null) {
return true;
}
return false;
}
@Override
public void addTreeModelListener(TreeModelListener l) {
listeners.add(TreeModelListener.class, l);
}
@Override
public void removeTreeModelListener(TreeModelListener l) {
listeners.remove(TreeModelListener.class, l);
}
@Override
public void valueForPathChanged(TreePath path, Object newValue) {
}
}
[/code]
NodeFile
[code]import java.io.File;
import java.util.List;
/**
- Interface a ser implementada para o FileStructureTreeMode trabalhar com seu
- “Filtro”
- @author Victor Duarte da Silva(InSeOfKn)
/
public interface NodeFile {
/*
* obtem o arquivo que o nó representa
*
* @return o arquivo que o nó representa
*/
public File getFile();
/**
* Obtem os filhos (somente o os que se deseja exibir). Folhas devem
* retornar null e nós vazios um List vazio. <br>
* Gere a lista dentro desse metodo apenas uma vez,
*
* @return os filhos desse nó
*/
public List<NodeFile> getSubFiles();
}
[/code]
Com isso já é possível utilizar o TreeModel, mas para facilitar a vida de vocês já implementei 2 NodeFile para ser usado com o FileStructureTreeModel.
NodeArchive - Estrutura completa.
[code]import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
- Implementação de NodeFile que exibe toda a estrutura
- @author Victor Duarte da Silva (InSeOfKn)
*/
public class NodeArchive implements NodeFile {
private File file;
private List<NodeFile> list;
private boolean generate = false;
public NodeArchive(File file) {
this.file = file;
}
public NodeArchive() {
this.file = null;
}
public File getFile() {
return file;
}
public strictfp List<NodeFile> getSubFiles() {
if (generate)
return list;
generate = true;
if (getFile() == null) { // faz com que se o nó não tenha arquivo que o
// represente liste os dispositivos de
// armazenamento
list = new ArrayList<NodeFile>();
for (File f : File.listRoots()) {
list.add(new NodeArchive(f));
}
return list;
}
if (getFile().listFiles() == null) {
if (!getFile().isFile()) // não usei isDirectory() pois se for vazio
// ele não considera diretorio
return list = new ArrayList<NodeFile>();
return null;
}
list = new ArrayList<NodeFile>();
for (File f : getFile().listFiles()) {
list.add(new NodeArchive(f));
}
return list;
}
@Override
public String toString() {
if (getFile() != null) {
if (getFile().getName().isEmpty())
return getFile().getPath();
return getFile().getName();
}
return "Computador";
}
}
[/code]
NodeDirectory - Somente Pastas
[code]import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
- Implememtação de NodeFile que só exibe Pastas.
- @author Victor Duarte da Silva
*/
public class NodeDirectory implements NodeFile {
private File file;
private List<NodeFile> list;
private boolean generate = false;
public NodeDirectory(File file) {
this.file = file;
}
/**
* Construtor que cria o Computado como root (guarda a lista de Dispositivos
* de Armazenamento)
*/
public NodeDirectory() {
this.file = null;
}
public File getFile() {
return file;
}
public strictfp List<NodeFile> getSubFiles() {
if (generate)
return list;
generate = true;
if (getFile() == null) { // faz com que se o nó não tenha arquivo que o
// represente liste os dispositivos de
// armazenamento
list = new ArrayList<NodeFile>();
for (File f : File.listRoots()) {
list.add(new NodeDirectory(f));
}
return list;
}
if (getFile().listFiles() == null) {
return null;
}
list = new ArrayList<NodeFile>();
for (File f : getFile().listFiles()) {
if (f.isDirectory()) {
list.add(new NodeDirectory(f));
}
}
if (list.isEmpty())
return list = null; // faz com que diretorios sem sub diretorios
// virem folhas.
return list;
}
@Override
public String toString() {
if (getFile() != null) {
if (getFile().getName().isEmpty())
return getFile().getPath();
return getFile().getName();
}
return "Computador";
}
}
[/code]
Testem! Usem! e relatem qualquer bug!
Em anexo vai um jar para ser colocado no ClassPath.
Obs: não notem o péssimo inglês e o péssimo português (eclipse não tem corretor ortografico :lol: )
Até! não deixem de comentar!