/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.base.explorer.list; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.DirectoryStream.Filter; import java.nio.file.Files; import java.nio.file.Path; import java.util.Comparator; import java.util.Optional; import java.util.stream.StreamSupport; import javax.swing.AbstractListModel; import javax.swing.DefaultListModel; import javax.swing.JList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.weasis.base.explorer.JIExplorerContext; import org.weasis.base.explorer.JIThumbnailCache; import org.weasis.base.explorer.TreeNode; import org.weasis.core.api.media.data.ImageElement; import org.weasis.core.api.media.data.MediaElement; import org.weasis.core.api.media.data.MediaReader; import org.weasis.core.ui.editor.ViewerPluginBuilder; @SuppressWarnings({ "serial" }) public abstract class AThumbnailModel<E extends MediaElement> extends AbstractListModel<E> implements IThumbnailModel<E> { private static final Logger LOGGER = LoggerFactory.getLogger(AThumbnailModel.class); protected JIExplorerContext reloadContext; protected boolean loading = false; protected final JList<E> list; protected final DefaultListModel<E> listModel; public AThumbnailModel(final JList<E> list) { this.list = list; // Fix list reselection interval when dragging this.list.putClientProperty("List.isFileList", Boolean.TRUE); //$NON-NLS-1$ listModel = new DefaultListModel<>(); list.setModel(listModel); } public synchronized boolean loading() { return this.loading; } @Override public synchronized void notifyAsUpdated(final int index) { fireContentsChanged(this, index, index); } @Override public void reload() { Optional<TreeNode> t = this.reloadContext.getSelectedDirNodes().stream().findFirst(); if (t.isPresent()) { setData(t.get().getNodePath()); } } @Override public final synchronized JIExplorerContext getReloadContext() { return this.reloadContext; } @Override public final synchronized void setReloadContext(final JIExplorerContext reloadContext) { this.reloadContext = reloadContext; } public final synchronized boolean isLoading() { return this.loading; } @Override public int getSize() { return listModel.getSize(); } @Override public E getElementAt(final int index) { return listModel.getElementAt(index); } @Override public void clear() { for (int i = 0; i < listModel.size(); i++) { E m = listModel.getElementAt(i); if (m instanceof ImageElement) { JIThumbnailCache.removeInQueue((ImageElement) m); } } list.getSelectionModel().clearSelection(); listModel.clear(); } @Override public boolean isEmpty() { return listModel.isEmpty(); } @Override public void addElement(E element) { listModel.addElement(element); } @Override public boolean contains(E elem) { return listModel.contains(elem); } @Override public boolean removeElement(E obj) { if (obj instanceof ImageElement) { JIThumbnailCache.removeInQueue((ImageElement) obj); } return listModel.removeElement(obj); } @Override public void loadContent(Path path, Filter<Path> filter) { if (path == null) { return; } clear(); try (DirectoryStream<Path> stream = Files.newDirectoryStream(path, filter)) { StreamSupport.stream(stream.spliterator(), false).sorted(Comparator.comparing(Path::getFileName)) .forEachOrdered(p -> { MediaReader media = ViewerPluginBuilder.getMedia(p.toFile()); if (media != null) { MediaElement preview = media.getPreview(); if (preview instanceof ImageElement) { preview.getFileCache().setRequireTransformation(true); addElement((E) preview); } if (getSize() == 1) { this.list.setSelectedIndex(0); } } }); } catch (IOException e) { LOGGER.error("Building child directories", e); //$NON-NLS-1$ } } @Override public void loadContent(Path path) { DirectoryStream.Filter<Path> filter = p -> !Files.isDirectory(p); loadContent(path, filter); } @Override public abstract void setData(Path path); }