|
/*
* @(#)SimpleChat.java 1.10 04/01/05
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
================================================================================
@(#)README 1.1 06/01/05
================================================================================
UniversalClient example
Description
-----------
The UniversalClient example is a basic 'client' application that uses the JMS 1.1 APIs.
It uses JMS Message Producer and Consumer to send and receive message.
UniversalClient.java does not use JNDI and relies on
the feature by which a broker can "auto-create" the destinations
desired by the user. The bulk of the application deals with the
user interface and the JMS related code is fairly straightforward.
Files
-----
UniversalClient.java Source file for this example.
*.class Prebuilt Java class files for this example.
README This file.
Configuring the environment
---------------------------
To recompile or run this example, you need to set CLASSPATH
to include at least:
jms.jar
imq.jar
directory containing this example
A detailed guideline on setting CLASSPATH is found in the README
file in the jms demo subdirectory as well as in the "Quick Start
Tutorial" in the Sun Java(tm) System Message Queue Developer's Guide.
The following are examples for setting CLASSPATH on the different
platforms. These commands are run from the directory containing
this example.
On Solaris:
setenv CLASSPATH /usr/share/lib/jms.jar:/usr/share/lib/imq.jar:.
On Windows:
set CLASSPATH=%IMQ_HOME%\lib\jms.jar;%IMQ_HOME%\lib\imq.jar;.
On Linux:
setenv CLASSPATH /opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
#####hpux-dev#####
On HP-UX:
export CLASSPATH=/opt/sun/mq/share/lib/jms.jar:
/opt/sun/mq/share/lib/imq.jar:.
Note that it is assumed that the above export command is run on
BASH shell
Building the example
--------------------
Run the following:
javac UniversalClient.java
Running the example
-------------------
Run the following:
java UniversalClient
The application comes up not connected to any jms session.
To connect to a broker, bring down the "Actions" menu and
select the "Connect ..." menu item. A dialog will appear to
provide broker hostname, port, username, password, clientID
etc
To disconnect from a given broker host: port bring down the
"Actions" menu and select the "Disconnect" menu item
Once the application is connected, one can send message using
a message producer. To create a producer bring down the "Actions"
menu and select the "Send Message..." menu item. The Send Message
dialog box will come up, where destination name,type and message
size,ttl etc can be specified while sending message.
To stop message sender bring down the "Actions" menu and select
the "Stop Message Sender" menu item
To receive message bring down the "Actions" menu and select the
"Receive Message..." menu item. The receive message dialog box
will come up where destination name, message consumer type and
message selector can be specified.
To stop message receiver bring down the "Actions" menu and select
the "Stop Message Receiver" menu item.
The received message are displayed on a Message Table. To see the
details of a message double click on a row of a message table or
select a row of a message table and click on "Message Details" button.
To start auto scrolling of message table i.e to always see the last
message received, drag the message table vertical scroll bar at the
bottom. To stop auto scrolling drag the message table vertical scroll
bar else where.
To clear existing messages in the message table bring down the "Actions"
menu and select the "Clear Messages" menu item.
The status bar at the bottom shows Message Queue Client Runtime
Connection Notification And Connection related log
To exit from the application, bring down the "console" menu and
click "exit"
/*
* @(#)SimpleChat.java 1.10 04/01/05
*
* Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
//package examples.applications.uclient;
import com.sun.messaging.jms.notification.ConnectionReconnectedEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Label;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.ResourceAllocationException;
import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TransactionRolledBackException;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JProgressBar;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
/**
* The UniversalClient example is a basic 'client' application that uses the JMS 1.1 APIs.
* It uses JMS Message Producer and Consumer to send and receive message.
*
* When the application is launched, use the 'Universal Client'Actions menu to start or connect to
* a boker.
*
* The broker host port can be provided using the GUI. Once the client is connected one can send
* jms messages to any number of destination Topic or Queue.
*
* Once the Producer send messages to a destination of the given boker,
* one can create a consumer for the same destination which receives the messages
* and display them in a Message Table.
*
* For destination of type Queue one can simply receive message either by using transacted session
* or by using non-transacted session
*
* For topic type destination the one can create a durable Topic subscriber for a given
* topic with a given selector. One can receive message using the topic subscriber created during the
* first receive message button click, but if at later stage one changes the topic selector or the
* transaction type a new durable topic selector is created
*
*
* One can see the details of the message received, by using the 'Message Details' button.
*
*
* @author Sujit Biswas
*/
public class UniversalClient implements UniversalClientConstants,
ExceptionListener {
// Connection, factory and session..
private ConnectionFactory myConnFactory;
private Connection myConn;
private Session myProducerSession;
private Session myConsumerSession;
private MessageProducer myProducer;
private MessageConsumer myConsumer;
private Destination myDestination;
private boolean connected = false;
//data structures
private HashMap mySessionMap = new HashMap();
private HashMap myProducerMap = new HashMap();
//username, hostname
private String userName;
private String password;
private String hostName = "localhost";
private String clientID;
private int port = 7676;
// main frame
private JFrame frame;
//MenuBar and MenuItems
private JMenuBar menuBar;
private JMenuItem connectItem;
private JMenuItem disconnectItem;
private JMenuItem clearItem;
private JMenuItem exitItem;
private JMenuItem sendMsgItem;
private JMenuItem sendMsgStopItem;
private JMenuItem rcvMsgItem;
private JMenuItem rcvMsgStopItem;
//connection dialog box
private ConnectionDialogBox connDialogB;
private JButton connectB;
private JButton connCancelB;
//send message dialog box
private SendMessageDialogBox sendMsgDialogB;
private JButton sendMsgB;
private JButton sendMsgCancelB;
//Footer panel
private JPanel footerPanel;
private JLabel footerLabel;
private boolean footerInUse;
//message table to show the received message
private JTable msgTable;
private JScrollPane msgTableScrollPane;
private boolean scrollingON;
//top panel
private double msgProductionRate;
private JPanel topPanel;
private JLabel msgProductionRateLabel;
private JLabel hostPortLabel;
private JLabel clientIDLabel;
private JProgressBar sendMsgProgressBar = new JProgressBar();
//Message details frame
private JFrame detailsFrame;
private PropertyPanel msgDetailsHeaderPanel;
private PropertyPanel msgDetailsPropertyPanel;
private PropertyPanel msgDetailsBodyPanel;
//receive messages dialog box
private ReceiveMessageDialogBox receiveMsgDialogB;
private JButton receiveMsgB;
private JButton receiveMsgCancelB;
//status area
StatusArea statusArea;
//stop msg sender
private boolean msgSenderStopped;
// stop msg receiver
private boolean msgReceiverStopped;
public UniversalClient() {
userName = "guest";
password = "guest";
clientID = System.getProperty("universalclient.cid", null);
if (clientID == null) {
clientID = System.getProperty("user.name", "UClient-ID");
}
createAndShowGUI();
Thread statusReporter = new StatusReportingThread();
statusReporter.setPriority(Thread.MIN_PRIORITY);
statusReporter.setDaemon(true);
statusReporter.start();
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private void createAndShowGUI() {
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
//Make sure we have nice window decorations.
//JFrame.setDefaultLookAndFeelDecorated(true);
//Create and set up the window.
frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
//create Menubar
menuBar = createMenuBar();
frame.setJMenuBar(menuBar);
//Add the top panel
topPanel = createTopPanel();
frame.getContentPane().add(topPanel, BorderLayout.NORTH);
//create message table panel
JPanel tablePanel = createTablePanel();
//create footer Panel
createFooterPanel();
//add footer to message table
tablePanel.add(footerPanel, BorderLayout.SOUTH);
//create status area
statusArea = new StatusArea();
statusArea.appendText(
"# Message Queue Client Runtime Connection Notification And Connection related log");
/*
* Create another split pane containing the table panel above
* and the status area.
*/
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitPane.setOneTouchExpandable(true);
splitPane.setTopComponent(tablePanel);
splitPane.setBottomComponent(statusArea);
splitPane.setResizeWeight(0.9);
frame.getContentPane().add(splitPane, BorderLayout.CENTER);
//set size of mainframe
setSize();
//Display the window.
frame.setVisible(true);
}
/**
* sets the size of the main frame
*/
private void setSize() {
int relativeSize = 10; //with base = 15
String osName = System.getProperty("os.name", "");
if (osName.indexOf("Windows") >= 0) {
relativeSize = 12;
}
Toolkit tk = frame.getToolkit();
Dimension d = tk.getScreenSize();
frame.setSize((d.width * relativeSize) / 15,
(d.height * relativeSize) / 15);
frame.setLocation(d.width / 8, d.height / 16);
}
/**
* Create menubar for application.
*/
private JMenuBar createMenuBar() {
JMenuBar mb = new JMenuBar();
JMenu consoleMenu = (JMenu) mb.add(new JMenu("Universal Client"));
consoleMenu.setMnemonic('C');
JMenu actionsMenu = (JMenu) mb.add(new JMenu("Actions"));
actionsMenu.setMnemonic('A');
connectItem = addMenuItem(actionsMenu, "Connect ...");
connectItem.setMnemonic('C');
disconnectItem = addMenuItem(actionsMenu, "Disconnect");
disconnectItem.setMnemonic('D');
actionsMenu.add(new JSeparator());
sendMsgItem = addMenuItem(actionsMenu, "Send Message ...");
sendMsgItem.setMnemonic('M');
sendMsgStopItem = addMenuItem(actionsMenu, "Stop Msg Sender");
sendMsgStopItem.setMnemonic('S');
actionsMenu.add(new JSeparator());
rcvMsgItem = addMenuItem(actionsMenu, "Receive Message ...");
rcvMsgItem.setMnemonic('R');
rcvMsgStopItem = addMenuItem(actionsMenu, "Stop Msg Receiver");
rcvMsgStopItem.setMnemonic('t');
actionsMenu.add(new JSeparator());
clearItem = addMenuItem(actionsMenu, "Clear Messages");
clearItem.setMnemonic('e');
exitItem = addMenuItem(consoleMenu, "Exit");
exitItem.setMnemonic('x');
exitItem.setAccelerator(KeyStroke.getKeyStroke('Q', 2));
disconnectItem.setEnabled(false);
connectItem.addActionListener(new ConnectionPopUpListener());
disconnectItem.addActionListener(new DisConnectionListener());
sendMsgItem.addActionListener(new SendMessagePopUpListener());
sendMsgItem.setEnabled(false);
sendMsgStopItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setMsgSenderStopped(true);
}
});
sendMsgStopItem.setEnabled(false);
rcvMsgItem.addActionListener(new ReceiveMessagePopUpListener());
rcvMsgItem.setEnabled(false);
rcvMsgStopItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stopMsgReceiver();
}
});
rcvMsgStopItem.setEnabled(false);
clearItem.addActionListener(new ClearMessageListener());
exitItem.addActionListener(new ExitListener());
return (mb);
}
/**
* adds menu item to menu
*/
private JMenuItem addMenuItem(JMenu menu, String itemStr) {
JMenuItem item = (JMenuItem) menu.add(newJMenuItem(itemStr));
return item;
}
/**
* returns a new JMenuItem
*/
private JMenuItem newJMenuItem(String s) {
JMenuItem jmi = new JMenuItem(s);
return jmi;
}
/**
* create table Panel for message received
*/
private JPanel createTablePanel() {
JPanel tPanel = new JPanel();
tPanel.setLayout(new BorderLayout());
msgTable = new JTable(new MsgTable());
msgTable.addMouseListener(new TableMouseListener());
TableColumn column = msgTable.getColumnModel().getColumn(1);
column.setPreferredWidth(125);
column = msgTable.getColumnModel().getColumn(2);
column.setPreferredWidth(85);
column = msgTable.getColumnModel().getColumn(3);
column.setPreferredWidth(95);
column = msgTable.getColumnModel().getColumn(4);
column.setPreferredWidth(15);
column = msgTable.getColumnModel().getColumn(5);
column.setPreferredWidth(15);
column = msgTable.getColumnModel().getColumn(6);
column.setPreferredWidth(40);
msgTableScrollPane = new JScrollPane(msgTable);
msgTableScrollPane.setAutoscrolls(true);
MouseMotionListener doScrollRectToVisible = new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
((JScrollBar) e.getSource()).scrollRectToVisible(r);
int maxHeight = msgTable.getVisibleRect().height;
if (e.getY() > (maxHeight - 30)) {
setScrollingON(true);
} else {
setScrollingON(false);
}
}
};
msgTableScrollPane.getVerticalScrollBar().addMouseMotionListener(doScrollRectToVisible);
msgTableScrollPane.getVerticalScrollBar().setToolTipText("Drag to Bottom to Start auto scroll, to Stop autoscroll Drag else where");
tPanel.add(new JLabel("Received Message Table", SwingConstants.CENTER),
BorderLayout.NORTH);
tPanel.add(msgTableScrollPane, BorderLayout.CENTER);
tPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
return tPanel;
}
/**
* create top Panel for production related statistics
*/
private JPanel createTopPanel() {
msgProductionRate = Double.NaN;
topPanel = new JPanel(new BorderLayout());
topPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
JLabel l = new JLabel("Connection & Message Production",
SwingConstants.CENTER);
l.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
topPanel.add(BorderLayout.NORTH, l);
JPanel dummyP = new JPanel(new BorderLayout());
clientIDLabel = new JLabel();
msgProductionRateLabel = new JLabel();
hostPortLabel = new JLabel();
dummyP.add(BorderLayout.NORTH, clientIDLabel);
dummyP.add(BorderLayout.CENTER, hostPortLabel);
dummyP.add(BorderLayout.SOUTH, msgProductionRateLabel);
topPanel.add(BorderLayout.WEST, dummyP);
setClientID();
setMsgProductionRate("Not Available");
setHostPort("Client Not Connected");
dummyP = new JPanel(new BorderLayout());
setSendMsgProgressBar(0, "");
dummyP.add(BorderLayout.CENTER, sendMsgProgressBar);
topPanel.add(BorderLayout.SOUTH, dummyP);
topPanel.setPreferredSize(new Dimension(0, 95));
return topPanel;
}
/**
* Main
*/
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
UniversalClient uc = new UniversalClient();
}
});
}
/**
* shows connection dialog box to connect to a broker
*/
private void popUpConnDialogBox() {
if (connDialogB == null) {
connDialogB = new ConnectionDialogBox(frame);
connectB = connDialogB.getConnectButton();
connectB.addActionListener(new ConnectionListener());
connCancelB = connDialogB.getCancelButton();
connCancelB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
connDialogB.setVisible(false);
}
});
}
connDialogB.setUserName(userName);
connDialogB.setPassword(password);
connDialogB.setClientID(clientID);
connDialogB.setVisible(true);
}
/**
* shows Send Message dialog box for sending one or more message
*/
private void popUpSendMessageDialogBox() {
if (sendMsgDialogB == null) {
sendMsgDialogB = new SendMessageDialogBox(frame);
sendMsgB = sendMsgDialogB.getSendButton();
sendMsgB.addActionListener(new SendMessageListener());
sendMsgCancelB = sendMsgDialogB.getCancelButton();
sendMsgCancelB.addActionListener(new Acti
|