001 /* 002 * $Id: SimpleFileSystemModel.java 2303 2007-09-14 12:18:16Z kschaefe $ 003 * 004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021 022 package org.jdesktop.swingx.treetable; 023 024 import java.io.File; 025 import java.util.Date; 026 027 import javax.swing.event.EventListenerList; 028 import javax.swing.event.TreeModelListener; 029 import javax.swing.tree.TreePath; 030 031 /** 032 * A tree table model to simulate a file system. 033 * <p> 034 * This tree table model implementation does not extends 035 * {@code AbstractTreeTableModel}. The file system metaphor demonstrates that 036 * it is often easier to directly implement tree structures directly instead of 037 * using intermediaries, such as {@code TreeNode}. 038 * <p> 039 * It would be possible to create this same class by extending 040 * {@code AbstractTreeTableModel}, however the number of methods that you would 041 * need to override almost precludes that means of implementation. 042 * <p> 043 * A "full" version of this model might allow editing of file names, the 044 * deletion of files, and the movement of files. This simple implementation does 045 * not intend to tackle such problems, but this implementation may be extended 046 * to handle such details. 047 * 048 * @author Ramesh Gupta 049 * @author Karl Schaefer 050 */ 051 public class SimpleFileSystemModel implements TreeTableModel { 052 protected EventListenerList listenerList; 053 054 // the returned file length for directories 055 private static final Long ZERO = Long.valueOf(0); 056 057 private File root; 058 059 /** 060 * Creates a file system model, using the root directory as the model root. 061 */ 062 public SimpleFileSystemModel() { 063 this(new File(File.separator)); 064 } 065 066 /** 067 * Creates a file system model, using the specified {@code root} as the 068 * model root. 069 */ 070 public SimpleFileSystemModel(File root) { 071 this.root = root; 072 this.listenerList = new EventListenerList(); 073 } 074 075 /** 076 * {@inheritDoc} 077 */ 078 public File getChild(Object parent, int index) { 079 if (parent instanceof File) { 080 File parentFile = (File) parent; 081 File[] files = parentFile.listFiles(); 082 083 if (files != null) { 084 return files[index]; 085 } 086 } 087 088 return null; 089 } 090 091 /** 092 * {@inheritDoc} 093 */ 094 public int getChildCount(Object parent) { 095 if (parent instanceof File) { 096 String[] children = ((File) parent).list(); 097 098 if (children != null) { 099 return children.length; 100 } 101 } 102 103 return 0; 104 } 105 106 /** 107 * {@inheritDoc} 108 */ 109 public Class<?> getColumnClass(int column) { 110 switch(column) { 111 case 0: 112 return String.class; 113 case 1: 114 return Long.class; 115 case 2: 116 return Boolean.class; 117 case 3: 118 return Date.class; 119 default: 120 return Object.class; 121 } 122 } 123 124 /** 125 * {@inheritDoc} 126 */ 127 public int getColumnCount() { 128 return 4; 129 } 130 131 /** 132 * {@inheritDoc} 133 */ 134 public String getColumnName(int column) { 135 switch (column) { 136 case 0: 137 return "Name"; 138 case 1: 139 return "Size"; 140 case 2: 141 return "Directory"; 142 case 3: 143 return "Modification Date"; 144 default: 145 return "Column " + column; 146 } 147 } 148 149 /** 150 * {@inheritDoc} 151 */ 152 public Object getValueAt(Object node, int column) { 153 if (node instanceof File) { 154 File file = (File) node; 155 switch (column) { 156 case 0: 157 return file.getName(); 158 case 1: 159 return file.isFile() ? file.length() : ZERO; 160 case 2: 161 return file.isDirectory(); 162 case 3: 163 return new Date(file.lastModified()); 164 } 165 } 166 167 return null; 168 } 169 170 /** 171 * {@inheritDoc} 172 */ 173 public int getHierarchicalColumn() { 174 return 0; 175 } 176 177 /** 178 * {@inheritDoc} 179 */ 180 public boolean isCellEditable(Object node, int column) { 181 return false; 182 } 183 184 /** 185 * {@inheritDoc} 186 */ 187 public void setValueAt(Object value, Object node, int column) { 188 //does nothing 189 } 190 191 /** 192 * {@inheritDoc} 193 */ 194 public void addTreeModelListener(TreeModelListener l) { 195 listenerList.add(TreeModelListener.class, l); 196 } 197 198 /** 199 * {@inheritDoc} 200 */ 201 public int getIndexOfChild(Object parent, Object child) { 202 if (parent instanceof File && child instanceof File) { 203 File parentFile = (File) parent; 204 File[] files = parentFile.listFiles(); 205 206 for (int i = 0, len = files.length; i < len; i++) { 207 if (files[i].equals(child)) { 208 return i; 209 } 210 } 211 } 212 213 return -1; 214 } 215 216 /** 217 * {@inheritDoc} 218 */ 219 public File getRoot() { 220 return root; 221 } 222 223 /** 224 * {@inheritDoc} 225 */ 226 public boolean isLeaf(Object node) { 227 if (node instanceof File) { 228 //do not use isFile(); some system files return false 229 return ((File) node).list() == null; 230 } 231 232 return true; 233 } 234 235 /** 236 * {@inheritDoc} 237 */ 238 public void removeTreeModelListener(TreeModelListener l) { 239 listenerList.remove(TreeModelListener.class, l); 240 } 241 242 /** 243 * {@inheritDoc} 244 */ 245 public void valueForPathChanged(TreePath path, Object newValue) { 246 //does nothing 247 } 248 249 /** 250 * Gets a an array of all the listeners attached to this model. 251 * 252 * @return an array of listeners; this array is guaranteed to be 253 * non-{@code null} 254 */ 255 public TreeModelListener[] getTreeModelListeners() { 256 return listenerList.getListeners(TreeModelListener.class); 257 } 258 }