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 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 private Action connectAction, disconnectAction, clearAction, refreshAction, publishAction, exitAction; 33 34 private static final String NOT_CONNECTED = "Not connected"; 36 private static final String CONNECTED_TO = "Connected to "; 37 38 static final ImageIcon networkIcon = 40 new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class .class.getResource("/images/network.png"))); 41 static final ImageIcon stopIcon = 42 new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class .class.getResource("/images/stop.png"))); 43 static final ImageIcon trashIcon = 44 new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class .class.getResource("/images/trashcan_empty.png"))); 45 static final ImageIcon scriptIcon = 46 new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class .class.getResource("/images/history.png"))); 47 static final ImageIcon envelopeIcon = 48 new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class .class.getResource("/images/mail_generic.png"))); 49 static final ImageIcon rightArrowIcon = 50 new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class .class.getResource("/images/1rightarrow.png"))); 51 static final ImageIcon downArrowIcon = 52 new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class .class.getResource("/images/1downarrow.png"))); 53 static final ImageIcon homeIcon = 54 new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class .class.getResource("/images/gohome.png"))); 55 static final ImageIcon refreshIcon = 56 new ImageIcon(Toolkit.getDefaultToolkit().getImage(Class .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 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 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 setupColumns(); 83 84 messagePane = new JEditorPane("text/html", ""); 86 messagePane.setEditable(false); 87 messagePane.setPreferredSize(new Dimension(500, 400)); 88 89 this.right = new JSplitPane(JSplitPane.VERTICAL_SPLIT, 91 new JScrollPane(messagesTable), 92 new JScrollPane(messagePane)); 93 94 this.splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, 96 new JScrollPane(topicTree), 97 right); 98 99 statusBar = new JLabel(NOT_CONNECTED); 101 statusBar.setBorder(new BevelBorder(BevelBorder.LOWERED)); 102 103 getContentPane().setLayout(new BorderLayout()); 105 getContentPane().add(splitter, BorderLayout.CENTER); 106 getContentPane().add(statusBar, BorderLayout.SOUTH); 107 108 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 setJMenuBar(setupMenuBar()); 121 122 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 SwingUtilities.invokeLater(new Runnable () { 143 public void run() 144 { 145 topicTree.expandPath(e.getTreePath()); 146 } 147 }); 148 } 149 }); 150 151 topicTree.addTreeSelectionListener(new TreeSelectionListener() { 155 156 160 public void valueChanged(javax.swing.event.TreeSelectionEvent e) 161 { 162 refreshList(); 163 } 164 165 }); 166 167 messagesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { 170 171 175 public void valueChanged(ListSelectionEvent e) 176 { 177 ListSelectionModel lsm = messagesTable.getSelectionModel(); 178 StringBuffer description = new StringBuffer (); 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 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 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 uri) 237 { 238 try { 239 c.connect(new URLConnectionFactory(uri), "#"); 240 241 connectAction.setEnabled(false); 243 disconnectAction.setEnabled(true); 244 refreshAction.setEnabled(true); 245 publishAction.setEnabled(true); 246 247 statusBar.setText(CONNECTED_TO + uri); 249 } 250 catch (javax.jms.JMSException 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 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 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 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 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 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 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 getTableCellRendererComponent(JTable table, 393 Object 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 437 public Component getTreeCellRendererComponent(JTree tree, 438 Object 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 (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 475 public static void main(String s[]) 476 { 477 MessageController c = new MessageController(); 478 479 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 |