KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ubermq > jms > ui > viewer > MessageViewer


1 package com.ubermq.jms.ui.viewer;
2
3 import com.ubermq.jms.client.*;
4 import java.awt.*;
5 import java.awt.event.*;
6 import java.text.*;
7 import java.util.*;
8 import javax.swing.*;
9 import javax.swing.border.*;
10 import javax.swing.event.*;
11 import javax.swing.table.*;
12 import javax.swing.tree.*;
13
14 /**
15  * A Swing-based message viewer window that handles incoming
16  * JMS messages and displays them. The window has a tree
17  * as the left pane, and a list in the right pane, showing
18  * messages as delivered to the topic in the hierarchy.
19  */

20 public class MessageViewer
21     extends JFrame
22 {
23     private final MessageController c;
24
25     private final JTree topicTree;
26     private final JTable messagesTable;
27     private final JEditorPane messagePane;
28     private final JLabel statusBar;
29     private final JSplitPane right, splitter;
30
31     // ACTIONS
32
private Action connectAction, disconnectAction, clearAction, refreshAction, publishAction, exitAction;
33
34     // STRINGS
35
private static final String JavaDoc NOT_CONNECTED = "Not connected";
36     private static final String JavaDoc CONNECTED_TO = "Connected to ";
37
38     // IMAGES
39
static final ImageIcon networkIcon =
40         new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class JavaDoc.class.getResource("/images/network.png")));
41     static final ImageIcon stopIcon =
42         new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class JavaDoc.class.getResource("/images/stop.png")));
43     static final ImageIcon trashIcon =
44         new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class JavaDoc.class.getResource("/images/trashcan_empty.png")));
45     static final ImageIcon scriptIcon =
46         new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class JavaDoc.class.getResource("/images/history.png")));
47     static final ImageIcon envelopeIcon =
48         new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class JavaDoc.class.getResource("/images/mail_generic.png")));
49     static final ImageIcon rightArrowIcon =
50         new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class JavaDoc.class.getResource("/images/1rightarrow.png")));
51     static final ImageIcon downArrowIcon =
52         new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class JavaDoc.class.getResource("/images/1downarrow.png")));
53     static final ImageIcon homeIcon =
54         new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class JavaDoc.class.getResource("/images/gohome.png")));
55     static final ImageIcon refreshIcon =
56         new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class JavaDoc.class.getResource("/images/refresh.png")));
57
58
59     public MessageViewer(final MessageController c)
60     {
61         super("UberMQ Message Viewer");
62         this.c = c;
63
64         // construct the tree
65
topicTree = new JTree(c.getTreeModel());
66         topicTree.expandRow(0);
67         topicTree.setScrollsOnExpand(true);
68         topicTree.setCellRenderer(new MyTreeCellRenderer(topicTree.getFont()));
69
70         final TreeSelectionModel tsm = new DefaultTreeSelectionModel();
71         tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
72         topicTree.setSelectionModel(tsm);
73
74         // construct the table
75
messagesTable = new JTable(c.getTableModel());
76         messagesTable.setShowHorizontalLines(false);
77         messagesTable.setDefaultRenderer(Date.class,
78                                          new MyDateRenderer());
79         messagesTable.setSelectionMode(DefaultListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
80
81         // set up columns
82
setupColumns();
83
84         // construct message pane
85
messagePane = new JEditorPane("text/html", "");
86         messagePane.setEditable(false);
87         messagePane.setPreferredSize(new Dimension(500, 400));
88
89         // construct the right hand list/msg pane
90
this.right = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
91                                     new JScrollPane(messagesTable),
92                                     new JScrollPane(messagePane));
93
94         // split em
95
this.splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
96                                        new JScrollPane(topicTree),
97                                        right);
98
99         // add status bar
100
statusBar = new JLabel(NOT_CONNECTED);
101         statusBar.setBorder(new BevelBorder(BevelBorder.LOWERED));
102
103         // add the split pane to the content pane. done.
104
getContentPane().setLayout(new BorderLayout());
105         getContentPane().add(splitter, BorderLayout.CENTER);
106         getContentPane().add(statusBar, BorderLayout.SOUTH);
107
108         // actions
109
connectAction = new ConnectAction();
110         disconnectAction = new DisconnectAction();
111         disconnectAction.setEnabled(false);
112         clearAction = new ClearAction();
113         refreshAction = new RefreshAction();
114         refreshAction.setEnabled(false);
115         publishAction = new PublishAction();
116         publishAction.setEnabled(false);
117         exitAction = new ExitAction();
118
119         // create the menu bar, and add it
120
setJMenuBar(setupMenuBar());
121
122         // whenever the tree model gets a new node, we expand the
123
// view so the user can see the new node.
124
c.getTreeModel().addTreeModelListener(new TreeModelListener() {
125                     public void treeNodesRemoved(TreeModelEvent e)
126                     {
127                     }
128                     public void treeNodesChanged(TreeModelEvent e)
129                     {
130                         if (topicTree.getSelectionPath() != null)
131                         {
132                             if (e.getChildren()[0].equals(topicTree.getSelectionPath().getLastPathComponent()))
133                                 refreshList();
134                         }
135                     }
136                     public void treeStructureChanged(TreeModelEvent e)
137                     {
138                     }
139                     public void treeNodesInserted(final TreeModelEvent e)
140                     {
141                         // make sure the new node is visible.
142
SwingUtilities.invokeLater(new Runnable JavaDoc() {
143                                     public void run()
144                                     {
145                                         topicTree.expandPath(e.getTreePath());
146                                     }
147                                 });
148                     }
149                 });
150
151         // when you select something in the tree,
152
// the controller's populateList method is called to
153
// fill the list with messages from the given node.
154
topicTree.addTreeSelectionListener(new TreeSelectionListener() {
155
156                     /**
157                      * Called whenever the value of the selection changes.
158                      * @param e the event that characterizes the change.
159                      */

160                     public void valueChanged(javax.swing.event.TreeSelectionEvent JavaDoc e)
161                     {
162                         refreshList();
163                     }
164
165                 });
166
167         // the list selection handler causes the descriptive
168
// panel to contain the message text
169
messagesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
170
171                     /**
172                      * Called whenever the value of the selection changes.
173                      * @param e the event that characterizes the change.
174                      */

175                     public void valueChanged(ListSelectionEvent e)
176                     {
177                         ListSelectionModel lsm = messagesTable.getSelectionModel();
178                         StringBuffer JavaDoc description = new StringBuffer JavaDoc();
179
180                         int lastIndex = lsm.getMaxSelectionIndex();
181                         for (int i = lsm.getMinSelectionIndex(); i >= 0 && i <= lastIndex; i++)
182                         {
183                             if (lsm.isSelectedIndex(i) && i < messagesTable.getModel().getRowCount())
184                             {
185                                 description.append(c.getMessageDescription(i));
186                                 description.append("\n");
187                             }
188                         }
189
190                         messagePane.setText(description.toString());
191                     }
192
193                 });
194
195     }
196
197     private static final int TABLE_MODEL_INDEX[] = {MessageController.COL_TYPE,
198             MessageController.COL_TIMESTAMP,
199             MessageController.COL_MSG_NUMBER,
200             MessageController.COL_SENDER_ID,
201             MessageController.COL_SEQUENCE};
202     private static final int TABLE_PREFERRED_WIDTH[] = {100, 275, 100, 150, 50};
203     private static final String JavaDoc TABLE_HEADER_VALUE[] = {"Type", "Received", "Msg #", "Sender", "Seq"};
204
205     private void setupColumns()
206     {
207         DefaultTableColumnModel columns = (DefaultTableColumnModel)messagesTable.getColumnModel();
208         for (int i = 0; i < columns.getColumnCount(); i++)
209         {
210             TableColumn tc = columns.getColumn(i);
211
212             tc.setModelIndex(TABLE_MODEL_INDEX[i]);
213             tc.setPreferredWidth(TABLE_PREFERRED_WIDTH[i]);
214             tc.setHeaderValue(TABLE_HEADER_VALUE[i]);
215         }
216     }
217
218     /**
219      * Adds all messages contained in the selected topic to the right
220      * hand message list.
221      */

222     private void refreshList()
223     {
224         TreeSelectionModel tsm = topicTree.getSelectionModel();
225         if (!tsm.isSelectionEmpty()) {
226             MessageTreeNode mtn = (MessageTreeNode)tsm.getSelectionPath().getLastPathComponent();
227
228             int row = this.messagesTable.getSelectedRow();
229             c.populateList(mtn);
230             this.messagesTable.getSelectionModel().setSelectionInterval(row, row);
231
232             mtn.viewed();
233         }
234     }
235
236     private void connect(String JavaDoc uri)
237     {
238         try {
239             c.connect(new URLConnectionFactory(uri), "#");
240
241             // enable/disable
242
connectAction.setEnabled(false);
243             disconnectAction.setEnabled(true);
244             refreshAction.setEnabled(true);
245             publishAction.setEnabled(true);
246
247             // status bar
248
statusBar.setText(CONNECTED_TO + uri);
249         }
250         catch (javax.jms.JMSException JavaDoc x) {
251             JOptionPane.showMessageDialog(MessageViewer.this, x.getMessage());
252         }
253     }
254
255     private class ConnectAction extends AbstractAction
256     {
257         ConnectAction() {super("Connect...", networkIcon);}
258         public void actionPerformed(ActionEvent e)
259         {
260             String JavaDoc uri =
261                 JOptionPane.showInputDialog(MessageViewer.this,
262                                             "Please enter the URI of the server to connect to.",
263                                             "ubermq://localhost:3999");
264             if (uri == null ||
265                 uri.length() == 0)
266                 return;
267
268             connect(uri);
269         }
270     }
271
272     private class DisconnectAction extends AbstractAction
273     {
274         DisconnectAction() {super("Disconnect", stopIcon);}
275         public void actionPerformed(ActionEvent e)
276         {
277             c.disconnect();
278
279             setEnabled(false);
280             connectAction.setEnabled(true);
281             refreshAction.setEnabled(false);
282             publishAction.setEnabled(false);
283
284             statusBar.setText(NOT_CONNECTED);
285         }
286
287     }
288
289     private class ClearAction extends AbstractAction
290     {
291         ClearAction() {super("Clear Messages", trashIcon);}
292         public void actionPerformed(ActionEvent e)
293         {
294             c.clear();
295         }
296     }
297
298     private class RefreshAction extends AbstractAction
299     {
300         RefreshAction()
301         {
302             super("Refresh", refreshIcon);
303             putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F5, 0));
304         }
305
306         public void actionPerformed(ActionEvent e)
307         {
308             refreshList();
309         }
310     }
311
312     private class PublishAction extends AbstractAction
313     {
314         PublishAction()
315         {
316             super("Publish...", envelopeIcon);
317             putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P, KeyEvent.CTRL_MASK));
318         }
319
320         public void actionPerformed(ActionEvent e)
321         {
322             String JavaDoc topic =
323                 JOptionPane.showInputDialog(MessageViewer.this,
324                                             "Enter the topic to publish to",
325                                             "com.ubermq.publish.test");
326             if (topic == null ||
327                 topic.length() == 0)
328                 return;
329
330             String JavaDoc text =
331                 JOptionPane.showInputDialog(MessageViewer.this,
332                                             "Enter some text to include as the message body",
333                                             "hello world");
334             if (text == null ||
335                 text.length() == 0)
336                 return;
337
338             try
339             {
340                 c.publish(topic, text);
341             }
342             catch (javax.jms.JMSException JavaDoc x) {
343                 JOptionPane.showMessageDialog(MessageViewer.this, x.getMessage());
344             }
345
346         }
347     }
348
349     private class ExitAction extends AbstractAction
350     {
351         ExitAction()
352         {
353             super("Quit");
354             putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, KeyEvent.CTRL_MASK));
355         }
356         public void actionPerformed(ActionEvent e)
357         {
358             System.exit(0);
359         }
360     }
361
362     JMenuBar setupMenuBar()
363     {
364         JMenuBar menuBar = new JMenuBar();
365
366         // Server |
367
JMenu serverMenu = new JMenu("Server");
368         serverMenu.add(connectAction);
369         serverMenu.add(disconnectAction);
370         serverMenu.addSeparator();
371         serverMenu.add(exitAction);
372
373         JMenu publishMenu = new JMenu("Message");
374         publishMenu.add(refreshAction);
375         publishMenu.add(clearAction);
376         publishMenu.addSeparator();
377         publishMenu.add(publishAction);
378
379         // add menus to bar.
380
menuBar.add(serverMenu);
381         menuBar.add(publishMenu);
382         return menuBar;
383     }
384
385     private static class MyDateRenderer
386         extends DefaultTableCellRenderer
387         implements TableCellRenderer
388     {
389         private static final DateFormat df =
390             new SimpleDateFormat("dd MMM yyyy HH:mm:ss.SSS");
391
392         public java.awt.Component JavaDoc getTableCellRendererComponent(JTable table,
393                                                                 Object JavaDoc value,
394                                                                 boolean isSelected,
395                                                                 boolean hasFocus,
396                                                                 int row,
397                                                                 int column)
398         {
399             return super.getTableCellRendererComponent(table,
400                                                        df.format((Date)value),
401                                                        isSelected,
402                                                        hasFocus,
403                                                        row,
404                                                        column);
405         }
406     }
407
408     private class MyTreeCellRenderer
409         extends DefaultTreeCellRenderer
410         implements TreeCellRenderer
411     {
412         private final Font plainFont, newMessageFont;
413
414         public MyTreeCellRenderer(Font plainFont)
415         {
416             super();
417             this.plainFont = plainFont;
418             this.newMessageFont = plainFont.deriveFont(Font.BOLD);
419
420             setLeafIcon(envelopeIcon);
421             setClosedIcon(scriptIcon);
422             setOpenIcon(scriptIcon);
423         }
424
425         /**
426          * Sets the value of the current tree cell to <code>value</code>.
427          * If <code>selected</code> is true, the cell will be drawn as if
428          * selected. If <code>expanded</code> is true the node is currently
429          * expanded and if <code>leaf</code> is true the node represets a
430          * leaf and if <code>hasFocus</code> is true the node currently has
431          * focus. <code>tree</code> is the <code>JTree</code> the receiver is being
432          * configured for. Returns the <code>Component</code> that the renderer
433          * uses to draw the value.
434          *
435          * @return the <code>Component</code> that the renderer uses to draw the value
436          */

437         public Component getTreeCellRendererComponent(JTree tree,
438                                                       Object JavaDoc value,
439                                                       boolean selected,
440                                                       boolean expanded,
441                                                       boolean leaf,
442                                                       int row,
443                                                       boolean hasFocus)
444         {
445             TreePath path = tree.getPathForRow(row);
446             if (path != null) {
447                 MessageTreeNode mtn = (MessageTreeNode)path.getLastPathComponent();
448
449                 if (mtn.hasNewMessages()) {
450                     setFont(newMessageFont);
451                 } else {
452                     setFont(plainFont);
453                 }
454             } else {
455                 setFont(plainFont);
456             }
457
458             super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
459
460             // if we are root, display home icon
461
if (value == c.getTreeModel().getRoot())
462                 setIcon(homeIcon);
463
464             return this;
465         }
466
467     }
468
469     private static final Dimension INITIAL_SIZE = new Dimension(600, 400);
470     private static final double DIVIDER_PROPORTION = 0.4;
471
472     /**
473      * Constructs the message viewer application window.
474      */

475     public static void main(String JavaDoc s[])
476     {
477         MessageController c = new MessageController();
478
479         // display
480
MessageViewer frame = new MessageViewer(c);
481         frame.addWindowListener(new WindowAdapter() {
482                     public void windowClosing(WindowEvent e) {System.exit(0);}
483                 });
484
485         frame.pack();
486         frame.setSize(INITIAL_SIZE);
487         frame.setVisible(true);
488         frame.right.setDividerLocation(DIVIDER_PROPORTION);
489         frame.splitter.setDividerLocation(DIVIDER_PROPORTION);
490
491         if (s.length > 0)
492             frame.connect(s[0]);
493     }
494
495 }
496
497
498
Popular Tags