package chatty.gui.components; import chatty.Chatty; import chatty.gui.components.LiveStreamsList.ListDataChangedListener; import chatty.gui.components.menus.ContextMenuAdapter; import chatty.gui.components.menus.ContextMenuListener; import chatty.util.api.StreamInfo; import java.awt.CardLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.List; import javax.swing.JFrame; import javax.swing.JScrollPane; /** * * @author tduva */ public class LiveStreamsDialog extends JFrame { private static final Comparator<StreamInfo> NAME_COMPARATOR = new LiveStreamsNameComparator(); private static final Comparator<StreamInfo> CHANGED_COMPARATOR = new LiveStreamsTimeChangedComparator(); private static final Comparator<StreamInfo> GAME_COMPARATOR = new LiveStreamsGameComparator(); private static final Comparator<StreamInfo> VIEWERS_COMPARATOR = new LiveStreamsViewersComparator(); private final ChannelInfoDialog channelInfo; private static final String BASE_TITLE = "Live Streams"; private final JScrollPane scroll; private final LiveStreamsList list; private final LiveStreamsRemovedList removedList; private final CardLayout cardLayout; private String titleSorting = ""; private String titleCounts = ""; private boolean liveStreamListSelected = true; public LiveStreamsDialog(ContextMenuListener listener) { setTitle("Live Streams"); setPreferredSize(new Dimension(280,350)); ContextMenuListener localCml = new MyContextMenuListener(); LiveStreamListener localLiveStreamListener = new LiveStreamListener() { @Override public void liveStreamClicked(StreamInfo stream) { openChannelInfoDialog(stream); } }; // Create list list = new LiveStreamsList(localLiveStreamListener); list.addContextMenuListener(listener); list.addContextMenuListener(localCml); setSorting(CHANGED_COMPARATOR); list.addListDataChangedListener(new ListDataChangedListener() { @Override public void listDataChanged() { listUpdated(); } @Override public void itemRemoved(StreamInfo item) { removedList.addStreamInfo(item); } @Override public void itemAdded(StreamInfo item) { removedList.removeStreamInfo(item); } }); removedList = new LiveStreamsRemovedList(localLiveStreamListener); removedList.addContextMenuListener(localCml); removedList.addContextMenuListener(listener); removedList.addBackButtonListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { switchList(); } }); // Test data if (Chatty.DEBUG) { List<StreamInfo> testData = new ArrayList<>(); StreamInfo testEntry1 = new StreamInfo("joshimuz", null); testEntry1.set("Crash Nitro Kart WR Attempts - GTA:SA in December hopefully possibly maybe", "Crash Nitro Kart", 140, -1); testEntry1.setDisplayName("Joshimoose"); testData.add(testEntry1); StreamInfo testEntry2 = new StreamInfo("mrnojojojo", null); testEntry2.set("GTA3 Wintermod Race", "Grand Theft Auto III", 123, -1); testData.add(testEntry2); StreamInfo testEntry3 = new StreamInfo("ismokybacon", null); testEntry3.set("GTA:SA Badlands any% Race", "Grand Theft Auto: San Andreas", 14, -1); testData.add(testEntry3); StreamInfo testEntry4 = new StreamInfo("abc", null); testEntry4.set("GTA:SA Badlands any% Race", null, 14, -1); testData.add(testEntry4); for (int i=0;i<0;i++) { StreamInfo newEntry = new StreamInfo("test"+i, null); newEntry.set("Random Title", "Some Game", i, -1); testData.add(newEntry); } list.addStreams(testData); removedList.addStreamInfo(testEntry1); removedList.addStreamInfo(testEntry2); removedList.addStreamInfo(testEntry3); removedList.addStreamInfo(testEntry4); } channelInfo = new ChannelInfoDialog(this); channelInfo.addContextMenuListener(listener); // Add to dialog cardLayout = new CardLayout(); setLayout(cardLayout); scroll = new JScrollPane(list); scroll.getVerticalScrollBar().setUnitIncrement(20); add(scroll); add(removedList); pack(); }; /** * Adds the given stream info to the list, if valid and online, or sets it if it is already in the list. * * @param streamInfo */ public void addStream(StreamInfo streamInfo) { list.addStream(streamInfo); channelInfo.update(streamInfo); } /** * Sets the sorting of the list. * * @param sorting */ public void setSorting(String sorting) { if (sorting.equals("recent")) { setSorting(CHANGED_COMPARATOR); } else if (sorting.equals("name")) { setSorting(NAME_COMPARATOR); } else if (sorting.equals("game")) { setSorting(GAME_COMPARATOR); } else if (sorting.equals("viewers")) { setSorting(VIEWERS_COMPARATOR); } } public void setHistoryRange(int range) { channelInfo.setHistoryRange(range); } /** * Sets the sorting of the list to the given comparator and changes the * title accordingly. * * @param mode */ private void setSorting(Comparator<StreamInfo> mode) { String text = "Sorting: "; if (mode == NAME_COMPARATOR) { text += "Name"; } else if (mode == CHANGED_COMPARATOR) { text += "Recent"; } else if (mode == GAME_COMPARATOR) { text += "Game"; } else if (mode == VIEWERS_COMPARATOR) { text += "Viewers"; } titleSorting = text; updateTitle(); list.setComparator(mode); } private void updateTitle() { if (liveStreamListSelected) { setTitle(BASE_TITLE+" ("+titleCounts+") ["+titleSorting+"]"); } else { setTitle("Offline/Left Streams"); } } /** * Called when any list data was changed (added/removed/"new" color). */ private void listUpdated() { titleCounts = String.valueOf(list.getModel().getSize()); updateTitle(); } private class MyContextMenuListener extends ContextMenuAdapter { @Override public void streamInfosMenuItemClicked(ActionEvent e, Collection<StreamInfo> streams) { String cmd = e.getActionCommand(); if (cmd.equals("openChannelInfo")) { openChannelInfoDialog(streams.iterator().next()); } else if (cmd.equals("showRemovedList")) { switchList(); } } } private void openChannelInfoDialog(StreamInfo info) { if (!channelInfo.isVisible()) { channelInfo.setLocationRelativeTo(LiveStreamsDialog.this); } channelInfo.set(info); channelInfo.setVisible(true); } private void switchList() { liveStreamListSelected = !liveStreamListSelected; updateTitle(); cardLayout.next(getContentPane()); } /** * Comparator to sort StreamInfo objects by the name of the stream. */ private static class LiveStreamsNameComparator implements Comparator<StreamInfo> { @Override public int compare(StreamInfo o1, StreamInfo o2) { return o1.getStream().compareTo(o2.getStream()); } } /** * Comparator to sort StreamInfo objects by the last time the status was * changed. */ private static class LiveStreamsTimeChangedComparator implements Comparator<StreamInfo> { @Override public int compare(StreamInfo o1, StreamInfo o2) { long time1 = o1.getStatusChangeTimeAgo(); long time2 = o2.getStatusChangeTimeAgo(); //System.out.println("Comparing: "+o1.getStream()+time1+" "+time2+o2.getStream()); if (time1 == time2) { return o1.getStream().compareTo(o2.getStream()); } if (time1 > time2) { return 1; } return -1; } } /** * Comparator to sort StreamInfo objects by the game. */ private static class LiveStreamsGameComparator implements Comparator<StreamInfo> { @Override public int compare(StreamInfo o1, StreamInfo o2) { String game1 = o1.getGame(); String game2 = o2.getGame(); //if (game1 == game2 || (game1 != null && game1.equals(game2))) { if (game1 == null ? game2 == null : game1.equals(game2)) { return o1.getStream().compareTo(o2.getStream()); } if (game1 == null) { return 1; } if (game2 == null) { return -1; } return game1.compareTo(game2); } } /** * Comparator to sort StreamInfo objects by the name of the stream. */ private static class LiveStreamsViewersComparator implements Comparator<StreamInfo> { @Override public int compare(StreamInfo o1, StreamInfo o2) { if (o1.getViewers() > o2.getViewers()) { return -1; } if (o1.getViewers() < o2.getViewers()) { return 1; } return o1.getStream().compareTo(o2.getStream()); } } }