EMMA Coverage Report (generated Sun Apr 20 22:38:01 CEST 2008)
[all classes][net.sf.jomic.tools]

COVERAGE SUMMARY FOR SOURCE FILE [ProgressFrame.java]

nameclass, %method, %block, %line, %
ProgressFrame.java100% (2/2)48%  (11/23)77%  (348/450)73%  (74.9/102)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ProgressFrame$CancelAction100% (1/1)67%  (2/3)59%  (22/37)66%  (5.2/8)
actionPerformed (ActionEvent): void 0%   (0/1)0%   (0/4)0%   (0/2)
<static initializer> 100% (1/1)53%  (8/15)53%  (0.5/1)
ProgressFrame$CancelAction (ProgressFrame, ProgressFrame): void 100% (1/1)78%  (14/18)94%  (4.7/5)
     
class ProgressFrame100% (1/1)45%  (9/20)79%  (326/413)74%  (69.7/94)
actionPerformed (ActionEvent): void 0%   (0/1)0%   (0/28)0%   (0/5)
addActionListener (ActionListener): void 0%   (0/1)0%   (0/5)0%   (0/2)
cancel (): void 0%   (0/1)0%   (0/19)0%   (0/6)
removeActionListener (ActionListener): void 0%   (0/1)0%   (0/5)0%   (0/2)
windowActivated (WindowEvent): void 0%   (0/1)0%   (0/1)0%   (0/1)
windowClosed (WindowEvent): void 0%   (0/1)0%   (0/1)0%   (0/1)
windowClosing (WindowEvent): void 0%   (0/1)0%   (0/3)0%   (0/2)
windowDeactivated (WindowEvent): void 0%   (0/1)0%   (0/1)0%   (0/1)
windowDeiconified (WindowEvent): void 0%   (0/1)0%   (0/1)0%   (0/1)
windowIconified (WindowEvent): void 0%   (0/1)0%   (0/1)0%   (0/1)
windowOpened (WindowEvent): void 0%   (0/1)0%   (0/1)0%   (0/1)
<static initializer> 100% (1/1)80%  (12/15)80%  (0.8/1)
getNormalizedProgress (long, long): int 100% (1/1)81%  (17/21)87%  (2.6/3)
setMaximum (long): void 100% (1/1)81%  (17/21)90%  (3.6/4)
dispose (): void 100% (1/1)85%  (28/33)95%  (5.7/6)
ProgressFrame (): void 100% (1/1)98%  (207/212)100% (43.9/44)
isCanceled (): boolean 100% (1/1)100% (3/3)100% (1/1)
reset (): void 100% (1/1)100% (22/22)100% (6/6)
setNote (String): void 100% (1/1)100% (7/7)100% (3/3)
setProgress (long): void 100% (1/1)100% (13/13)100% (3/3)

1// Jomic - a viewer for comic book archives.
2// Copyright (C) 2004-2008 Thomas Aglassinger
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16package net.sf.jomic.tools;
17 
18import java.awt.Container;
19import java.awt.Dimension;
20import java.awt.GridBagConstraints;
21import java.awt.GridBagLayout;
22import java.awt.Insets;
23import java.awt.event.ActionEvent;
24import java.awt.event.ActionListener;
25import java.awt.event.WindowEvent;
26import java.awt.event.WindowListener;
27 
28import javax.swing.AbstractAction;
29import javax.swing.Action;
30import javax.swing.JButton;
31import javax.swing.JFrame;
32import javax.swing.JLabel;
33import javax.swing.JProgressBar;
34 
35import net.sf.jomic.common.JomicTools;
36import net.sf.jomic.ui.Commands;
37import net.sf.wraplog.Logger;
38 
39/**
40 *  JFrame containing a label to display a note on the status, a progress bar and a "Cancel" button.
41 *  Different to <code>ProgressMonitor</code>, this can be reused after calling <code>reset()</code>
42 *  . Furthermore, the progress values are of type <code>long</code> instead of <code>int</code>.
43 *
44 * @author    Thomas Aglassinger
45 * @see       javax.swing.ProgressMonitor
46 */
47public class ProgressFrame extends JFrame implements ActionListener, WindowListener
48{
49    private static final int INSET = 6;
50 
51    private ActionDelegate actionDelegate;
52    private JButton cancelButton;
53    private boolean canceled;
54    private JomicTools jomicTools;
55    private LocaleTools localeTools;
56    private Logger logger;
57    private long maxProgress;
58    private JLabel noteLabel;
59    private JProgressBar progressBar;
60    private SystemTools systemTools;
61    private UiTools uiTools;
62 
63    public ProgressFrame() {
64        super();
65        logger = Logger.getLogger(ProgressFrame.class);
66        jomicTools = JomicTools.instance();
67        localeTools = LocaleTools.instance();
68        systemTools = SystemTools.instance();
69        uiTools = UiTools.instance();
70 
71        String cancelText = localeTools.getCancelText();
72        Container pane = getContentPane();
73        GridBagConstraints constraints = new GridBagConstraints();
74        Action cancelAction = new CancelAction(this);
75 
76        jomicTools.setIconToJomicLogo(this);
77        actionDelegate = new ActionDelegate(logger);
78        noteLabel = new JLabel("...");
79        progressBar = new JProgressBar();
80        cancelButton = new JButton();
81        cancelButton.setAction(cancelAction);
82        cancelButton.addActionListener(this);
83        uiTools.addKeyStrokeAction(cancelButton, "CANCEL", cancelAction);
84        uiTools.addKeyStrokeAction(cancelButton, "ESCAPE", cancelAction);
85        if (systemTools.isMacOSX()) {
86            uiTools.addKeyStrokeAction(cancelButton, "meta PERIOD", cancelAction);
87        }
88        cancelButton.setText(cancelText);
89        getRootPane().setDefaultButton(cancelButton);
90 
91        Dimension size = progressBar.getPreferredSize();
92 
93        progressBar.setPreferredSize(new Dimension(2 * size.width, size.height));
94 
95        // TODO: Use insets conforming to UI guidelines.
96        pane.setLayout(new GridBagLayout());
97        constraints.anchor = GridBagConstraints.LINE_START;
98        constraints.gridwidth = GridBagConstraints.REMAINDER;
99        constraints.gridx = 0;
100        constraints.gridy = 0;
101        constraints.insets = new Insets(INSET, INSET + INSET / 2, INSET, INSET);
102        pane.add(noteLabel, constraints);
103        constraints.anchor = GridBagConstraints.CENTER;
104        constraints.gridwidth = 1;
105        constraints.gridy += 1;
106        constraints.insets = new Insets(0, INSET, 0, INSET);
107        pane.add(progressBar, constraints);
108        constraints.gridx += 1;
109        constraints.insets = new Insets(0, 0, INSET, INSET);
110        pane.add(cancelButton, constraints);
111        reset();
112        pack();
113        setResizable(false);
114    }
115 
116    /**
117     *  Specifies the maximum value.
118     */
119    public void setMaximum(long newMaximumValue) {
120        assert newMaximumValue > 0;
121        progressBar.setMaximum(getNormalizedProgress(newMaximumValue, newMaximumValue));
122        maxProgress = newMaximumValue;
123    }
124 
125    /**
126     *  Specifies the additional note that is displayed along with the progress message. Used, for
127     *  example, to show which file the is currently being copied during a multiple-file copy.
128     *
129     * @param  newNote  a String specifying the note to display
130     */
131    public void setNote(String newNote) {
132        noteLabel.setText(newNote);
133        validate();
134    }
135 
136    /**
137     *  Indicate the progress of the operation being monitored.
138     *
139     * @param  newProgress  an int specifying the current value, between the maximum and minimum
140     *      specified for this component
141     */
142    public void setProgress(long newProgress) {
143        progressBar.setIndeterminate(false);
144        progressBar.setValue(getNormalizedProgress(newProgress, maxProgress));
145    }
146 
147    public boolean isCanceled() {
148        return canceled;
149    }
150 
151    /**
152     *  Get int-progress from long currentValue normalized in relation to maxValue.
153     */
154    private int getNormalizedProgress(long currentValue, long maxValue) {
155        assert maxValue > 0;
156        double value = (double) currentValue / maxValue;
157 
158        return (int) (value * (Integer.MAX_VALUE / 2));
159    }
160 
161    public void actionPerformed(ActionEvent event) {
162        Object eventSource = event.getSource();
163 
164        assert eventSource == cancelButton : "event.source=" + eventSource;
165        cancel();
166        actionDelegate.actionPerformed(event);
167    }
168 
169    public void addActionListener(ActionListener listener) {
170        actionDelegate.addActionListener(listener);
171    }
172 
173    public void dispose() {
174        if (logger.isDebugEnabled()) {
175            logger.debug("disposing " + ProgressFrame.class);
176        }
177        cancelButton.removeActionListener(this);
178        // HACK: without this, the AWTEventThread would continue to exist.
179        // I have no idea why.
180        progressBar.setIndeterminate(false);
181        super.dispose();
182    }
183 
184    public void removeActionListener(ActionListener listener) {
185        actionDelegate.removeActionListener(listener);
186    }
187 
188    public void reset() {
189        canceled = false;
190        noteLabel.setText(" ");
191        cancelButton.setEnabled(true);
192        progressBar.setValue(progressBar.getMinimum());
193        progressBar.setIndeterminate(true);
194    }
195 
196    public void windowActivated(WindowEvent event) {
197        // Do nothing.
198    }
199 
200    public void windowClosed(WindowEvent event) {
201        // Do nothing.
202    }
203 
204    public void windowClosing(WindowEvent event) {
205        cancel();
206    }
207 
208    public void windowDeactivated(WindowEvent event) {
209        // Do nothing.
210    }
211 
212    public void windowDeiconified(WindowEvent event) {
213        // Do nothing.
214    }
215 
216    public void windowIconified(WindowEvent event) {
217        // Do nothing.
218    }
219 
220    public void windowOpened(WindowEvent event) {
221        // Do nothing.
222    }
223 
224    private synchronized void cancel() {
225        if (!canceled) {
226            cancelButton.setEnabled(false);
227            canceled = true;
228            if (logger.isInfoEnabled()) {
229                logger.info("operation canceled");
230            }
231        }
232    }
233 
234    /**
235     *  Action to cancel a progress frame.
236     *
237     * @author    Thomas Aglassinger
238     */
239    private class CancelAction extends AbstractAction
240    {
241        private ProgressFrame owner;
242 
243        public CancelAction(ProgressFrame newOwner) {
244            super(Commands.CANCEL);
245            assert newOwner != null;
246            owner = newOwner;
247        }
248 
249        public void actionPerformed(ActionEvent event) {
250            owner.cancel();
251        }
252    }
253}

[all classes][net.sf.jomic.tools]
EMMA 2.0.4217 (C) Vladimir Roubtsov