package org.limewire.ui.swing.library.sharing; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import net.miginfocom.swing.MigLayout; import org.jdesktop.application.Resource; import org.jdesktop.swingx.JXTable; import org.limewire.collection.glazedlists.GlazedListsFactory; import org.limewire.friend.api.Friend; import org.limewire.friend.api.FriendEvent; import org.limewire.inject.LazySingleton; import org.limewire.listener.EventListener; import org.limewire.listener.ListenerSupport; import org.limewire.listener.SwingEDTEvent; import org.limewire.ui.swing.components.HyperlinkButton; import org.limewire.ui.swing.table.GlazedJXTable; import org.limewire.ui.swing.util.GuiUtils; import org.limewire.ui.swing.util.I18n; import ca.odell.glazedlists.BasicEventList; import ca.odell.glazedlists.EventList; import ca.odell.glazedlists.SortedList; import ca.odell.glazedlists.gui.TableFormat; import ca.odell.glazedlists.impl.swing.SwingThreadProxyEventList; import ca.odell.glazedlists.swing.DefaultEventTableModel; import com.google.inject.Inject; import com.google.inject.name.Named; @LazySingleton class LibrarySharingFriendListPanel { @Resource private Font labelFont; @Resource private Color labelColor; @Resource private Font linkFont; @Resource private Color backgroundColor; private final JPanel component; private final JLabel headerLabel; private final HyperlinkButton editButton; private final Map<String, Friend> knownFriends; private final List<String> sharedIds; private final LibrarySharingFriendListRenderer renderer; private final EventList<String> eventList; private final JXTable friendList; private final JScrollPane scrollPane; @Inject public LibrarySharingFriendListPanel(EditSharingAction sharingAction, @Named("known") Map<String, Friend> knownFriends) { GuiUtils.assignResources(this); this.knownFriends = knownFriends; this.friendList = new GlazedJXTable(); this.sharedIds = new ArrayList<String>(); eventList = new BasicEventList<String>(); SortedList<String> sortedList = GlazedListsFactory.sortedList(eventList, new FriendComparator()); SwingThreadProxyEventList<String> stpl = GlazedListsFactory.swingThreadProxyEventList(sortedList); friendList.setModel(new DefaultEventTableModel<String>(stpl, new FriendTableFormat())); component = new JPanel(new MigLayout("insets 0, gap 0, fillx", "134!", "")); component.setOpaque(false); headerLabel = new JLabel(); headerLabel.setFont(labelFont); headerLabel.setForeground(labelColor); component.add(headerLabel, "aligny top, gaptop 8, gapleft 6, gapbottom 6, wrap"); friendList.setTableHeader(null); friendList.setShowGrid(false, false); friendList.setFocusable(false); friendList.setBackground(backgroundColor); scrollPane = new JScrollPane(friendList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setMinimumSize(new Dimension(0,0)); scrollPane.setBorder(BorderFactory.createEmptyBorder(1,0,1,0)); scrollPane.setBackground(backgroundColor); renderer = new LibrarySharingFriendListRenderer(scrollPane); friendList.getColumnExt(0).setCellRenderer(renderer); component.add(scrollPane, "grow, wrap"); editButton = new HyperlinkButton(I18n.tr("Edit Sharing"), sharingAction); editButton.setFont(linkFont); component.add(editButton, "aligny top, gaptop 5, gapleft 6, gapbottom 5, wrap"); scrollPane.getVerticalScrollBar().addComponentListener(new ComponentListener(){ @Override public void componentHidden(ComponentEvent e) { scrollPane.setBorder(BorderFactory.createEmptyBorder(1,0,1,0)); } @Override public void componentShown(ComponentEvent e) { scrollPane.setBorder(BorderFactory.createMatteBorder(1,0,1,0, Color.BLACK)); } @Override public void componentMoved(ComponentEvent e) {} @Override public void componentResized(ComponentEvent e) {} }); } @Inject void register(@Named("known") ListenerSupport<FriendEvent> friendSupport) { friendSupport.addListener(new EventListener<FriendEvent>() { @Override @SwingEDTEvent public void handleEvent(FriendEvent event) { switch(event.getType()) { case ADDED: setSharedFriendIds(sharedIds); break; } } }); } void clear() { eventList.clear(); } /** Sets the list of IDs this is shared with. */ void setSharedFriendIds(List<String> newFriendIds) { if(!newFriendIds.isEmpty()) { headerLabel.setText(I18n.tr("Sharing list with...")); } else { headerLabel.setText(I18n.tr("Not Shared")); } // Only set if we're not refreshing.. if(newFriendIds != sharedIds) { sharedIds.clear(); sharedIds.addAll(new ArrayList<String>(newFriendIds)); } List<String> newModel = new ArrayList<String>(); int unknown = 0; for(String id : sharedIds) { Friend friend = knownFriends.get(id); if(friend != null) { newModel.add(friend.getRenderName()); } else { unknown++; } } if(unknown > 0) { newModel.add(I18n.tr("{0} friends from other accounts", unknown)); // TODO: Do something about row sizes. friendList.setRowHeightEnabled(true); } else { friendList.setRowHeightEnabled(false); } eventList.clear(); eventList.addAll(newModel); friendList.setVisibleRowCount(newModel.size()); component.revalidate(); } JComponent getComponent() { return component; } private static class FriendComparator implements Comparator<String> { @Override public int compare(String name1, String name2) { return name1.compareToIgnoreCase(name2); } } private static class FriendTableFormat implements TableFormat<String> { @Override public int getColumnCount() { return 1; } @Override public String getColumnName(int column) { return ""; } @Override public Object getColumnValue(String baseObject, int column) { return baseObject; } } }