View Javadoc

1   package org.robsite.extension.rss;
2   
3   import java.awt.Component;
4   import java.awt.Dimension;
5   import java.awt.GridBagConstraints;
6   import java.awt.GridBagLayout;
7   import java.awt.Insets;
8   
9   import java.beans.PropertyChangeEvent;
10  import java.beans.PropertyVetoException;
11  import java.beans.VetoableChangeListener;
12  
13  import java.io.IOException;
14  
15  import java.net.MalformedURLException;
16  import java.net.SocketTimeoutException;
17  
18  import java.text.MessageFormat;
19  
20  import java.util.ResourceBundle;
21  
22  import javax.swing.Icon;
23  import javax.swing.ImageIcon;
24  import javax.swing.JLabel;
25  import javax.swing.JPanel;
26  import javax.swing.JTextField;
27  import javax.swing.event.DocumentEvent;
28  import javax.swing.event.DocumentListener;
29  
30  import javax.xml.parsers.ParserConfigurationException;
31  
32  import oracle.bali.ewt.dialog.JEWTDialog;
33  import oracle.bali.ewt.text.MultiLineLabel;
34  import oracle.bali.ewt.text.WordWrapper;
35  
36  import oracle.ide.Ide;
37  
38  import oracle.javatools.dialogs.ExceptionDialog;
39  import oracle.javatools.dialogs.MessageDialog;
40  
41  import org.robsite.extension.rss.model.SimpleRSSParser;
42  
43  import org.xml.sax.SAXException;
44  
45  /***
46   * The panel / dialog that is used to add a new RSS feed.
47   * 
48   * @author brian_duff@sourceforge.net
49   * @version $Revision: 1.1.1.1 $
50   */
51  public final class NewChannelPanel extends JPanel 
52  {
53    private final GridBagLayout _layout = new GridBagLayout();
54    private final JLabel _urlLabel = new JLabel();
55    private final MultiLineLabel _hint = new MultiLineLabel();
56    private final JTextField _tfURL = new JTextField();
57    private final Icon _xmlIcon = new ImageIcon( 
58      NewChannelPanel.class.getResource( "xml.gif" ) );
59    private final JPanel _panel = new JPanel();
60    private final ResHelper _res = new ResHelper( "NewChannelPanel." );
61  
62    public NewChannelPanel()
63    {
64      jbInit();
65    }
66    
67    /***
68     * Get the URL the user has entered in the dialog.
69     * 
70     * @return the url entered by the user in the dialog.
71     */
72    public String getURL()
73    {
74      return _tfURL.getText();
75    }
76    
77    /***
78     * Set the URL in the dialog.
79     * 
80     * @param url the URL to display in the dialog.
81     */
82    private void setURL( String url )
83    {
84      _tfURL.setText( url );
85    }
86    
87    private void jbInit()
88    {
89      this.setLayout(_layout);
90      _res.resLabel( "ChannelURL", _urlLabel, _tfURL );
91      _urlLabel.setIcon(_xmlIcon);
92      _hint.setTextWrapper( WordWrapper.getTextWrapper() );
93      _hint.setPreferredColumns( 60 );
94      _hint.setText( _res.getRes( "Hint" ) );
95      this.add(_urlLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 12), 0, 0));
96      this.add(_hint, new GridBagConstraints(0, 0, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 15, 0), 0, 0));
97      this.add(_tfURL, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
98    }
99    
100   public boolean runCreateDialog( Component parent )
101   {
102     return runDialog( _res.getRes( "CreateDialogTitle" ), parent );
103   }
104   
105   public boolean runEditDialog( Component parent, String url )
106   {
107     setURL( url );
108     // Prepopulated text fields have a stupid preferred width based on the
109     // amount of text they contain, making dialogs huge. Just one of many
110     // irritating workarounds everyone using Swing has to do all the time ;)
111     _tfURL.setPreferredSize(
112       new Dimension( 0, _tfURL.getPreferredSize().height )
113     );
114     return runDialog( _res.getRes( "EditDialogTitle" ), parent );
115   }
116   
117   private boolean runDialog( String title, Component parent )
118   { 
119     final JEWTDialog jd = JEWTDialog.createDialog( parent, title, 
120       JEWTDialog.BUTTON_OK + JEWTDialog.BUTTON_CANCEL );
121       
122     jd.setContent( this );
123 
124     // Keep the OK button disabled until a URL has been provided.
125     jd.setOKButtonEnabled( _tfURL.getText().trim().length() > 0 );
126     _tfURL.getDocument().addDocumentListener( new DocumentListener() {
127       private void update()
128       {
129         jd.setOKButtonEnabled( _tfURL.getText().trim().length() > 0 );
130       }
131     
132       public void insertUpdate( DocumentEvent de )
133       {
134         update();
135       }
136       
137       public void removeUpdate( DocumentEvent de )
138       {
139         update();        
140       }
141       
142       public void changedUpdate( DocumentEvent de )
143       {
144         update();        
145       }
146     });
147     
148     // This is how to do validation on the contents of a dialog
149     // before the dialog is dismissed. 
150     jd.addVetoableChangeListener( new VetoableChangeListener() {
151     
152       public void vetoableChange( PropertyChangeEvent event )
153         throws PropertyVetoException
154       {
155         if ( JEWTDialog.isDialogClosingEvent( event ) )
156         {
157           if ( !checkURL() )
158           {
159             _tfURL.requestFocus();
160             // Throwing a PropertyVetoException prevents the dialog from 
161             // closing.
162             throw new PropertyVetoException( "", event );
163           }
164           // Otherwise, the dialog is closed at this point.
165         }
166       }
167     });
168     
169     
170     return jd.runDialog();
171   }
172   
173   private boolean checkURL()
174   {
175     try
176     {
177       HTTPUtil.setHTTPTimeout( 
178         NewsFeedExtension.get().getPreferences().getHTTPTimeout() );
179       
180       SimpleRSSParser.parse( _tfURL.getText().trim() );
181       
182       return true;
183     }
184     catch ( SocketTimeoutException timeout )
185     {
186       timeout.printStackTrace();
187       return MessageDialog.confirm( this, 
188         _res.getRes( "NoConnect", Ide.getProgramName() ),
189         _res.getRes( "NoConnectTitle" ),
190         null );
191     }
192     catch ( MalformedURLException mfe )
193     {
194       mfe.printStackTrace();
195     
196       
197       MessageDialog.error( this, 
198         _res.getRes( "BadURL", mfe.getLocalizedMessage() ), 
199         _res.getRes( "BadURLTitle" ), null );
200       return false;
201     
202     }
203     catch ( ParserConfigurationException parserError )
204     {
205       showExceptionDialog( parserError );
206       return false;
207     }    
208     catch ( SAXException saxException )
209     {
210       saxException.printStackTrace();
211       return MessageDialog.confirm( this, 
212         _res.getRes( "RSSParseError", Ide.getProgramName() ),
213         _res.getRes( "RSSParseErrorTitle" ),
214         null );  
215     }
216     catch ( IOException e )
217     {
218       e.printStackTrace();
219       return MessageDialog.confirm( this, 
220         _res.getRes( "IOError", Ide.getProgramName() ),
221         _res.getRes( "IOErrorTitle" ),
222         null );    
223     }
224     finally
225     {
226       HTTPUtil.resetHTTPTimeout(); 
227     }
228   }
229   
230   private void showExceptionDialog( Exception e )
231   {
232     ExceptionDialog.showExceptionDialog( this, e );
233   }
234 
235 }