Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/fm/gui/fmCreateChannelDialog.java


1   /****************************************************************************
2    * Copyright (c) 2003 Andrew Duka | aduka@users.sourceforge.net
3    * All right reserved.
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2.1 of the License, or (at your option) any later version.
9    *
10   ****************************************************************************/
11  package com.fm.gui;
12  
13  import javax.swing.*;
14  import javax.swing.event.TreeSelectionListener;
15  import javax.swing.event.TreeSelectionEvent;
16  import javax.swing.tree.TreeModel;
17  import javax.swing.tree.DefaultTreeModel;
18  import javax.swing.tree.TreePath;
19  import javax.swing.tree.DefaultMutableTreeNode;
20  
21  import com.fm.rss.rssChannelCategory;
22  import com.fm.rss.rssChannel;
23  import com.fm.gui.action.createCategoryAction;
24  import com.fm.update.retrieveThread;
25  import com.fm.update.fmEvent;
26  
27  import java.text.DateFormat;
28  import java.util.*;
29  import java.awt.*;
30  import java.awt.event.*;
31  import java.net.URL;
32  import java.net.MalformedURLException;
33  
34  /**
35   * Add/Update category dialog.
36   *
37   * <p>This dialog supposed to handle add/update category operations.</p>
38   *
39   * <p>Default action listener simply disposes dialog then Save or Discard
40   * button is pressed</p>
41   *
42   */
43  public class fmCreateChannelDialog extends JDialog implements ActionListener {
44  
45      private fmCategoryTree  categoryTree;
46    private JTextField      channelTitle;
47      private JTextField      channelURL;
48  
49      /** result channel                  */
50      private rssChannel      resultChannel;
51  
52      /** Parent frame            */
53      private JFrame          parentFrame;
54      /** Iterates operation step */
55      private JButton         nextButton;
56      /** Dicreases operation step */
57      private JButton         prevButton;
58      /** Panel with add steps controls */
59      private JPanel          stepsPane;
60      /** Label for huge hints */
61      private JLabel          titlePaneLabel;
62  
63  
64      /** Checked if user wish autoremove old news */
65      private JCheckBox useAutoremove;
66      /** Number of days we keep the news          */
67      private JComboBox daysComboBox;
68      /** Checked if autoupdate will be used       */
69      private JCheckBox useAutocheck;
70      /** Number of days we keep the news          */
71      private JTextField autoUpdateMinutes;
72  
73      private int createStep;
74      /** Channel retriever */
75      private retrieveThread retriever;
76  
77  
78      /**
79       * Default constructor
80       */
81      public fmCreateChannelDialog(JFrame parent, TreeModel m)
82      {
83          super(parent);
84          parentFrame = parent;
85  
86          // DEFAULT WINDOW ADAPTER
87          addWindowListener(new WindowAdapter() {
88              public void windowClosing(WindowEvent e)
89              {
90                  if (retriever != null)
91                  {
92                      stopRetrieveProcess();
93                  }
94                  dispose();
95              }
96          });
97  
98          resultChannel = new rssChannel();
99          createStep = 0;
100         retriever = null;
101 
102 
103         setTitle(fmUITheme.getString("dialog.create_channel.step" +
104                                             createStep + ".title"));
105 
106         JPanel titlePane = new JPanel(new FlowLayout(FlowLayout.LEFT));
107         titlePane.setBackground(fmUITheme.WHITE_COLOR);
108         titlePane.setPreferredSize(new Dimension(400,40));
109 
110         titlePaneLabel = new JLabel(fmUITheme.getString("dialog.create_channel.step0" +
111                                                                              ".secondary_title"));
112         titlePaneLabel.setFont(new Font("Verdana",Font.BOLD,15));
113         titlePane.add(titlePaneLabel);
114 
115         ///////////////////////////////////////////////////
116         // ESCAPE KEY LISTENER
117         KeyListener escapeListener = new KeyAdapter() {
118             public void keyPressed(KeyEvent e) {
119                 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
120                     dispose();
121                 }
122             }
123         };
124 
125         // Multi step panel
126         stepsPane = new JPanel(new CardLayout());
127         stepsPane.setBorder(fmUITheme.FM_BUTTON_BORDER);
128 
129         //Common dimension for edit bocxes
130         Dimension editBoxDim = new Dimension(350,25);
131 
132         // STEP 1 PANEL
133         JPanel step1Pane = new JPanel();
134         step1Pane.setLayout(new BoxLayout(step1Pane, BoxLayout.Y_AXIS));
135         JLabel label = new JLabel(fmUITheme.getString("label.feed_source"));
136         label.setAlignmentX(Component.LEFT_ALIGNMENT);
137 
138         channelURL = new JTextField();
139         channelURL.setAlignmentX(LEFT_ALIGNMENT);
140         channelURL.setPreferredSize(editBoxDim);
141         channelURL.setMaximumSize(editBoxDim);
142         channelURL.setBorder(fmUITheme.TEXT_FIELD_BORDER);
143         channelURL.addKeyListener(escapeListener);
144 
145 
146 
147         step1Pane.add(label);
148         step1Pane.add(Box.createRigidArea(new Dimension(0,3)));
149 
150         step1Pane.add(channelURL);
151         step1Pane.add(Box.createRigidArea(new Dimension(0,10)));
152 
153 
154 
155         label = new JLabel(fmUITheme.getString("dialog.create_channel.step0" +
156                                                             ".help"));
157         label.setAlignmentX(LEFT_ALIGNMENT);
158 
159         step1Pane.add(label);
160         // STEP 1 PANEL END
161 
162 
163         // STEP 2 PANEL
164         JPanel step2Pane = new JPanel();
165         step2Pane.setLayout(new BoxLayout(step2Pane, BoxLayout.Y_AXIS));
166 
167         label = new JLabel(fmUITheme.getString("label.title"));
168         label.setAlignmentX(LEFT_ALIGNMENT);
169 
170         channelTitle = new JTextField();
171         channelTitle.setAlignmentX(Component.LEFT_ALIGNMENT);
172         channelTitle.setPreferredSize(editBoxDim);
173         channelTitle.setMaximumSize(editBoxDim);
174         channelTitle.setBorder(fmUITheme.TEXT_FIELD_BORDER);
175         channelTitle.addKeyListener(escapeListener);
176 
177         step2Pane.add(label);
178         step2Pane.add(Box.createRigidArea(new Dimension(0,3)));
179 
180         step2Pane.add(channelTitle);
181         step2Pane.add(Box.createRigidArea(new Dimension(0,10)));
182 
183         label = new JLabel(fmUITheme.getString("dialog.create_channel.step1" +
184                                                             ".help"));
185         label.setAlignmentX(LEFT_ALIGNMENT);
186 
187         step2Pane.add(label);
188         // STEP 2 PANEL END
189 
190 
191         // STEP3
192         JPanel step3Pane = new JPanel();
193         step3Pane.setLayout(new BoxLayout(step3Pane, BoxLayout.Y_AXIS));
194         /////////////////////////////////////////////
195         // AUTOCHECK
196         JPanel autoCheckPanel  = new JPanel();
197         autoCheckPanel.setLayout(new BoxLayout(autoCheckPanel,BoxLayout.X_AXIS));
198         autoCheckPanel.setBorder(BorderFactory.createTitledBorder(fmUITheme.getString("label.autoupdate")));
199 
200         autoUpdateMinutes = new JTextField(3);
201         autoUpdateMinutes.setText("60");
202         autoUpdateMinutes.setEditable(false);
203         autoUpdateMinutes.setMaximumSize(autoUpdateMinutes.getPreferredSize());
204         useAutocheck =  new JCheckBox(fmUITheme.getString("box.auto_check_enable.label"),
205                                                       false);
206         useAutocheck.setToolTipText(fmUITheme.getString("box.auto_check_enable.tooltip"));
207         useAutocheck.addItemListener(new ItemListener() {
208             public void itemStateChanged(ItemEvent e)
209             {
210                 autoUpdateMinutes.setEditable(!autoUpdateMinutes.isEditable());
211             }
212         });
213 
214 
215         autoCheckPanel.add(useAutocheck);
216         autoCheckPanel.add(autoUpdateMinutes);
217         autoCheckPanel.add(new JLabel(" " + fmUITheme.getString("label.autoupdate.minutes")), BorderLayout.EAST);
218         autoCheckPanel.add(Box.createHorizontalGlue());
219         autoCheckPanel.add(Box.createVerticalGlue());
220 
221 
222 
223 
224         ////////////////////////////////////////////////////////
225         // AUTO REMOVE
226         JPanel storePolicyPanel  = new JPanel();
227         storePolicyPanel.setLayout(new BoxLayout(storePolicyPanel,BoxLayout.X_AXIS));
228         storePolicyPanel.setBorder(BorderFactory.createTitledBorder(fmUITheme.getString("label.storepolicy")));
229 
230         daysComboBox= new JComboBox(new Integer[]{new Integer(1),
231                                                   new Integer(3),
232                                                   new Integer(5),
233                                                   new Integer(7),
234                                                   new Integer(14),
235                                                   new Integer(30),
236                                                   new Integer(60),
237                                                   new Integer(365)});
238         daysComboBox.setEnabled(false);
239         daysComboBox.setMaximumSize(daysComboBox.getPreferredSize());
240 
241         useAutoremove =  new JCheckBox(fmUITheme.getString("label.storepolicy.remove"),
242                                                       false);
243         useAutoremove.setToolTipText(fmUITheme.getString("box.storepolicy.tooltip"));
244         useAutoremove.addItemListener(new ItemListener() {
245             public void itemStateChanged(ItemEvent e)
246             {
247                 daysComboBox.setEnabled(!daysComboBox.isEnabled());
248             }
249         });
250         storePolicyPanel.add(useAutoremove);
251         storePolicyPanel.add(daysComboBox);
252         storePolicyPanel.add(new JLabel(fmUITheme.getString("label.storepolicy.days")));
253         storePolicyPanel.add(Box.createHorizontalGlue());
254         storePolicyPanel.add(Box.createVerticalGlue());
255 
256 
257         step3Pane.add(autoCheckPanel);//, BorderLayout.NORTH);
258         step3Pane.add(Box.createVerticalStrut(15));
259         step3Pane.add(storePolicyPanel);//, BorderLayout.CENTER);
260 
261         ///////////////////////////////////////////////////////////////////////
262         // STEP 4 PANEL
263         JPanel step4Pane = new JPanel();
264         step4Pane.setLayout(new BoxLayout(step4Pane, BoxLayout.Y_AXIS));
265 
266         label = new JLabel(fmUITheme.getString("label.folder"));
267         label.setAlignmentX(LEFT_ALIGNMENT);
268 
269         categoryTree = new fmCategoryTree((DefaultTreeModel)m); // using common data
270         JScrollPane treeScroll = new JScrollPane(categoryTree);
271         categoryTree.addKeyListener(escapeListener);
272         //categoryTree.repaint();
273 
274         treeScroll.setPreferredSize(new Dimension(200,150));
275         treeScroll.setAlignmentX(LEFT_ALIGNMENT);
276 
277         // TREE LISTENER
278         categoryTree.addTreeSelectionListener(new TreeSelectionListener() {
279             public void valueChanged(TreeSelectionEvent e)
280             {
281                 fmTreeNode node = (fmTreeNode)categoryTree.getLastSelectedPathComponent();
282                 if (node != null)
283                     nextButton.setEnabled(true);
284                 else
285                     nextButton.setEnabled(false);
286             }
287         });
288 
289         step4Pane.add(label);
290         step4Pane.add(Box.createRigidArea(new Dimension(0,3)));
291 
292         step4Pane.add(treeScroll);
293         step4Pane.add(Box.createRigidArea(new Dimension(0,8)));
294 
295         label = new JLabel(fmUITheme.getString("dialog.create_channel.step3" +
296                                                             ".help"));
297         step4Pane.add(label);
298 
299         label.setAlignmentX(LEFT_ALIGNMENT);
300         JButton createFolderButton = new JButton(new createCategoryAction(categoryTree));
301         createFolderButton.setAlignmentX(LEFT_ALIGNMENT);
302         step4Pane.add(Box.createRigidArea(new Dimension(0,15)));
303         step4Pane.add(createFolderButton);
304         // STEP 4 PANEL END
305 
306         stepsPane.add(step1Pane, "URL input pane");
307         stepsPane.add(step2Pane, "Channel title");
308         stepsPane.add(step3Pane, "Channel autoupdate");
309         stepsPane.add(step4Pane, "Channel folder");
310 
311 
312         // NAVIGATION PANE
313         GridBagLayout navGridBag = new GridBagLayout();
314         GridBagConstraints c = new GridBagConstraints();
315         JPanel navPane = new JPanel(navGridBag);
316 
317         prevButton = fmUITheme.getButtonInstance("button.prev.label",
318                                                  "button.prev.tooltip",
319                                                   KeyEvent.VK_P);
320         prevButton.addKeyListener(escapeListener);
321 
322         nextButton = fmUITheme.getButtonInstance("button.next.label",
323                                                  "button.next.tooltip",
324                                                   KeyEvent.VK_N);
325         nextButton.addKeyListener(escapeListener);
326 
327         // PREV BUTTON LISTENER
328         prevButton.addActionListener(new ActionListener() {
329             public void actionPerformed(ActionEvent e)
330             {
331                 previousStep();
332             }
333         });
334         // PREV BUTTON SETTINGS
335         c.anchor = GridBagConstraints.SOUTHEAST;
336         c.gridx = 0;
337         c.gridy = 1;
338         c.weightx = 0.15;
339         c.gridwidth = 2;
340         c.insets = new Insets(15,2,6,0);
341         c.ipadx = 15;
342         navGridBag.setConstraints(prevButton, c);
343         navPane.add(prevButton);
344 
345         // NEXT BUTTON LISTENER
346         nextButton.addActionListener(new ActionListener() {
347             public void actionPerformed(ActionEvent e)
348             {
349                 nextStep();
350             }
351         });
352         // NEXT BUTTON SETTINGS
353         c.gridx = GridBagConstraints.RELATIVE;
354         c.weightx = GridBagConstraints.RELATIVE;
355         navGridBag.setConstraints(nextButton, c);
356         navPane.add(nextButton);
357 
358 
359     JButton button = fmUITheme.getButtonInstance("button.cancel.label",
360                                                      "button.cancel.label",
361                                                       KeyEvent.VK_C);
362         c.insets = new Insets(15,8,6,0);
363         c.fill = GridBagConstraints.HORIZONTAL;
364     navGridBag.setConstraints(button, c);
365         button.addKeyListener(escapeListener);
366 
367         // CANCEL ACTION LISTENER
368         button.addActionListener(new ActionListener() {
369             public void actionPerformed(ActionEvent e)
370             {
371                 if (retriever != null)
372                     stopRetrieveProcess();
373                 else
374                     dispose();
375             }
376         });
377     navPane.add(button);
378 
379         // FINAL ADD
380         this.getContentPane().add(titlePane, BorderLayout.NORTH);
381         this.getContentPane().add(stepsPane, BorderLayout.CENTER);
382         this.getContentPane().add(navPane, BorderLayout.SOUTH);
383 
384         // Resizeability
385         setResizable(false);
386 
387 
388     }
389 
390     /**
391      * Default action handler.
392      *
393      * <p>Default action handler simply disposes dialog if one of
394      * the dialog buttons is pressed</p>
395      *
396      * @param e ActionEvent instance
397      */
398     public void actionPerformed(ActionEvent e)
399     {
400         if (e.getActionCommand().equals(fmEvent.RETRIEVE_FINISHED))
401         {
402             // restoring URL value
403             channelURL.setText(resultChannel.getSource());
404             // Enabling buttons
405             prevButton.setEnabled(true);
406             nextButton.setEnabled(true);
407 
408             if (((fmEvent)e).getStatus() == fmEvent.SUCCESS_STATUS)
409             {
410                 ++createStep;
411 
412                 setStepTitles(createStep);
413 
414                 channelTitle.setText(resultChannel.getTitle());
415 
416                 // Changing pane
417                 ((CardLayout)stepsPane.getLayout()).next(stepsPane);
418 
419                 if (resultChannel.getTtl() != -1)
420                 {
421                     useAutocheck.setSelected(true);
422                     autoUpdateMinutes.setText((new Integer(resultChannel.getTtl())).toString());
423                 }
424                 retriever = null; //reseting retriever
425             }
426             else
427             {
428                 JOptionPane.showMessageDialog(this,
429                                               fmUITheme.getString("msg.channel_retrieve_failed"),
430                                               fmUITheme.getString("label.error"),
431                                               JOptionPane.ERROR_MESSAGE);
432                 retriever = null; //reseting retriever
433                 return;
434             }
435         }
436 
437     }
438 
439 
440     /**
441      * Return current category tree view
442      */
443     public fmCategoryTree getCategoryTree()
444     {
445         return categoryTree;
446     }
447 
448     /**
449      * Start thread, which will retrieve the channel specified by given URL.
450      * <p>Note: Blocks all controls except 'Cancel' button</p>
451      *
452      * @param sURL channel source URL
453      */
454     private void retrieveChannel(String sURL)
455     {
456          if (sURL.length() == 0)
457             return;
458 
459         try { URL testURL = new URL(sURL); }
460         catch (MalformedURLException e)
461         {
462             JOptionPane.showMessageDialog(this,
463                                           fmUITheme.getString("msg.invalid_url"),
464                                           fmUITheme.getString("label.error"),
465                                           JOptionPane.ERROR_MESSAGE);
466             return;
467         }
468 
469         // resultChannel object must be created prior, since
470         // create/edit operations both use this function
471         resultChannel.setSource(sURL);
472         retriever = new retrieveThread(this, resultChannel, retrieveThread.RETRIEVE_MODE);
473 
474         nextButton.setEnabled(false);
475         prevButton.setEnabled(false);
476         channelURL.setText(fmUITheme.getString("dialog.open_url.retrieve_message"));
477         retriever.start();
478 
479 
480     }
481 
482     /**
483      * Stop retrieve thread and enable all blocked buttons
484      * <p>Note: Unblocks all controls previously blocked by <see>retriveChannel()</see></p>
485      */
486     private void stopRetrieveProcess()
487     {
488 
489 
490     }
491 
492     /**
493      * Overrides standard implementation
494      *
495      * @param isVisible boolean flag
496      */
497     public void setVisible(boolean isVisible)
498     {
499 
500         if (isVisible)
501         {
502             // Location
503             Point location = new Point(parentFrame.getLocationOnScreen());
504             location.x += 30;
505             location.y += 30;
506             setLocation(location);
507 
508             // Initializing source URL from the clipboard (if any URL there)
509             channelURL.paste();
510             String t_new = channelURL.getText();
511 
512             if (t_new.length() > 1024) // TOO LONG STRING ?
513                 channelURL.setText("");
514             else
515             {
516                 try
517                 {
518                     URL checkURL = new URL(t_new); // Check for validness
519                 }
520                 catch (MalformedURLException e)
521                 {
522                     channelURL.setText("");
523                 }
524             }
525             // END OF URL INIT
526         }
527 
528         super.setVisible(isVisible);
529     }
530 
531     /**
532      * React for Next button
533      */
534     private void nextStep()
535     {
536         if (createStep == 0) // PROCESS RETRIEVEMENT
537         {
538             retrieveChannel(channelURL.getText());
539         }
540         else if ((createStep > 0) && (createStep < 3))
541         {
542             ((CardLayout)stepsPane.getLayout()).next(stepsPane);
543             ++createStep;
544 
545             setStepTitles(createStep);
546 
547             // At the finish
548             if (createStep == 3)
549             {
550                 nextButton.setText(fmUITheme.getString("button.finish.label"));
551                 nextButton.setToolTipText(fmUITheme.getString("button.finish.tooltip"));
552 
553                 // disable finish if none folder has been selected
554                 if (categoryTree.getSelectionPath() == null)
555                     nextButton.setEnabled(false);
556                 else
557                     nextButton.setEnabled(true);
558             }
559         }
560         else // FINAL STEP - CREATION
561         {
562              performChannelCreate();
563         }
564     }
565 
566 
567 
568     /**
569      * React for Back button
570      */
571     private void previousStep()
572     {
573         if (createStep == 3)
574         {
575             // RESTORING NEXT BUTTON
576             nextButton.setText(fmUITheme.getString("button.next.label"));
577             nextButton.setToolTipText(fmUITheme.getString("button.next.tooltip"));
578             nextButton.setEnabled(true);
579         }
580 
581         if (createStep > 0)
582         {
583             ((CardLayout)stepsPane.getLayout()).previous(stepsPane);
584             --createStep;
585 
586             setStepTitles(createStep);
587 
588             // Nothing prior
589             if (createStep == 0)
590                 prevButton.setEnabled(false);
591         }
592     }
593 
594     /**
595      * Set titles accordingly to step number
596      *
597      * @param step
598      */
599     public void setStepTitles(int step)
600     {
601         setTitle(fmUITheme.getString("dialog.create_channel.step" +
602                     step + ".title"));
603         titlePaneLabel.setText(fmUITheme.getString("dialog.create_channel.step" +
604                     step + ".secondary_title"));
605     }
606 
607     /**
608      * Create channel using current data
609      *
610      */
611     private void performChannelCreate()
612     {
613         String chTitleStr = channelTitle.getText();
614 
615         if (chTitleStr.length() == 0)
616         {
617             JOptionPane.showMessageDialog(null,
618                     fmUITheme.getString("msg.short_title_warning"),
619                     fmUITheme.getString("label.error"),
620                     JOptionPane.ERROR_MESSAGE);
621             return;
622         }
623         else
624         {
625             resultChannel.setTitle(chTitleStr);
626         }
627 
628         if (resultChannel.getID() == 0)
629             resultChannel.setID(resultChannel.generateID());
630 
631         ///////////////////////////////////////////////////////
632         // KeepPeriod & Autocheck
633         if (useAutocheck.isSelected())
634         {
635             resultChannel.setTtl(Integer.parseInt(autoUpdateMinutes.getText()));
636         }
637 
638         if (useAutoremove.isSelected())
639         {
640             resultChannel.setKeepPeriod(((Integer) daysComboBox.getSelectedItem()).intValue());
641             resultChannel.filterItems();
642         }
643 
644         // getting tree
645         fmTreeNode parentNode;
646         rssChannelCategory parentCat = null;
647         TreePath nodePath = categoryTree.getSelectionPath();
648 
649         if (nodePath == null)
650         {
651             // none of categories is selected
652             // probably display message here
653             nextButton.setEnabled(false);
654             return;
655         }
656 
657         else
658         {
659             parentNode = (fmTreeNode)nodePath.getLastPathComponent();
660             parentCat  = (rssChannelCategory) parentNode.getUserObject();
661         }
662 
663         int result = categoryTree.insertNode(parentCat, resultChannel, true);
664 
665 
666         if (result == fmCategoryTree.NODE_NOT_FOUND)
667         {
668             JOptionPane.showMessageDialog(null,
669                     fmUITheme.getString("msg.cant_find_folder"),
670                     fmUITheme.getString("label.error"),
671                     JOptionPane.ERROR_MESSAGE);
672         }
673         else if (result == fmCategoryTree.NODE_EXISTS)
674         {
675             JOptionPane.showMessageDialog(null,
676                     fmUITheme.getString("msg.channel_exists_warning"),
677                     fmUITheme.getString("label.error"),
678                     JOptionPane.ERROR_MESSAGE);
679         }
680         else
681         {
682             this.dispose();
683         }
684     }
685 }