KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > pooka > gui > NewMessageFrame


1 package net.suberic.pooka.gui;
2 import net.suberic.pooka.*;
3 import net.suberic.util.gui.*;
4 import net.suberic.util.swing.EntryTextArea;
5 import net.suberic.util.swing.*;
6 import javax.swing.plaf.metal.MetalTheme JavaDoc;
7 import javax.mail.*;
8 import javax.mail.internet.*;
9 import java.awt.*;
10 import java.awt.event.*;
11 import javax.swing.*;
12 import javax.swing.text.TextAction JavaDoc;
13 import java.util.*;
14 import javax.swing.text.JTextComponent JavaDoc;
15 import javax.swing.event.*;
16 import java.io.File JavaDoc;
17
18 /**
19  * A window for entering new messages.
20  */

21 public class NewMessageFrame extends MessageFrame implements NewMessageUI {
22
23   public boolean firstShow = true;
24
25   /**
26    * Creates a NewMessageFrame from the given Message.
27    */

28
29   public NewMessageFrame(NewMessageProxy newMsgProxy) {
30     super(newMsgProxy);
31
32     configureMessageFrame();
33
34     this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
35     this.addWindowListener(new WindowAdapter() {
36         public void windowClosing(WindowEvent we) {
37           handleClose();
38         }
39       });
40
41     FocusTraversalPolicy ftp = new LayoutFocusTraversalPolicy() {
42         public Component JavaDoc getInitialComponent(Window w) {
43           if (w instanceof MessageFrame) {
44             return ((MessageFrame) w).getMessageDisplay();
45           }
46
47           return super.getInitialComponent(w);
48         }
49       };
50     this.setFocusTraversalPolicy(ftp);
51
52   }
53
54   public NewMessageFrame(NewMessageInternalFrame source) {
55     this.setTitle(Pooka.getProperty("Pooka.messageWindow.messageTitle.newMessage", "New Message"));
56     messageDisplay = source.getMessageDisplay();
57     messageDisplay.setMessageUI(this);
58     msg = source.getMessageProxy();
59     toolbar = source.getToolbar();
60     keyBindings = source.getKeyBindings();
61
62     this.getContentPane().add("North", toolbar);
63     this.getContentPane().add("Center", messageDisplay);
64
65     toolbar.setActive(this.getActions());
66
67     configureInterfaceStyle();
68
69     this.setLocation(source.getLocationOnScreen());
70
71     this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
72     this.addWindowListener(new WindowAdapter() {
73         public void windowClosing(WindowEvent we) {
74           handleClose();
75         }
76       });
77
78     FocusTraversalPolicy ftp = new LayoutFocusTraversalPolicy() {
79         public Component JavaDoc getInitialComponent(Window w) {
80           if (w instanceof MessageFrame) {
81             return ((MessageFrame) w).getMessageDisplay();
82           }
83
84           return super.getInitialComponent(w);
85         }
86       };
87     this.setFocusTraversalPolicy(ftp);
88
89   }
90
91   /**
92    * This configures the MessageFrame. This means that here is
93    * where we create the headerPanel and editorPane and add them to the
94    * splitPane.
95    */

96   protected void configureMessageFrame() {
97
98     try {
99       this.createDefaultActions();
100
101       this.setTitle(Pooka.getProperty("Pooka.messageWindow.messageTitle.newMessage", "New Message"));
102
103       messageDisplay = new NewMessageDisplayPanel(this);
104       messageDisplay.configureMessageDisplay();
105
106       toolbar = new ConfigurableToolbar("NewMessageWindowToolbar", Pooka.getResources());
107
108       this.getContentPane().add("North", toolbar);
109       this.getContentPane().add("Center", messageDisplay);
110
111       toolbar.setActive(this.getActions());
112
113       keyBindings = new ConfigurableKeyBinding(getMessageDisplay(), "NewMessageWindow.keyBindings", Pooka.getResources());
114       //keyBindings.setCondition(JComponent.WHEN_IN_FOCUSED_WINDOW);
115

116       keyBindings.setActive(getActions());
117     } catch (MessagingException me) {
118       showError(Pooka.getProperty("error.MessageFrame.errorLoadingMessage", "Error loading Message: ") + "\n" + me.getMessage(), Pooka.getProperty("error.MessageFrame.errorLoadingMessage.title", "Error loading message."));
119       me.printStackTrace();
120     }
121
122     configureInterfaceStyle();
123
124   }
125
126
127   /**
128    * Gets the Theme object from the ThemeManager which is appropriate
129    * for this UI.
130    */

131   public MetalTheme JavaDoc getTheme(ThemeManager tm) {
132     UserProfile up = getSelectedProfile();
133     if (up != null) {
134       String JavaDoc id = Pooka.getProperty(up.getUserProperty() + ".theme", "");
135       if (id != null && ! id.equals("")) {
136         return tm.getTheme(id);
137       }
138     }
139
140     return tm.getDefaultTheme();
141   }
142
143
144   /**
145    * Closes the message window. This checks to see if the underlying
146    * message is modified, and if so, pops up a dialog to make sure that
147    * you really want to close the window.
148    *
149    * Currently, saveDraft isn't implemented, so 'yes' acts as 'cancel'.
150    */

151   public void closeMessageUI() {
152     System.err.println("running closeMessageUI().");
153     handleClose();
154   }
155
156   private void handleClose() {
157     System.err.println("running handleClose().");
158     // first, make sure this is still a valid NewMessageUI.
159
NewMessageProxy nmp = (NewMessageProxy)getMessageProxy();
160     if (nmp == null)
161       dispose();
162
163     if (nmp.getNewMessageUI() == this) {
164       if (((NewMessageProxy)getMessageProxy()).promptForClose()) {
165         int saveDraft = promptSaveDraft();
166         switch (saveDraft) {
167         case JOptionPane.YES_OPTION:
168           ((NewMessageProxy)getMessageProxy()).saveDraft();
169           break;
170         case JOptionPane.NO_OPTION:
171           NewMessageProxy.getUnsentProxies().remove(getMessageProxy());
172           dispose();
173           break;
174         default:
175           return;
176         }
177       } else {
178         NewMessageProxy.getUnsentProxies().remove(getMessageProxy());
179         dispose();
180       }
181     } else {
182       dispose();
183     }
184   }
185
186   /**
187    * Prompts the user to see if she wants to save this message as a draft.
188    *
189    * If the message is not modified, returns JOptionPane.NO_OPTION.
190    */

191   public int promptSaveDraft() {
192     if (isModified()) {
193       return showConfirmDialog(Pooka.getProperty("error.saveDraft.message", "This message has unsaved changes. Would you like to save a draft copy?"), Pooka.getProperty("error.saveDraft.title", "Save Draft"), JOptionPane.YES_NO_CANCEL_OPTION);
194     } else {
195       return JOptionPane.NO_OPTION;
196     }
197   }
198
199   /**
200    * Reattaches the window to the MessagePanel, if there is one.
201    */

202   public void attachWindow() {
203     if (Pooka.getMainPanel().getContentPanel() instanceof MessagePanel) {
204       MessagePanel mp = (MessagePanel) Pooka.getMainPanel().getContentPanel();
205       NewMessageInternalFrame nmif = new NewMessageInternalFrame(mp, this);
206       getMessageProxy().setMessageUI(nmif);
207       nmif.openMessageUI();
208       this.setModified(false);
209       this.dispose();
210     }
211   }
212
213   /**
214    * This returns the values in the MesssageWindow as a set of
215    * InternetHeaders.
216    */

217   public InternetHeaders getMessageHeaders() throws MessagingException {
218     return getNewMessageDisplay().getMessageHeaders();
219   }
220
221   /**
222    * This registers the Keyboard action not only for the FolderWindow
223    * itself, but also for pretty much all of its children, also. This
224    * is to work around something which I think is a bug in jdk 1.2.
225    * (this is not really necessary in jdk 1.3.)
226    *
227    * Overrides JComponent.registerKeyboardAction(ActionListener anAction,
228    * String aCommand, KeyStroke aKeyStroke, int aCondition)
229    */

230
231   public void registerKeyboardAction(ActionListener anAction,
232                                      String JavaDoc aCommand, KeyStroke aKeyStroke, int aCondition) {
233     if (messageDisplay != null)
234       messageDisplay.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);
235     toolbar.registerKeyboardAction(anAction, aCommand, aKeyStroke, aCondition);
236   }
237
238   /**
239    * This unregisters the Keyboard action not only for the FolderWindow
240    * itself, but also for pretty much all of its children, also. This
241    * is to work around something which I think is a bug in jdk 1.2.
242    * (this is not really necessary in jdk 1.3.)
243    *
244    * Overrides JComponent.unregisterKeyboardAction(KeyStroke aKeyStroke)
245    */

246
247   public void unregisterKeyboardAction(KeyStroke aKeyStroke) {
248     if (messageDisplay != null)
249       messageDisplay.unregisterKeyboardAction(aKeyStroke);
250     toolbar.unregisterKeyboardAction(aKeyStroke);
251   }
252
253   /**
254    * This notifies the NewMessageUI that the attachment at the
255    * provided index has been removed. This does not actually remove
256    * the attachment, but rather should be called by the MessageProxy
257    * when an attachment has been removed.
258    */

259   public void attachmentRemoved(int index) {
260     getNewMessageDisplay().attachmentRemoved(index);
261   }
262
263   /**
264    * This notifies the NewMessageUI that an attachment has been added
265    * at the provided index. This does not actually add an attachment,
266    * but rather should be called by the MessageProxy when an attachment
267    * has been added.
268    */

269   public void attachmentAdded(int index) {
270     getNewMessageDisplay().attachmentAdded(index);
271   }
272
273   /**
274    * Pops up a JFileChooser and returns the results.
275    */

276   public File JavaDoc[] getFiles(String JavaDoc title, String JavaDoc buttonText) {
277     JFileChooser jfc;
278     String JavaDoc currentDirectoryPath = Pooka.getProperty("Pooka.tmp.currentDirectory", "");
279     if (currentDirectoryPath == "")
280       jfc = new JFileChooser();
281     else
282       jfc = new JFileChooser(currentDirectoryPath);
283
284     jfc.setDialogTitle(title);
285     jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
286     jfc.setMultiSelectionEnabled(true);
287     int a = jfc.showDialog(this, buttonText);
288
289     Pooka.getResources().setProperty("Pooka.tmp.currentDirectory", jfc.getCurrentDirectory().getPath(), true);
290
291     if (a == JFileChooser.APPROVE_OPTION)
292       return jfc.getSelectedFiles();
293     else
294       return null;
295   }
296
297   /**
298    * Shows an Address Selection form for the given AddressEntryTextArea.
299    */

300   public void showAddressWindow(AddressEntryTextArea aeta) {
301     JFrame jf = new JFrame(Pooka.getProperty("AddressBookTable.title", "Choose Address"));
302     jf.getContentPane().add(new AddressBookSelectionPanel(aeta, jf));
303     jf.pack();
304     jf.setVisible(true);
305   }
306
307   /**
308    * As specified by interface net.suberic.pooka.UserProfileContainer.
309    *
310    * This implementation returns the DefaultProfile of the associated
311    * MessageProxy if the MessageFrame is not editable. If the
312    * MessageFrame is editable, it returns the currently selected
313    * UserProfile object.
314    */

315   public UserProfile getDefaultProfile() {
316     if (isEditable())
317       return getSelectedProfile();
318     else
319       return getMessageProxy().getDefaultProfile();
320   }
321
322   /**
323    * This method returns the UserProfile currently selected in the
324    * drop-down menu.
325    */

326   public UserProfile getSelectedProfile() {
327     return getNewMessageDisplay().getSelectedProfile();
328   }
329
330   /**
331    * sets the currently selected Profile.
332    */

333   public void setSelectedProfile(UserProfile newProfile) {
334     getNewMessageDisplay().setSelectedProfile(newProfile);
335   }
336
337   /**
338    * Overrides JComponent.addNotify().
339    *
340    * We override addNotify() here to set the proper splitPane location.
341    */

342   public void addNotify() {
343     super.addNotify();
344
345     if (firstShow) {
346       messageDisplay.sizeToDefault();
347       resizeByWidth();
348       firstShow = false;
349     }
350   }
351
352   /**
353    * Shows a SendFailedDialog.
354    */

355   public SendFailedDialog showSendFailedDialog(OutgoingMailServer server, javax.mail. MessagingException JavaDoc sfe) {
356     // note this should always be called on the AWTEventThread.
357
SendFailedDialog sfd = new SendFailedDialog(server, sfe);
358     sfd.configureComponent();
359     JOptionPane.showMessageDialog(Pooka.getMainPanel(), new Object JavaDoc[] { sfd }, "Error sending message", JOptionPane.QUESTION_MESSAGE);
360     //Pooka.getUIFactory().showConfirmDialog(new Object[] { sfd }, "Error sending message", 1);
361
return sfd;
362   }
363
364   public boolean isEditable() {
365     return true;
366   }
367
368   public boolean isModified() {
369     return getNewMessageDisplay().isModified();
370   }
371
372   public void setModified(boolean mod) {
373     getNewMessageDisplay().setModified(mod);
374   }
375
376   /**
377    * Sets this as busy or not busy.
378    */

379   public void setBusy(boolean newValue) {
380      super.setBusy(newValue);
381
382     final boolean fNewValue = newValue;
383     Runnable JavaDoc runMe = new Runnable JavaDoc() {
384         public void run() {
385           setEnabled(! fNewValue);
386         }
387       };
388
389     if (SwingUtilities.isEventDispatchThread()) {
390       runMe.run();
391     } else {
392       SwingUtilities.invokeLater(runMe);
393     }
394
395   }
396
397   /**
398    * Sets this editor as enabled or disabled.
399    */

400   public void setEnabled(boolean enabled) {
401     super.setEnabled(enabled);
402     toolbar.setEnabled(enabled);
403     getNewMessageDisplay().setEnabled(enabled);
404   }
405
406   public NewMessageDisplayPanel getNewMessageDisplay() {
407     return (NewMessageDisplayPanel) messageDisplay;
408   }
409
410   //------- Actions ----------//
411

412   /**
413    * performTextAction grabs the focused component on the
414    * MessageFrame and, if it is a JTextComponent, tries to get it
415    * to perform the appropriate ActionEvent.
416    */

417   public void performTextAction(String JavaDoc name, ActionEvent e) {
418     getNewMessageDisplay().performTextAction(name, e);
419   }
420
421   public Action JavaDoc[] getActions() {
422     Action JavaDoc[] returnValue = getDefaultActions();
423
424     if (getMessageDisplay() != null && getMessageDisplay().getActions() != null)
425       returnValue = TextAction.augmentList(getMessageDisplay().getActions(), returnValue);
426
427     return returnValue;
428   }
429
430   public Action JavaDoc[] getDefaultActions() {
431     return defaultActions;
432   }
433
434   private void createDefaultActions() {
435     // The actions supported by the window itself.
436

437     /*defaultActions = new Action[] {
438       new CloseAction(),
439       new CutAction(),
440       new CopyAction(),
441       new PasteAction(),
442       new TestAction()
443       };*/

444
445     defaultActions = new Action JavaDoc[] {
446       new CloseAction(),
447     };
448   }
449
450   //-----------actions----------------
451

452
453   class CloseAction extends AbstractAction {
454
455     CloseAction() {
456       super("file-close");
457     }
458
459     public void actionPerformed(ActionEvent e) {
460       closeMessageUI();
461     }
462   }
463
464   class CutAction extends AbstractAction {
465
466     CutAction() {
467       super("cut-to-clipboard");
468     }
469
470     public void actionPerformed(ActionEvent e) {
471       performTextAction((String JavaDoc)getValue(Action.NAME), e);
472     }
473   }
474
475   class CopyAction extends AbstractAction {
476
477     CopyAction() {
478       super("copy-to-clipboard");
479     }
480
481     public void actionPerformed(ActionEvent e) {
482       performTextAction((String JavaDoc)getValue(Action.NAME), e);
483     }
484   }
485
486   class PasteAction extends AbstractAction {
487
488     PasteAction() {
489       super("paste-from-clipboard");
490     }
491
492     public void actionPerformed(ActionEvent e) {
493       performTextAction((String JavaDoc)getValue(Action.NAME), e);
494     }
495   }
496
497   class TestAction extends AbstractAction {
498
499     TestAction() {
500       super("test");
501     }
502
503     public void actionPerformed(ActionEvent e) {
504       System.out.println(net.suberic.pooka.MailUtilities.wrapText(getMessageText()));
505     }
506   }
507
508 }
509
510
511
512
513
514
Popular Tags