KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SnowMailClient > view > folders > FoldersView


1 package SnowMailClient.view.folders;
2
3 import SnowMailClient.SnowMailClientApp;
4 import SnowMailClient.model.folders.*;
5 import SnowMailClient.model.*;
6 import SnowMailClient.view.*;
7 import SnowMailClient.Language.Language;
8 import snow.utils.gui.*;
9 import snow.utils.storage.*;
10
11 import java.awt.*;
12 import java.awt.dnd.*;
13 import java.awt.datatransfer.*;
14 import java.awt.event.*;
15
16 import javax.swing.*;
17 import javax.swing.border.*;
18 import javax.swing.tree.*;
19 import javax.swing.event.*;
20 import java.io.*;
21
22 /** The main folder view with Drag & Drop gesture implementation
23    to drag any mails from a folder to another mail folder
24 */

25 public class FoldersView extends SnowBackgroundPanel
26 {
27   private final JTree tree;
28   public int fontSize = UIManager.getFont("Label.font").getSize();
29   // used for drag&drop
30
private final SnowMailClientApp mailApp;
31   final private StorageTreeModel model;
32   FolderViewTreeRenderer folderViewTreeRenderer;
33   // set from folderview constructor *later*
34
FolderView folderView;
35
36   final private JProgressBar loadProgress = new JProgressBar();
37
38
39   public FoldersView(StorageTreeModel model, SnowMailClientApp mailApp)
40   {
41     super(new BorderLayout(0,0));
42     this.mailApp = mailApp;
43     this.model = model;
44
45     tree = new JTree(model);
46     JScrollPane jsp = new JScrollPane(tree);
47     add(jsp, BorderLayout.CENTER);
48     jsp.getViewport().setOpaque(false);
49     jsp.setOpaque(false);
50     tree.setOpaque(false);
51
52
53     tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
54     tree.setCellRenderer(folderViewTreeRenderer = new FolderViewTreeRenderer());
55
56
57     add(loadProgress, BorderLayout.SOUTH);
58     loadProgress.setVisible(false);
59
60     tree.setDropTarget(new TreeDropTarget());
61
62
63     tree.addMouseListener(new MouseAdapter()
64     {
65       @Override JavaDoc public void mousePressed(MouseEvent e)
66       {
67          if(e.isPopupTrigger()) showTreePopup(e); //linux
68
}
69       @Override JavaDoc public void mouseReleased(MouseEvent e)
70       {
71          if(e.isPopupTrigger()) showTreePopup(e); //windows
72
}
73     });
74
75
76   } // Constructor
77

78
79
80
81   /** listen to folder selection
82       (this is called from folderView's constructor)
83   */

84   public void installFolderSelectionListener(FolderView folderView)
85   {
86     this.folderView = folderView;
87     tree.addTreeSelectionListener(new TreeSelectionListener()
88     {
89        public void valueChanged(TreeSelectionEvent e)
90        {
91           if(tree.getSelectionCount()>0)
92           {
93              TreePath path = e.getPath();
94              FolderTreeNode folderNode = (FolderTreeNode) path.getLastPathComponent();
95              setSelectedMailFolder(folderNode);
96           }
97        }
98     });
99
100     // set the initial selected folder
101
String JavaDoc[] ps = SnowMailClientApp.getInstance().getProperties().getArrayProperty("FoldersView_selection", new String JavaDoc[]{});
102     if(ps.length>0)
103     {
104       final FolderTreeNode node = model.getNodeForPath(ps);
105       EventQueue.invokeLater(new Runnable JavaDoc(){ public void run()
106       {
107         tree.setSelectionPath(new TreePath(node.getPath()));
108       }});
109     }
110   }
111
112   /** to be called in the EDT !
113       is called from the search results...
114       @param selectedMess can be null. If not (when called from searchTree...)
115        it select this message
116   */

117   public void setSelectedFolder(final FolderTreeNode node, final MailMessage selectedMess)
118   {
119     messageToSelect = selectedMess;
120     // this produces an event that will cause the call of
121
// setSelectedMailFolder below later ...
122
// but only if the selection has changed !!
123
tree.setSelectionPath(new TreePath(node.getPath()));
124
125     // to force message selection when the folder is already open...
126
// ###
127
setSelectedMailFolder(node);
128   }
129
130   private MailMessage messageToSelect = null;
131
132
133   /** this install a new selected mail folder, showing a progress for long process time
134       it leaves the EDT and is synchronized with this class.
135   */

136   private void setSelectedMailFolder(final FolderTreeNode folderNode)
137   {
138     Thread JavaDoc t = new Thread JavaDoc()
139     {
140        public void run()
141        {
142           synchronized(FoldersView.this)
143           {
144              // close the old folder ?
145

146
147              try
148              {
149                 if(!folderNode.isMailFolderOpened())
150                 {
151                   EventQueue.invokeLater(new Runnable JavaDoc() { public void run()
152                   {
153                     loadProgress.setVisible(true);
154                     loadProgress.setStringPainted(true);
155                     loadProgress.setString(Language.translate("Opening %",folderNode.getFolderFile().getName()));
156                     loadProgress.setIndeterminate(true);
157                   }});
158                 }
159
160                 final MailFolder mf = folderNode.getMailFolder();
161
162                 EventQueue.invokeLater(new Runnable JavaDoc() { public void run()
163                 {
164                   folderView.setMailFolder(folderNode, mf);
165                   if(messageToSelect!=null)
166                   {
167
168                     mf.setSelectedMessage( messageToSelect );
169                     mf.fireTableModelHasChanged();
170                   }
171                 }});
172              }
173              catch(Exception JavaDoc ex)
174              {
175                 ex.printStackTrace();
176                 JOptionPane.showMessageDialog(tree, ""+ex.getMessage(),
177                      Language.translate("Cannot open folder %",folderNode.getFolderName()),
178                      JOptionPane.ERROR_MESSAGE);
179              }
180              finally
181              {
182                 EventQueue.invokeLater(new Runnable JavaDoc() { public void run()
183                 {
184                   loadProgress.setIndeterminate(false);
185                   loadProgress.setVisible(false);
186                 }});
187              }
188           }
189        }
190     };
191     t.start();
192
193   }
194
195
196   public void terminateViewAndSaveSelection(AppProperties props)
197   {
198      // save the selected folder
199
TreePath path = tree.getSelectionPath();
200      if(path!=null)
201      {
202         FolderTreeNode node = (FolderTreeNode) path.getLastPathComponent();
203         String JavaDoc[] ps = model.getPathForNode(node);
204         props.setArrayProperty("FoldersView_selection", ps);
205      }
206      else
207      {
208         props.setArrayProperty("FoldersView_selection", new String JavaDoc[]{});
209      }
210   }
211
212
213   private void showTreePopup(MouseEvent e)
214   {
215     JPopupMenu popup = new JPopupMenu("Folders popup");
216     TreePath path = tree.getPathForLocation(e.getX(),e.getY());
217     if(path!=null)
218     {
219       FolderTreeNode node = (FolderTreeNode) path.getLastPathComponent();
220       popup.add(new AddNewFolderAction(node, tree));
221       try
222       {
223         if(node.getMailFolder().getRowCount()>0)
224         {
225            popup.addSeparator();
226            popup.add(new EmptyFolderAction(node, tree, model.getDeletedFolder()));
227         }
228       }
229       catch(Exception JavaDoc ee)
230       {
231         ee.printStackTrace();
232       }
233
234       if(!node.isSystemFolder() && !node.isRoot())
235       {
236          popup.addSeparator();
237          popup.add(new RenameSelectedFolder(node, tree));
238          popup.add(new RemoveSelectedFolder(node, tree));
239       }
240
241       // search in folder
242
popup.addSeparator();
243       popup.add(new SearchInSelectedFolder(node, tree));
244
245       popup.show(tree, e.getX(), e.getY());
246     }
247   }
248
249   // used to locate drop
250
int dropX, dropY;
251   boolean dropLocationValid = false;
252
253   private void mailMessagesWereJustDroppenOnTree(int actionCopyOrMove)
254   {
255      folderView.isDragGestureStartedFromTable = false;
256
257      TreePath path = tree.getClosestPathForLocation(dropX, dropY);
258      if(path!=null && this.dropLocationValid)
259      {
260         FolderTreeNode destinationNode = (FolderTreeNode) path.getLastPathComponent();
261         try
262         {
263           MailFolder destinationFolder = destinationNode.getMailFolder();
264
265           FolderView folder = mailApp.getFolderView();
266           if(folder!=null)
267           {
268              MailMessage[] messs = folder.getSelectedMessages();
269              for(int i=0; i<messs.length; i++)
270              {
271                 destinationFolder.addMessage(messs[i]);
272                 messs[i].selectedInView = false;
273                 // on success and in move case, not copy
274
if(actionCopyOrMove==DnDConstants.ACTION_MOVE)
275                 {
276                   folder.getMailFolder().removeMessage(messs[i]);
277                 }
278              }
279           }
280         }
281         catch(Exception JavaDoc e)
282         {
283           JOptionPane.showMessageDialog(this,
284               ""+e.getMessage(),
285               Language.translate("Cannot drop mail"), JOptionPane.ERROR_MESSAGE);
286           //e.printStackTrace();
287
}
288      }
289   }
290
291   /** this is the drop target for receiving messages dragged
292       at destination of the tree and initiated from the folderView.
293   */

294   class TreeDropTarget extends DropTarget
295   {
296       int oldClosestRow = -1;
297
298       public TreeDropTarget()
299       {
300         super();
301         setDefaultActions(DnDConstants.ACTION_COPY_OR_MOVE);
302       }
303
304       public void dropActionChanged(DropTargetDragEvent dtde)
305       {
306          // remove preselection highlight
307
folderViewTreeRenderer.setDropTarget(-1, false);
308          oldClosestRow = -1;
309          tree.repaint();
310       }
311
312       public void dragExit(DropTargetEvent dte)
313       {
314          // remove preselection highlight
315
folderViewTreeRenderer.setDropTarget(-1, false);
316          oldClosestRow = -1;
317          tree.repaint();
318
319          folderView.isDragGestureStartedFromTable = false;
320       }
321
322
323       /** show the target with a red box around
324       */

325       public void dragOver(DropTargetDragEvent dtde)
326       {
327         Point pt = dtde.getLocation();
328         dropX = (int) pt.getX();
329         dropY = (int) pt.getY();
330
331         int closestRow = tree.getClosestRowForLocation(dropX, dropY);
332
333         if(closestRow>=0)
334         {
335            FolderTreeNode node = (FolderTreeNode) tree.getClosestPathForLocation(dropX, dropY).getLastPathComponent();
336            // now, we just avoid dragging in root
337
if(node.getParentNode()==null)
338            {
339               dropLocationValid = false;
340            }
341            else
342            {
343               dropLocationValid = true;
344            }
345
346            //NOT GOOD: this would load the folder !!! if(folderView.getMailFolder()==node.getMailFolder())
347
// also avoid droping on the source itself
348
if(node.equals(folderView.getFolderNode()))
349            {
350              dropLocationValid = false;
351            }
352         }
353
354         folderViewTreeRenderer.setDropTarget(closestRow, dropLocationValid);
355
356         if(oldClosestRow!=closestRow)
357         {
358           tree.repaint();
359           oldClosestRow = closestRow;
360         }
361
362       }
363
364       public void drop(DropTargetDropEvent dtde)
365       {
366         Transferable transferable = dtde.getTransferable();
367         Point pt = dtde.getLocation();
368         dropX = (int) pt.getX();
369         dropY = (int) pt.getY();
370
371
372         DataFlavor[] flavors = transferable.getTransferDataFlavors();
373         for(int i=0; i<flavors.length; i++)
374         {
375           DataFlavor flavour = flavors[i];
376
377           if(flavour.isMimeTypeEqual("application/x-java-jvm-local-objectref; class=java.lang.String"))
378           {
379              if(dtde.getDropAction()==DnDConstants.ACTION_COPY
380              || dtde.getDropAction()==DnDConstants.ACTION_MOVE)
381              {
382                 dtde.acceptDrop(dtde.getDropAction());
383                 // only after accept, we can get the transfer data
384
try
385                 {
386                     if(folderView.isDragGestureStartedFromTable)
387                     {
388                        mailMessagesWereJustDroppenOnTree(dtde.getDropAction());
389                     }
390                 }
391                 catch(Exception JavaDoc ee)
392                 { //??
393
ee.printStackTrace();
394                 }
395              }
396           }
397         } // loop on flavors
398

399         // suppress preselection
400
folderViewTreeRenderer.setDropTarget(-1, false);
401         oldClosestRow = -1;
402         tree.repaint();
403      }
404
405   } // TreeDropTarget
406

407 } // FoldersView
Popular Tags