package games.strategy.engine.framework.map.download; import java.awt.GridLayout; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Consumer; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.SwingUtilities; import com.google.common.collect.Maps; import games.strategy.ui.SwingComponents; /** A small non-modal window that holds the progress bars for the current and pending map downloads. */ public final class MapDownloadProgressPanel extends JPanel { private static final long serialVersionUID = -7288639737337542689L; private final DownloadCoordinator downloadCoordinator; /* * Maintain grids that are placed east and west. * This gives us a minimal and uniform width for each column. */ private final JPanel labelGrid = SwingComponents.gridPanel(0, 1); private final JPanel progressGrid = SwingComponents.gridPanel(0, 1); private final List<DownloadFileDescription> downloadList = new ArrayList<>(); private final Map<DownloadFileDescription, JLabel> labels = Maps.newHashMap(); private final Map<DownloadFileDescription, JProgressBar> progressBars = Maps.newHashMap(); public MapDownloadProgressPanel(final JFrame parent) { downloadCoordinator = new DownloadCoordinator(); } public void cancel() { downloadCoordinator.cancelDownloads(); } public void download(List<DownloadFileDescription> newDownloads) { final List<DownloadFileDescription> brandNewDownloads = new ArrayList<>(); for (final DownloadFileDescription download : newDownloads) { if (!downloadList.contains(download) && !download.getMapName().isEmpty()) { brandNewDownloads.add(download); } } newDownloads = brandNewDownloads; if (newDownloads.isEmpty()) { return; } final int itemCount = newDownloads.size() + downloadList.size(); this.removeAll(); add(SwingComponents.horizontalJPanel(labelGrid, progressGrid)); labelGrid.setLayout(new GridLayout(itemCount, 1)); progressGrid.setLayout(new GridLayout(itemCount, 1)); for (final DownloadFileDescription download : newDownloads) { if (download.getMapName().isEmpty()) { continue; } // space at the end of the label so the text does not end right at the progress bar labels.put(download, new JLabel(download.getMapName() + " ")); final JProgressBar progressBar = new JProgressBar(); progressBar.setStringPainted(true); progressBar.setToolTipText("Installing to: " + download.getInstallLocation().getAbsolutePath()); progressBars.put(download, progressBar); } for (int i = newDownloads.size() - 1; i >= 0; i--) { // add new downoads to the head of the list, this will allow the user to see newly added items directly, // rather than having to scroll down to see new items. downloadList.add(0, newDownloads.get(i)); } for (final DownloadFileDescription download : downloadList) { labelGrid.add(labels.get(download)); progressGrid.add(progressBars.get(download)); } revalidate(); repaint(); for (final DownloadFileDescription download : newDownloads) { if (download.getMapName().isEmpty()) { continue; } final JProgressBar progressBar = progressBars.get(download); final Consumer<Integer> progressListener = s -> SwingUtilities.invokeLater(() -> progressBar.setValue(s)); final Runnable completionListener = () -> SwingUtilities.invokeLater(() -> progressBar.setValue(progressBar.getMaximum())); downloadCoordinator.accept(download, progressListener, completionListener, progressBar); } } }