001:package com.xoetrope.resource;
002:
003:import java.io.File;
004:import java.util.prefs.Preferences;
005:
006:import java.awt.event.ActionListener;
007:import java.awt.event.ActionEvent;
008:import javax.swing.event.ListSelectionListener;
009:import javax.swing.event.ListSelectionEvent;
010:
011:import javax.swing.JFileChooser;
012:import javax.swing.JOptionPane;
013:import javax.swing.SwingUtilities;
014:
015:import net.xoetrope.swing.XEdit;
016:import net.xoetrope.swing.XCheckbox;
017:import net.xoetrope.swing.XList;
018:import net.xoetrope.swing.XButton;
019:import net.xoetrope.swing.XLabel;
020:import net.xoetrope.swing.XPanel;
021:import com.xoetrope.swing.XProgressBar;
022:
023:import net.xoetrope.xui.XPage;
024:import net.xoetrope.xui.XProject;
025:import net.xoetrope.xui.data.XBaseModel;
026:import net.xoetrope.xui.helper.SwingWorker;
027:import net.xoetrope.xui.helper.XTranslator;
028:import net.xoetrope.xui.helper.XuiUtilities;
029:import net.xoetrope.xui.style.XStyle;
030:
031:import net.xoetrope.optional.annotation.Find;
032:import net.xoetrope.optional.annotation.Event;
033:import net.xoetrope.optional.annotation.XPageAnnotationProcessor;
034:
035:/**
036: * <p>A panel for showing download progress. The panel may contain the following
037: * components</p>
038: * <ul>
039: * <li>fileList, an XList showing the list of files to download</li>
040: * <li>downloadProgress, a XProgressBar showing the overall download progress</li>
041: * <li>downloadStatus, a XLabel showing the download status</li>
042: * <li>fileDetails, a XLabel showing details of the selected file</li>
043: * <li>targetEdit, a XEdit field showing the output folder</li>
044: * <li>startDownload, a XButton used to start the download</li>
045: * <li>pauseDownload, a XButton used to pause the download</li>
046: * <li>stopDownload, a XButton used to stop the download</li>
047: * <ul>
048: * <p>The resource loader expects a list of files to be downloaded to be set as
049: * children of the model node passed to startDownload. Each child node should
050: * contain the attributes: file name, file date, file size in the positions
051: * specified by the contsnts in XResourceLoader.
052: * </p>
053: * <p>by default the class expect the list of files to be stored in the
054: * resourceList node of the model, but this can be changed via the
055: * <code>setResourceList</code> method
056: * </p>
057: *
058: * <p> Copyright (c) Xoetrope Ltd., 2001-2007, This software is licensed under
059: * the GNU Public License (GPL), please see license.txt for more details. If
060: * you make commercial use of this software you must purchase a commercial
061: * license from Xoetrope.</p>
062: * @author luano
063: */
064:public class XResourceLoaderProgressPanel extends XPanel implements XResourceLoaderStatus, ActionListener, ListSelectionListener
065:{
066: @Find
067: private XList fileList;
068:
069: @Find
070: private XProgressBar downloadProgress;
071:
072: @Find
073: private XLabel downloadStatus, fileDetails;
074:
075: @Find
076: private XEdit stagingEdit;
077:
078: @Find
079: private XButton startDownload, pauseDownload, stopDownload;
080:
081: @Find
082: private XButton browseStaging;
083:
084: @Find
085: private XCheckbox alwaysDownload;
086:
087: private XBaseModel resourceList;
088: private XResourceLoader resourceLoader;
089: private String serverUrl;
090:
091: private XProject currentProject;
092: private Preferences preferences;
093:
094: private File targetFolder;
095:
096: public XResourceLoaderProgressPanel()
097: {
098: }
099:
100: public void setup( XProject project, XPage parentPage, String url, File folder, Preferences prefs )
101: {
102: currentProject = project;
103: targetFolder = folder;
104:
105: XPageAnnotationProcessor annotationProcessor = new XPageAnnotationProcessor();
106: annotationProcessor.setupComponents( parentPage, this );
107:
108: stagingEdit.setEnabled( false );
109: resourceList = (XBaseModel)project.getModel().get( "resourceList" );
110:
111: if ( startDownload != null )
112: startDownload.addActionListener( this );
113: if ( pauseDownload != null )
114: pauseDownload.addActionListener( this );
115: if ( stopDownload != null )
116: stopDownload.addActionListener( this );
117: if ( browseStaging != null )
118: browseStaging.addActionListener( this );
119:
120: resourceLoader = XResourceLoader.getInstance( project );
121: resourceLoader.setServerURL( serverUrl = url );
122:
123: if ( fileList != null )
124: fileList.addListSelectionListener( this );
125:
126: XStyle style = currentProject.getStyleManager().getStyle( "list/alt" );
127: XResourceLoaderListCellRenderer renderer = new XResourceLoaderListCellRenderer( resourceList );
128: renderer.setAltUnselectedColors( style.getStyleAsColor( XStyle.COLOR_FORE ), style.getStyleAsColor( XStyle.COLOR_BACK ));
129: if ( fileList != null )
130: fileList.setCellRenderer( renderer );
131:
132: repaint();
133:
134: preferences = prefs;
135:
136: String stagingArea = preferences.get( "stagingArea", folder.getPath() );
137: if ( stagingEdit != null )
138: stagingEdit.setText( stagingArea );
139:
140: resourceLoader.setTargetFolder( folder );
141: }
142:
143: /**
144: * A new document has been selected, so update the display
145: */
146: public void fileSelected()
147: {
148: if (( fileDetails != null ) && ( downloadStatus != null )) {
149: int idx = fileList.getSelectedIndex();
150: if ( idx >= 0 ) {
151: XBaseModel documentModel = ((XBaseModel)resourceList.get( idx ));
152: if ( documentModel != null ) {
153: String fileName = (String)documentModel.getAttribValue( XResourceLoader.DOWNLOAD_FILENAME );
154: fileDetails.setText( fileName );
155: }
156: }
157: }
158: }
159:
160: /**
161: * Find the staging area
162: */
163: public void browseStaging()
164: {
165: if ( stagingEdit != null ) {
166: String theFolder = stagingEdit.getText();
167: JFileChooser chooser = new JFileChooser( );
168: chooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
169: if ( chooser.showOpenDialog( this ) == JFileChooser.APPROVE_OPTION ) {
170: targetFolder = chooser.getSelectedFile();
171: stagingEdit.setText( theFolder = targetFolder.getAbsolutePath() );
172: preferences.put( "targetFolder", theFolder );
173: resourceLoader.setTargetFolder( targetFolder );
174: }
175: }
176: }
177:
178: public void startDownload()
179: {
180: XTranslator translator = currentProject.getTranslator();
181: if ( targetFolder.exists()) {
182: boolean hasFiles = XuiUtilities.hasFiles( targetFolder );
183: boolean alwaysDownloadStatus = alwaysDownload.isSelected();
184: if ( !alwaysDownloadStatus && hasFiles ) {
185: int rc = JOptionPane.showConfirmDialog( this , translator.translate( "DOWNLOAD_FOLDER_NOT_EMPTY" ),
186: "Non empty folder",
187: JOptionPane.YES_NO_OPTION,
188: JOptionPane.QUESTION_MESSAGE );
189: if ( rc == JOptionPane.NO_OPTION )
190: return;
191: }
192:
193: resourceLoader.startDownload( getResourceList(), serverUrl, targetFolder, this );
194: if ( startDownload != null )
195: startDownload.setEnabled( false );
196:
197: if ( pauseDownload != null )
198: pauseDownload.setEnabled( true );
199:
200: if ( stopDownload != null )
201: stopDownload.setEnabled( true );
202: }
203: else
204: JOptionPane.showMessageDialog( this , translator.translate( "DOWNLOAD_CHOOSE_VALID_FOLDER" ), translator.translate( "DOWNLOAD_INVALID_FOLDER" ), JOptionPane.ERROR_MESSAGE );
205: }
206:
207: public void stopDownload()
208: {
209: resourceLoader.stopDownload();
210: }
211:
212: public void pauseDownload()
213: {
214: //worker.interrupt();
215: resourceLoader.pauseDownload();
216: }
217:
218: public void updateFileProgress()
219: {
220: if ( fileList != null )
221: fileList.repaint( 500 );
222: }
223:
224: public void setProgress( final int percent )
225: {
226: if ( downloadProgress != null )
227: downloadProgress.setProgress( percent );
228:
229: if ( percent >= 100 ) {
230: if ( startDownload != null )
231: startDownload.setEnabled( true );
232:
233: if ( pauseDownload != null )
234: pauseDownload.setEnabled( false );
235:
236: if ( stopDownload != null )
237: stopDownload.setEnabled( false );
238:
239: setProgressMessage( "Download complete" );
240: clearStatusMsg();
241: }
242:
243: if ( fileList != null )
244: fileList.repaint( 500 );
245: }
246:
247: public void setProgressMessage( final String msg )
248: {
249: if ( downloadStatus != null ) {
250: SwingUtilities.invokeLater( new Runnable() {
251: public void run()
252: {
253: downloadStatus.setText( msg );
254: }
255: });
256: }
257: }
258:
259: public void clearStatusMsg()
260: {
261: SwingWorker worker = new SwingWorker()
262: {
263: public Object construct()
264: {
265: try {
266: Thread.currentThread().sleep( 30000 );
267: }
268: catch ( Exception e )
269: {
270: }
271: return null;
272: }
273:
274: public void finished()
275: {
276: setProgressMessage( "" );
277: }
278: };
279: worker.start();
280: }
281:
282: /**
283: * Respond to one of the button presses
284: */
285: public void actionPerformed( ActionEvent ae )
286: {
287: Object src = ae.getSource();
288: if ( src == startDownload )
289: startDownload();
290: else if ( src == pauseDownload )
291: pauseDownload();
292: else if ( src == stopDownload )
293: stopDownload();
294: else if ( src == browseStaging )
295: browseStaging();
296: }
297:
298: /**
299: * Called whenever the value of the selection changes.
300: * @param e the event that characterizes the change.
301: */
302: public void valueChanged( ListSelectionEvent e )
303: {
304: if ( e.getSource() == fileList )
305: fileSelected();
306: }
307:
308: public XBaseModel getResourceList()
309: {
310: return resourceList;
311: }
312:
313: public void setResourceList( XBaseModel node )
314: {
315: resourceList = node;
316: }
317:}
|