package org.limewire.ui.swing.options; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Component; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JToggleButton; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableModel; import net.miginfocom.swing.MigLayout; import org.jdesktop.swingx.JXButton; import org.jdesktop.swingx.JXTable; import org.jdesktop.swingx.table.TableColumnExt; import org.limewire.core.api.Category; import org.limewire.core.api.file.CategoryManager; import org.limewire.ui.swing.components.FocusJOptionPane; import org.limewire.ui.swing.components.MultiLineLabel; import org.limewire.ui.swing.components.decorators.ButtonDecorator; import org.limewire.ui.swing.components.decorators.TableDecorator; import org.limewire.ui.swing.options.actions.OKDialogAction; import org.limewire.ui.swing.table.DefaultLimeTableCellRenderer; import org.limewire.ui.swing.util.I18n; import org.limewire.ui.swing.util.IconManager; import org.limewire.util.OSUtils; import com.google.inject.Inject; /** * A panel that simply displays the current file to category associations being used. */ public class ExtensionClassificationPanel extends JPanel { private static final Category[] ALL_CATEGORIES = Category.values(); private static final String TABLE_VIEW = "TABLE_VIEW"; private static final String OTHER_VIEW = "OTHER_VIEW"; private final CategoryManager categoryManager; private final IconManager iconManager; private final ButtonDecorator buttonDecorator; private final JXTable table; private final JPanel contentPanel; private final CardLayout contentSwitcher; private Category[] currentCategories = null; private final JPanel switchPanel; @Inject public ExtensionClassificationPanel(CategoryManager categoryManager, IconManager iconManager, TableDecorator tableDecorator, ButtonDecorator buttonDecorator) { super(new BorderLayout()); this.categoryManager = categoryManager; this.iconManager = iconManager; this.buttonDecorator = buttonDecorator; setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); setOpaque(false); add(new JLabel("<html>"+I18n.tr("Below are the file extensions LimeWire knows about and how they are classified throughout the program")+"</html>"), BorderLayout.NORTH); JPanel centerPanel = new JPanel(new BorderLayout()); centerPanel.setOpaque(false); switchPanel = new JPanel(new MigLayout("insets 10, gap 5")); switchPanel.setOpaque(false); centerPanel.add(switchPanel, BorderLayout.NORTH); table = new JXTable(); tableDecorator.decorate(table); table.setShowGrid(false, false); table.setColumnSelectionAllowed(false); table.setSelectionMode(0); table.setDefaultRenderer(Object.class, new DefaultLimeTableCellRenderer()); JScrollPane scrollPane = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrollPane.setOpaque(false); contentSwitcher = new CardLayout(); contentPanel = new JPanel(contentSwitcher); contentPanel.setOpaque(false); contentPanel.add(scrollPane, TABLE_VIEW); JPanel otherPanel = new JPanel(new GridBagLayout()); otherPanel.setOpaque(false); JLabel otherLabel = new MultiLineLabel(I18n.tr("File types that LimeWire doesn't know about are " + "classified as \"Other\". Add these files to a List by dragging them, or " + "when adding a folder, click \"Advanced\" and choose specific file " + "extensions"), 450); otherLabel.setOpaque(false); otherPanel.add(otherLabel); contentPanel.add(otherPanel, OTHER_VIEW); centerPanel.add(contentPanel, BorderLayout.CENTER); add(centerPanel, BorderLayout.CENTER); } /** * Builds a table model containing the extension association information for a given * set of categories. */ private TableModel createTableModel(Category... categories) { Collection<String> extensions = new HashSet<String>(); for ( Category category : categories ) { extensions.addAll(categoryManager.getExtensionsForCategory(category)); } List<String> sortedList = new ArrayList<String>(extensions); Collections.sort(sortedList); extensions = sortedList; List<String> headingList = new ArrayList<String>(); headingList.add(""); // Icon headingList.add(I18n.tr("Extension")); if (categories.length > 1) { headingList.add(I18n.tr("Category")); } if (OSUtils.isWindows()) { headingList.add(I18n.tr("Type")); } Object[][] data = new Object[extensions.size()][headingList.size()]; int y = 0; for ( String ext : extensions ) { int x = 0; Icon icon = iconManager.getIconForExtension(ext); data[y][x++] = icon; data[y][x++] = ext; if (categories.length > 1) { data[y][x++] = I18n.tr(categoryManager.getCategoryForExtension(ext).getSingularName()); } if (OSUtils.isWindows() && icon != null) { if (!icon.toString().startsWith("file:/")) { data[y][x++] = icon.toString(); } } y++; } return new DefaultTableModel(data, headingList.toArray()) { @Override public Class<?> getColumnClass(int column) { if (column == 0) { return Icon.class; } else { return String.class; } } }; } private class CategorySwitchAction extends AbstractAction { private final Category[] categoriesForSwitch; public CategorySwitchAction(String name, Category... categoriesForSwitch) { super(name); this.categoriesForSwitch = categoriesForSwitch; } public CategorySwitchAction(Category... categoriesForSwitch) { super(I18n.tr(categoriesForSwitch[0].getPluralName())); this.categoriesForSwitch = categoriesForSwitch; } @Override public void actionPerformed(ActionEvent e) { switchCategory(categoriesForSwitch); updateSelection((JButton)e.getSource()); } public Category[] getCategoriesForSwitch() { return categoriesForSwitch; } } /** * Switch the visible tab to the one containing the category. * * <p> Null category implies the all category as a shortcut if * ever needed */ public void switchCategory(Category category) { if (category == null) { switchCategory(ALL_CATEGORIES); } else { switchCategory(new Category[] {category}); } updateSelection(category); } private void switchCategory(Category... categories) { if (categories == currentCategories) { return; } if (categories.length == 1 && categories[0] == Category.OTHER) { contentSwitcher.show(contentPanel, OTHER_VIEW); } else { contentSwitcher.show(contentPanel, TABLE_VIEW); } currentCategories = categories; TableModel model = createTableModel(currentCategories); table.setModel(model); TableColumnExt iconColumn = table.getColumnExt(model.getColumnName(0)); iconColumn.setResizable(false); iconColumn.setMinWidth(16); iconColumn.setMaxWidth(16); iconColumn.setWidth(16); iconColumn.setComparator(new Comparator<ImageIcon>() { @Override public int compare(ImageIcon o1, ImageIcon o2) { return o1.getImage().toString().compareTo(o2.getImage().toString()); } }); } private void updateSelection(JButton button) { button.setSelected(true); for ( Component comp : switchPanel.getComponents() ) { if (comp instanceof JButton && button != comp) { ((JButton)comp).setSelected(false); } } } private void updateSelection(Category category) { for ( Component comp : switchPanel.getComponents() ) { if (comp instanceof JButton) { JButton button = ((JButton)comp); Category[] categoriesForSwitch = ((CategorySwitchAction)button.getAction()).getCategoriesForSwitch(); if (category == null) { button.setSelected(categoriesForSwitch.length > 1); } else { button.setSelected(categoriesForSwitch.length != 0 && categoriesForSwitch[0] == category); } } } } private JButton createSelectionButton(Action action) { JXButton button = new JXButton(action); button.setModel(new JToggleButton.ToggleButtonModel()); buttonDecorator.decorateLinkButton(button); return button; } /** * Loads the panel for use. Builds the table and lays out the component. */ public void init() { if (currentCategories == null) { switchCategory(ALL_CATEGORIES); } switchPanel.removeAll(); switchPanel.invalidate(); switchPanel.add(new JLabel(I18n.tr("Show:"))); JButton allButton = createSelectionButton(new CategorySwitchAction(I18n.tr("All"), ALL_CATEGORIES)); allButton.setSelected(currentCategories == ALL_CATEGORIES); switchPanel.add(allButton); for ( Category category : ALL_CATEGORIES ) { JButton categoryButton = createSelectionButton(new CategorySwitchAction(category)); categoryButton.setSelected(currentCategories.length == 1 && category == currentCategories[0]); switchPanel.add(categoryButton); } } public void showDialogue() { init(); JDialog dialog = FocusJOptionPane.createDialog(I18n.tr("File extension Classification"), null, this); JPanel buttonPanel = new JPanel(new MigLayout("insets 0 0 10 10, gap 4, fill")); buttonPanel.setOpaque(false); buttonPanel.add(new JButton(new OKDialogAction()), "tag ok"); dialog.getContentPane().add(buttonPanel, BorderLayout.SOUTH); dialog.pack(); table.requestFocusInWindow(); dialog.setVisible(true); } }