Java tutorial
/* * AndFHEM - Open Source Android application to control a FHEM home automation * server. * * Copyright (c) 2011, Matthias Klass or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU GENERAL PUBLIC LICENSE, as published by the Free Software Foundation. * * This program 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 distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package li.klass.fhem.ui; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.os.Environment; import android.util.Log; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import java.io.File; import java.io.FilenameFilter; import java.util.Collections; import java.util.List; import java.util.Locale; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Lists.newArrayList; public class FileDialog { private static final String PARENT_DIR = ".."; private final String TAG = getClass().getName(); private final Context context; private String[] fileList; private File currentPath; private ListenerList<FileSelectedListener> fileListenerList = new ListenerList<>(); private ListenerList<DirectorySelectedListener> dirListenerList = new ListenerList<>(); private boolean selectDirectoryOption; private String fileEndsWith; private Optional<Predicate<File>> fileFilter = Optional.absent(); public FileDialog(Context context, File initialPath) { this.context = context; checkNotNull(initialPath); if (!initialPath.exists() || !initialPath.canRead()) { initialPath = Environment.getExternalStorageDirectory(); } loadFileList(initialPath); } private void loadFileList(File path) { this.currentPath = path; Predicate<File> predicate = new Predicate<File>() { @Override public boolean apply(File sel) { if (!sel.canRead()) { return false; } else if (selectDirectoryOption) { return sel.isDirectory(); } else { boolean endsWith = fileEndsWith == null || sel.getName().toLowerCase(Locale.getDefault()).endsWith(fileEndsWith); return endsWith || sel.isDirectory(); } } }; if (fileFilter.isPresent()) { predicate = Predicates.and(predicate, fileFilter.get()); } List<String> result = newArrayList(); if (path.exists()) { if (path.getParentFile() != null) result.add(PARENT_DIR); final Predicate<File> finalPredicate = predicate; FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir, String filename) { return finalPredicate.apply(new File(dir, filename)); } }; String[] files = path.list(filter); if (files != null) { Collections.addAll(result, files); } Collections.sort(result); } fileList = result.toArray(new String[result.size()]); } public Dialog createFileDialog() { Dialog dialog; AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(currentPath.getAbsolutePath()); if (selectDirectoryOption) { builder.setPositiveButton("Select directory", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Log.d(TAG, currentPath.getPath()); fireDirectorySelectedEvent(currentPath); } }); } builder.setItems(fileList, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { String fileChosen = fileList[which]; File chosenFile = getChosenFile(fileChosen); if (chosenFile.isDirectory()) { loadFileList(chosenFile); dialog.cancel(); dialog.dismiss(); showDialog(); } else { fireFileSelectedEvent(chosenFile); } } }); dialog = builder.show(); return dialog; } public FileDialog setFileFilter(Predicate<File> fileFilter) { this.fileFilter = Optional.fromNullable(fileFilter); return this; } public FileDialog addFileListener(FileSelectedListener listener) { fileListenerList.add(listener); return this; } @SuppressWarnings("unused") public void removeFileListener(FileSelectedListener listener) { fileListenerList.remove(listener); } @SuppressWarnings("unused") public void setSelectDirectoryOption(boolean selectDirectoryOption) { this.selectDirectoryOption = selectDirectoryOption; } @SuppressWarnings("unused") public void addDirectoryListener(DirectorySelectedListener listener) { dirListenerList.add(listener); } @SuppressWarnings("unused") public void removeDirectoryListener(DirectorySelectedListener listener) { dirListenerList.remove(listener); } /** * Show file dialog */ public void showDialog() { createFileDialog().show(); } private void fireFileSelectedEvent(final File file) { fileListenerList.fireEvent(new FireHandler<FileSelectedListener>() { public void fireEvent(FileSelectedListener listener) { listener.fileSelected(file); } }); } private void fireDirectorySelectedEvent(final File directory) { dirListenerList.fireEvent(new FireHandler<DirectorySelectedListener>() { public void fireEvent(DirectorySelectedListener listener) { listener.directorySelected(directory); } }); } private File getChosenFile(String fileChosen) { if (fileChosen.equals(PARENT_DIR)) return currentPath.getParentFile(); else return new File(currentPath, fileChosen); } @SuppressWarnings("unused") public void setFileEndsWith(String fileEndsWith) { this.fileEndsWith = fileEndsWith != null ? fileEndsWith.toLowerCase(Locale.getDefault()) : null; } public interface FileSelectedListener { void fileSelected(File file); } public interface DirectorySelectedListener { void directorySelected(File directory); } private interface FireHandler<L> { void fireEvent(L listener); } class ListenerList<L> { private List<L> listenerList = newArrayList(); public void add(L listener) { listenerList.add(listener); } public void fireEvent(FireHandler<L> fireHandler) { for (L l : newArrayList(listenerList)) { fireHandler.fireEvent(l); } } public void remove(L listener) { listenerList.remove(listener); } } }