Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.gui

File ProgressBar.java

 

Coverage histogram

../../img/srcFileCovDistChart7.png
28% of files have more coverage

Code metrics

18
55
10
1
270
150
21
0.38
5.5
10
2.1

Classes

Class Line # Actions
ProgressBar 45 55 21 30
0.638554263.9%
 

Contributing tests

This file is covered by 77 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.gui;
22   
23    import jalview.util.MessageManager;
24   
25    import java.awt.BorderLayout;
26    import java.awt.Component;
27    import java.awt.GridLayout;
28    import java.awt.event.ActionEvent;
29    import java.awt.event.ActionListener;
30    import java.util.Hashtable;
31    import java.util.Map;
32   
33    import javax.swing.JButton;
34    import javax.swing.JLabel;
35    import javax.swing.JPanel;
36    import javax.swing.JProgressBar;
37    import javax.swing.SwingUtilities;
38   
39    /**
40    * A class to manage multiple progress bars embedded in a JPanel.
41    */
42    /*
43    * Refactored from code duplicated in AlignFrame, PCAPanel, WebserviceInfo.
44    */
 
45    public class ProgressBar implements IProgressIndicator
46    {
47    /*
48    * Progress bars in progress, keyed by any arbitrary long value
49    */
50    Map<Long, JPanel> progressBars;
51   
52    /*
53    * Optional handlers for the progress bars
54    */
55    Map<Long, IProgressIndicatorHandler> progressBarHandlers;
56   
57    /*
58    * The panel containing the progress bars - must have GridLayout
59    */
60    private JPanel statusPanel;
61   
62    /*
63    * Optional label where a status update message can be written on completion
64    * of progress
65    */
66    private JLabel statusBar;
67   
68    /**
69    * Constructor. Note that the container of the progress bars, and the status
70    * bar to which an optional completion message is written, should be unchanged
71    * for the lifetime of this object for consistent behaviour.
72    *
73    * @param container
74    * the panel holding the progress bars; must have GridLayout manager
75    * @param statusBar
76    * an optional place to write a message when a progress bar is
77    * removed
78    */
 
79  197 toggle public ProgressBar(JPanel container, JLabel statusBar)
80    {
81  197 if (container == null)
82    {
83  1 throw new NullPointerException();
84    }
85  196 if (!GridLayout.class
86    .isAssignableFrom(container.getLayout().getClass()))
87    {
88  1 throw new IllegalArgumentException("Container must have GridLayout");
89    }
90  195 this.statusPanel = container;
91  195 this.statusBar = statusBar;
92  195 this.progressBars = new Hashtable<>();
93  195 this.progressBarHandlers = new Hashtable<>();
94   
95    }
96   
97    /**
98    * Returns true if any progress bars are still active
99    *
100    * @return
101    */
 
102  0 toggle @Override
103    public boolean operationInProgress()
104    {
105  0 if (progressBars != null && progressBars.size() > 0)
106    {
107  0 return true;
108    }
109  0 return false;
110    }
111   
112    /**
113    * First call for a given id will show the message as a new progress bar. A
114    * second call with the same id will remove it. The 'removal' message is
115    * written to the status bar field (if neither is null).
116    *
117    * To avoid progress bars being left orphaned, ensure their removal is
118    * performed in a finally block if there is any risk of an error during
119    * execution.
120    */
 
121  14 toggle @Override
122    public void setProgressBar(final String message, final long id)
123    {
124  14 SwingUtilities.invokeLater(new Runnable()
125    {
 
126  14 toggle @Override
127    public void run()
128    {
129  14 JPanel progressPanel = progressBars.get(id);
130  14 if (progressPanel != null)
131    {
132    /*
133    * Progress bar is displayed for this id - remove it now, and any handler
134    */
135  7 progressBars.remove(id);
136  7 if (message != null && statusBar != null)
137    {
138  1 statusBar.setText(message);
139    }
140  7 if (progressBarHandlers.containsKey(id))
141    {
142  0 progressBarHandlers.remove(id);
143    }
144  7 removeRow(progressPanel);
145    }
146    else
147    {
148    /*
149    * No progress bar for this id - add one now
150    */
151  7 progressPanel = new JPanel(new BorderLayout(10, 5));
152   
153  7 JProgressBar progressBar = new JProgressBar();
154  7 progressBar.setIndeterminate(true);
155   
156  7 progressPanel.add(new JLabel(message), BorderLayout.WEST);
157  7 progressPanel.add(progressBar, BorderLayout.CENTER);
158   
159  7 addRow(progressPanel);
160   
161  7 progressBars.put(id, progressPanel);
162    }
163   
164  14 refreshLayout();
165    }
166    });
167   
168    }
169   
170    /**
171    * Lays out progress bar container hierarchy
172    */
 
173  14 toggle protected void refreshLayout()
174    {
175    /*
176    * lay out progress bar container hierarchy
177    */
178  14 Component root = SwingUtilities.getRoot(statusPanel);
179  14 if (root != null)
180    {
181  8 root.validate();
182    }
183    }
184   
185    /**
186    * Remove one row with a progress bar, in a thread-safe manner
187    *
188    * @param progressPanel
189    */
 
190  7 toggle protected void removeRow(JPanel progressPanel)
191    {
192  7 synchronized (statusPanel)
193    {
194  7 statusPanel.remove(progressPanel);
195  7 GridLayout layout = (GridLayout) statusPanel.getLayout();
196  7 layout.setRows(layout.getRows() - 1);
197  7 statusPanel.remove(progressPanel);
198    }
199    }
200   
201    /**
202    * Add one row with a progress bar, in a thread-safe manner
203    *
204    * @param progressPanel
205    */
 
206  7 toggle protected void addRow(JPanel progressPanel)
207    {
208  7 synchronized (statusPanel)
209    {
210  7 GridLayout layout = (GridLayout) statusPanel.getLayout();
211  7 layout.setRows(layout.getRows() + 1);
212  7 statusPanel.add(progressPanel);
213    }
214    }
215   
216    /**
217    * Add a 'Cancel' handler for the given progress bar id. This should be called
218    * _after_ setProgressBar to have any effect.
219    */
 
220  0 toggle @Override
221    public void registerHandler(final long id,
222    final IProgressIndicatorHandler handler)
223    {
224  0 final IProgressIndicator us = this;
225   
226  0 SwingUtilities.invokeLater(new Runnable()
227    {
 
228  0 toggle @Override
229    public void run()
230    {
231  0 final JPanel progressPanel = progressBars.get(id);
232  0 if (progressPanel == null)
233    {
234  0 System.err.println(
235    "call setProgressBar before registering the progress bar's handler.");
236  0 return;
237    }
238   
239    /*
240    * Nothing useful to do if not a Cancel handler
241    */
242  0 if (!handler.canCancel())
243    {
244  0 return;
245    }
246   
247  0 progressBarHandlers.put(id, handler);
248  0 JButton cancel = new JButton(
249    MessageManager.getString("action.cancel"));
250  0 cancel.addActionListener(new ActionListener()
251    {
252   
 
253  0 toggle @Override
254    public void actionPerformed(ActionEvent e)
255    {
256  0 handler.cancelActivity(id);
257  0 us.setProgressBar(MessageManager
258    .formatMessage("label.cancelled_params", new Object[]
259    { ((JLabel) progressPanel.getComponent(0)).getText() }),
260    id);
261    }
262    });
263  0 progressPanel.add(cancel, BorderLayout.EAST);
264  0 refreshLayout();
265   
266    }
267    });
268    }
269   
270    }