/* * This file is part of muCommander, http://www.mucommander.com * Copyright (C) 2002-2016 Maxence Bernard * * muCommander is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * muCommander is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.mucommander.ui.list; import com.mucommander.commons.file.AbstractFile; import com.mucommander.commons.file.util.FileSet; import javax.swing.*; import java.awt.*; /** * FileList is a <code>JList</code> that displays information about a list of files: each row displays a file's name * and icon. * * <p>Since all <code>AbstractFile</code> methods are I/O bound and potentially lock-prone, it is not a good idea to * call them on request from the main event thread. To work around this, the constructor can preload all the information * subsequently needed by this list. This has a cost since all files will have to queried at init time, even if some * are not used (displayed) afterwards. On the other hand, navigation throughout the list will be faster. * Preloading can be enabled or disabled in the constructor but it should always enabled unless it is * known for certain that the underlying files are not I/O bound and cannot lock.</p> * * @author Maxence Bernard */ public class FileList extends JList { /** Files to display */ protected FileSet files; /** True if file attribute preloading has been enabled */ protected boolean fileAttributesPreloaded; /** Preloaded filenames, null if preloading is not enabled */ protected String[] filenames; /** Preloaded file icons, null if preloading is not enabled */ protected Icon[] icons; /** Custom font by the JLabel */ protected Font customFont; /** * Creates a new FileList where each file in the given {@link FileSet} is displayed on a separate row. * * @param files the set of files to display * @param preloadFileAttributes enables/disables file attribute preloading. It should always enabled unless it is known * for certain that the underlying files are not I/O bound and cannot lock. */ public FileList(final FileSet files, boolean preloadFileAttributes) { this.files = files; int nbFiles = files.size(); // Very important: allows the JList to operate in fixed cell height mode, which makes it substantially faster // to initialize when there is a large number of rows. if(nbFiles>0) setPrototypeCellValue(files.elementAt(0)); if(preloadFileAttributes) { filenames = new String[nbFiles]; icons = new Icon[nbFiles]; AbstractFile file; for(int i=0; i<nbFiles; i++) { file = files.elementAt(i); filenames[i] = file.getName(); icons[i] = file.getIcon(); } this.fileAttributesPreloaded = true; } // Use a custom ListModel setModel(new AbstractListModel() { public int getSize() { return files.size(); } public Object getElementAt(int index) { return files.elementAt(index); } }); customFont = new JLabel().getFont(); customFont = customFont.deriveFont(customFont.getStyle(), customFont.getSize()-2); // Use a custom ListCellRenderer setCellRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); label.setFont(customFont); if(FileList.this.fileAttributesPreloaded) { label.setText(filenames[index]); label.setIcon(icons[index]); } else { AbstractFile file = (AbstractFile)value; label.setText(file.getName()); label.setIcon(file.getIcon()); } return label; } }); } }