package org.limewire.ui.swing.images; import java.awt.Color; import java.awt.Insets; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import java.util.List; import javax.swing.BorderFactory; import javax.swing.JList; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import org.jdesktop.application.Resource; import org.jdesktop.swingx.JXList; import org.limewire.core.api.file.CategoryManager; import org.limewire.core.api.library.LocalFileItem; import org.limewire.ui.swing.components.Disposable; import org.limewire.ui.swing.library.table.LibraryPopupMenu; import org.limewire.ui.swing.table.TablePopupHandler; import org.limewire.ui.swing.util.GuiUtils; import org.limewire.ui.swing.util.NativeLaunchUtils; import ca.odell.glazedlists.EventList; import ca.odell.glazedlists.ListSelection; import ca.odell.glazedlists.swing.DefaultEventListModel; import ca.odell.glazedlists.swing.DefaultEventSelectionModel; import com.google.inject.Inject; import com.google.inject.Provider; /** * Draws a list of images. Images are displayed in a horizontal left * to right space before wrapping to a new line. Spaces between the * images are injected with the inset values list below. */ public class ImageList extends JXList implements Disposable { @Resource private Color backgroundListcolor; private final ImageCellRenderer imageCellRenderer; private final CategoryManager categoryManager; private DefaultEventListModel cachedEventListModel; private DefaultEventSelectionModel<LocalFileItem> cachedEventSelectionModel; @Inject public ImageList(final ImageCellRenderer imageCellRenderer, Provider<LibraryPopupMenu> libraryPopupMenu, CategoryManager categoryManager) { this.imageCellRenderer = imageCellRenderer; this.categoryManager = categoryManager; GuiUtils.assignResources(this); setBackground(backgroundListcolor); setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); setLayoutOrientation(JList.HORIZONTAL_WRAP); //this must be set to negative 1 to get horizontal line wrap setVisibleRowCount(-1); setCellRenderer(imageCellRenderer); //TODO: fix this, component dimensions not beign created yet without setting this imageCellRenderer.setBorder(BorderFactory.createEmptyBorder(15,7,0,7)); // add in inset size when calculated fixed cell dimensions // inset spacing is the white space you will see between images Insets insets = imageCellRenderer.getBorder().getBorderInsets(imageCellRenderer); setFixedCellHeight(imageCellRenderer.getHeight() + insets.top + insets.bottom); setFixedCellWidth(imageCellRenderer.getWidth() + insets.left + insets.right); //enable double click launching of image files. addMouseListener(new ImageDoubleClickMouseListener()); setPopupHandler(new ImagePopupHandler(this, libraryPopupMenu)); } public void setModel(EventList<LocalFileItem> eventList) { DefaultEventListModel newEventListModel = new DefaultEventListModel<LocalFileItem>(eventList); DefaultEventSelectionModel<LocalFileItem> newEventSelectionModel = new DefaultEventSelectionModel<LocalFileItem>(eventList); setSelectionModel(newEventSelectionModel); setModel(newEventListModel); newEventSelectionModel.setSelectionMode(ListSelection.MULTIPLE_INTERVAL_SELECTION_DEFENSIVE); if(cachedEventListModel != null) { cachedEventSelectionModel.dispose(); cachedEventListModel.dispose(); } cachedEventListModel = newEventListModel; cachedEventSelectionModel = newEventSelectionModel; } /** Returns all currently selected LocalFileItems. */ public List<LocalFileItem> getSelectedItems() { return cachedEventSelectionModel.getSelected(); } @Override public void dispose() { if(cachedEventListModel != null) { cachedEventSelectionModel.dispose(); cachedEventListModel.dispose(); } } /** * Sets the popup Handler for this List. */ public void setPopupHandler(final TablePopupHandler popupHandler) { addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { maybeShowPopup(e); } @Override public void mousePressed(MouseEvent e) { maybeShowPopup(e); } private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { popupHandler.maybeShowPopup(e.getComponent(), e.getX(), e.getY()); } } }); } /** * Returns the CellRenderer for this list. */ public ImageCellRenderer getImageCellRenderer() { return imageCellRenderer; } /** * This class listens for double clicks inside of the ImageList. * When a double click is detected, the relevant item in the list is launched. */ private final class ImageDoubleClickMouseListener extends MouseAdapter { @Override public void mouseClicked(MouseEvent e) { if(SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) { ImageList imageList = (ImageList)e.getComponent(); int index = imageList.locationToIndex(e.getPoint()); if(index >= 0) { LocalFileItem val = (LocalFileItem) imageList.getElementAt(index); File file = val.getFile(); NativeLaunchUtils.safeLaunchFile(file, categoryManager); } } } } }