/* Copyright 2009 Hauke Rehfeld This file is part of QuakeInjector. QuakeInjector is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QuakeInjector is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QuakeInjector. If not, see <http://www.gnu.org/licenses/>. */ package de.haukerehfeld.quakeinjector; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Rectangle; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayDeque; import java.util.Queue; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.Scrollable; import de.haukerehfeld.quakeinjector.gui.ProgressPopup; public class InstallQueuePanel extends JPanel implements Scrollable { private final static int size = 5; private final static int rowHeight = 20; private final static int MARGIN = 3; private GridBagLayout layout = new GridBagLayout(); private Queue<Job> jobs = new ArrayDeque<Job>(); public InstallQueuePanel() { setLayout(layout); } /** * @return PropertyChangeListener that listens on "progress" for the progressbar */ public Job addJob(String description, ActionListener cancelAction) { Job progressListener = new Job(cancelAction, description); jobs.offer(progressListener); layoutComponents(); scrollRectToVisible(new Rectangle(0, getHeight(), 0, 100)); return progressListener; } private void layoutComponents() { int row = 0; for (Job j: jobs) { remove(j.progressBar); remove(j.cancelButton); remove(j.finishedLabel); //System.out.println("removing finishedlabel"); final int row_ = row; if (!j.finished) { add(j.progressBar, new ProgressBarConstraints() {{ gridy = row_; }}); add(j.cancelButton, new CancelButtonConstraints() {{ gridy = row_; }}); } else { add(j.finishedLabel, new FinishedLabelConstraints() {{ gridy = row_; }}); //System.out.println("adding finishedlabel"); } row++; } revalidate(); repaint(); } public void finished(final Job j, String message) { j.finish(message); layoutComponents(); } @Override public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } @Override public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { return rowHeight; } @Override public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { return rowHeight; } @Override public boolean getScrollableTracksViewportWidth() { return true; } @Override public boolean getScrollableTracksViewportHeight() { return false; } private class RowConstraints extends GridBagConstraints {{ anchor = CENTER; fill = HORIZONTAL; insets = new java.awt.Insets(MARGIN, MARGIN, MARGIN, MARGIN); }} private class ProgressBarConstraints extends RowConstraints {{ weightx = 1; weighty = 1; }} private class CancelButtonConstraints extends RowConstraints {{ gridx = 1; }} private class FinishedLabelConstraints extends RowConstraints {{ weightx = 1; gridwidth = 2; }} public static class Job implements PropertyChangeListener { private JProgressBar progressBar; private JButton cancelButton; private JLabel finishedLabel; private String description; private boolean finished = false; public Job(ActionListener cancelAction, String description) { this.description = description; progressBar = new JProgressBar(); progressBar.setString(ProgressPopup.progressString(description, 0)); progressBar.setValue(0); progressBar.setStringPainted(true); cancelButton = new JButton("Cancel"); cancelButton.addActionListener(cancelAction); finishedLabel = new JLabel(description); } public void propertyChange(PropertyChangeEvent evt) { if ("progress" == evt.getPropertyName()) { int p = (Integer) evt.getNewValue(); setProgress(p); } } public void setProgress(int progress) { progressBar.setString(ProgressPopup.progressString(description, progress)); progressBar.setValue(progress); } private void finish(String message) { finished = true; progressBar.setEnabled(false); cancelButton.setEnabled(false); finishedLabel.setText(ProgressPopup.progressString(description, message)); finishedLabel.setPreferredSize(new Dimension((int) finishedLabel .getPreferredSize().getWidth(), (int) cancelButton.getSize().getHeight())); } } }