/****************************CICS Applications Design and Programming Sample***********************************************

	Java Classes supplied: 	MQClient		
				MQCommunicator
				AccountRecord
				AccountHistory
				AccountHistoryTableModel
				DisplayField

	Description:	This is a sample Java application to show a simple case of using MQSeries to access a CICS 
			application on a different system, with the standard MQSeries to CICS DPL bridge.
			The CICS server program being connected to is NACT02. This application makes use of the 
			Inquire function (Read without Lock) of NACT02 to retrieve customer details when the Customer
			Number is supplied by the user.
			Note: there are hard code values for the local queue manager the message channel and the queues
			to be used.

	Pre-Requisites:	This sample requires that the NACT02 program is installed on your CICS server and that the
			MQSeries to CICS DPL bridge has been set up and is active.  
			In order to connect to NACT02 An MQSeries queue manager must be set up and started on the
			machine on which this Java application is to run, along with the required MQSeries channel to
			the server machine and a listener. A set of MQSeries object definitions for use with this
			application are provided within the CICS Applications Design and Programming package of which
			this is part.
			


	(C) Copyright International Business Machines Corp. 1995,1999


			This code does not demonstrate all the techniques required for a large application.
			It is not a template and should not be used as the foundation for your next mission critical
			application.

 **************************************************************************************************************************
*/

/*				
	Class encapsulating the client GUI and functionality. It makes use of structures defined in other classes
	which represent record formats, as well as the MQCommunicator class which handles MQ connections.

*/


import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.DefaultListModel;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.*;
import javax.swing.event.ListSelectionListener; 
import javax.swing.table.*;
import javax.swing.event.*;
import javax.swing.UIManager.*;
import javax.swing.border.EmptyBorder;

import com.ibm.mq.*;

class MQClient extends JFrame {

	// *** MQ Variables ***
	private String				hostname;
	private String				channel;
	private String				qManager;
	private String				requestQueue;
	private String				replyQueue;
	
	private MQCommunicator			MQComms;

	private MQMessage			currentRequest;		// Reference to last request for an account's details
	private String				customerDetails = "";	// Account record currently being displayed
	private String				messageReturned ="";
	
	// Main frame appearance
	private final static String		title = "KanDoIT Account Enquiry Client";
	private String				aboutText;

	private final static int		xpos = 120, ypos = 80,			// Main window location
						aboutWidth=350, aboutHeight=150,	
						aboutXpos = 230, aboutYpos = 190;
	
	//CICS related variables
	private String				CICSresponseCode = "";			// CICS program response code 1
	private String 				CICSreasonCode = "";			// CICS program reponse code 2
	private int				CICSresponseAsInt;
	private int				CICSreasonAsInt;

	// 'About' dialog
	private JDialog				aboutDialog;

	// NEW GUI STUFF
	private JMenuBar			menuBar;

	private JMenu				clientMenu;

	private JMenuItem			menuExit, menuFetch;
	private JMenuItem			helpMenuAbout;
	private JButton				buttonFetch;

	private JComboBox			accountNumberField;

	private Color				background = Color.lightGray;	// Default background for fields


	private DisplayField			titleField = new DisplayField(50, background),
						initialField = new DisplayField(50, background),
						fnameField = new DisplayField(100, background),
						surnameField = new DisplayField(100, background),
						address1Field = new DisplayField(100, background),
						address2Field = new DisplayField(100, background),
						address3Field = new DisplayField(100, background),
						phoneField = new DisplayField(50, background),
						others1Field = new DisplayField(100, background),
						others2Field = new DisplayField(50, background),
						others3Field = new DisplayField(50, background),
						others4Field = new DisplayField(50, background),
						noOfCardsField = new DisplayField(50, background),
						dateIssuedField = new DisplayField(100, background),
						reasonField = new DisplayField(50, background),
						cardCodeField = new DisplayField(50, background),
						approvedField = new DisplayField(70, background),
						special1Field = new DisplayField(50, background),
						special2Field = new DisplayField(50, background),
						special3Field = new DisplayField(50, background),
						acctStatusField = new DisplayField(50, background),
						chargeLimitField = new DisplayField(100, background);

	
	private JTable				accountHistory = new JTable();
	private JScrollPane			scrollpane = new JScrollPane(accountHistory);
	private TableModel			dataModel;


	// Constants
	private final int			recordLength = 383,	// All records must be this length
						width = 800, height = 500,
						tableWidth=350, tableHeight=71,
						borderSize = 15,
						verticalPanelGap = 20, horizontalPanelGap = 20,
						verticalComponentGap = 5, horizontalComponentGap = 1;
	

	public MQClient(String[] args) {

		// Read command line args into class variables
		hostname = args[0];
		channel = args[1];
		qManager = args[2];
		requestQueue = args[3];
		replyQueue = args[4];

		// Setup MQ object
		MQComms = new MQCommunicator(hostname, channel, qManager, requestQueue, replyQueue);
		
		// Diagnostic output
		print("*** MQOptions ***");
		print("Hostname: " + hostname + "\nChannel: " + channel + "\nQManager: " + qManager + 
			"\nRequestQueue: " + requestQueue + "\nReplyQueue: " + replyQueue);

		// Layout & window appearance
		setJMenuBar(createClientMenuBar()); 
		
		JScrollPane scrollpane = new JScrollPane(createRecordPanel());
		
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add("North", createFetchPanel());
		getContentPane().add("Center", scrollpane);

		setTitle(title);
		setLocation(xpos, ypos);

		// Window Eventhandling	
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				exit();
			}
		});

		createEventHandlers();

		pack();
		setVisible(true);
	}


	public void enableDisableFields(boolean option) {
		accountNumberField.setEditable(option);
		buttonFetch.setEnabled(option);
	}


	// Retrieve account ID of requested record
	// Create new MQ message if appropriate
	public void clickedFetch() {
		try{
		String requested = getAccountNumber();
		// Disable the 'fetch' panel while a request is in progress...re-enabled afterwards in 'finally' section
		enableDisableListItems(false);
		

		if(requested == null){
			informUser("You requested an invalid record ID.  Enter a valid ID, or consult the help"
				+" file for assistance.");
			return;
		}

		
		// Otherwise pass string to communications object which handles MQ operations
		currentRequest = MQComms.send(requested);

		// Check to see if it returned OK
		if(currentRequest == null){
			informUser("There was an error sending your request. Make sure you are connected to a network,"
				+" and try again."
				+ "\nIf the problem persists, consult your systems administrator.");
			return;
		}

		print(">MQ Status: Waiting for a reply message...");
		// "currentRequest" now holds information about the message we just sent
		// Use this to wait on a reply.
		messageReturned = MQComms.receive(currentRequest);
		
		// Check to see if it returned OK
		if(messageReturned == null){
			informUser("There was an error waiting for the reply to your request. "
				+ "Consult your systems administrator for further assistance.");
			return;
		}

		//informUser("Message received!");
		//print("Message is: " + messageReturned);
		//Check that inquire has been successful
		CICSresponseCode = messageReturned.substring(12,16);
		print(">CICS response code " + CICSresponseCode+"#");
		
		CICSreasonCode = messageReturned.substring(16,20);
		print(">CICS reason code " + CICSreasonCode+"#");
		if(CICSresponseCode.equals("0000")){
			//Strip off the fields preceding the customer record
			customerDetails = messageReturned.substring(25,408);
			AccountRecord retrieved=new AccountRecord(customerDetails);
			displayRecord(retrieved);
			return;
		}

		//No valid record to display so clear fields 
		clearDisplay();

		//Check out error response returned by CICS
		if(CICSresponseCode.equals("0013")){
			informUser("No record can be found for the customer number given.");
			return;
		}
		if(CICSresponseCode.equals("LOCK")){
			informUser("The requested record is currently unavailable, possibly being updated."
					+ "\nPlease try again later.");
			return;
		}
		if(CICSresponseCode.equals("ABND")){
			informUser("Please inform the systems administrator that the CICS system has"
					+ "\nabnormally ended with code " + CICSreasonCode +" Severe Error");
			return;
		}
		if((CICSresponseCode.equals("FRMT")) & (CICSreasonCode.equals("LENE"))){
				informUser("Please inform the systems administrator that the call to the CICS program"
					+ "\nhas failed due to an error in the length of data supplied.");
		}
		if((CICSresponseCode.equals("FRMT")) & (CICSreasonCode.equals("REQE"))){
				informUser("Please inform the systems administrator that the call to the CICS program"
					+ "\nhas failed due to an error in the type of request made.");
		}
		informUser("Please inform the systems administrator that the call to the CICS program"
			+ "\nhas failed with the following error"
			+ "\nEIBRESP= "+ CICSresponseCode + " EIBRESP2= " + CICSreasonCode); 
		}finally{
			enableDisableListItems(true);
		}
	}


	public void clickedHelpAbout() {
		enableDisableListItems(false);
		try{
			// Load 'About' info from file if file is there & readable
			try {
				BufferedReader buffRead = new BufferedReader(new FileReader("about.txt"));
				
				String temp = "";
				while ((temp = buffRead.readLine()) != null){
					aboutText += "\n" + temp;
				}
			
				buffRead.close();

			} catch(IOException e){
				// If no file available use a simple explanatory string
				aboutText = "The about details file is not available or accessible.";
			}

			informUser(aboutText);      		
		}finally{
			enableDisableListItems(true);
		}					
		return;
	}


	public void clickedExit() {
		exit();
	}


	// Exiting control including status checking
	public void exit() {
		JOptionPane pane = new JOptionPane();
		int response = pane.showConfirmDialog(null, "Reallly exit ?", 
			"Confim exit", JOptionPane.YES_NO_OPTION);

		if(response == JOptionPane.NO_OPTION) return;
		else System.exit(0);
	}


	public void toggleStatus() {
		//if(menuBar.status.getState() == true) status.setVisible(true);
		//else status.setVisible(false);
	}


	public static void print(String msg) {
		PrintWriter message = new PrintWriter(System.out, true);
		message.println(msg);
	}


	public void informUser(String msg) {
		JOptionPane pane = new JOptionPane();
		pane.showMessageDialog(this, msg, "MQClient", JOptionPane.INFORMATION_MESSAGE);
		pane.setVisible(true);	

		//Dimension d = pane.getSize();
		//d.width = 420;
		//pane.setSize(d);
	}
	
	public void refreshWindowTitle(String str) {
		String folderPath = str;
		this.setTitle(title + " - " + folderPath);
	}

	
	/**
	 * Create the event handlers. Each button event is directed
	 * to a clicked*() method; the timer's alarm event is directed to
	 * the stopExam() method (via SwingUtilities.invokeLater()).
	 */
	protected void createEventHandlers() {

		getButtonFetch().addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				clickedFetch();
			}
		});

		getMenuItemFetch().addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				clickedFetch();
			}
		});

		getMenuItemExit().addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				clickedExit();
			}
		});
		getMenuItemHelpAbout().addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				clickedHelpAbout();
			}
		});
	}


   protected JMenuBar createClientMenuBar() {
		// Create menu bar
		JMenuBar jMenuBar = new JMenuBar();

		// Create menu
		JMenu jMenu = new JMenu("Actions");
		
		// Create menu items
		menuExit = new JMenuItem("Exit");
		menuExit.setMnemonic('x');

		menuFetch = new JMenuItem("Fetch Record");
		menuFetch.setMnemonic('f');

		// Add the menu items to the menus
		jMenu.add(menuFetch);
		jMenu.addSeparator();
		jMenu.add(menuExit);

		// Add the menus to the menu bar
		jMenuBar.add(jMenu);

		// Create help menu
		JMenu helpMenu = new JMenu("Help");
		// Create help menu items
		helpMenuAbout = new JMenuItem("About this application");
		helpMenuAbout.setMnemonic('a');

		// Add the help menu items to the menus
		helpMenu.add(helpMenuAbout);
		//Add the help menu to the menu bar 
		jMenuBar.add(helpMenu);

		return jMenuBar;
	}

	public void enableDisableListItems(boolean option) {
		getMenuItemExit().setEnabled(option);
		getMenuItemFetch().setEnabled(option);
		getMenuItemHelpAbout().setEnabled(option);
		getButtonFetch().setEnabled(option);
		getAccountNumberField().setEnabled(option);
	}

	// Get the fetch button
	protected JButton getButtonFetch() {
		return buttonFetch;
	}

	// Get the fetch menu item
	protected JMenuItem getMenuItemFetch() {
		return menuFetch;
	}

	// Get the Exit menu item
	protected JMenuItem getMenuItemExit() {
		return menuExit;
	}
	// Get the Help About menu item
	protected JMenuItem getMenuItemHelpAbout() {
		return helpMenuAbout;
	}

	protected JComboBox getAccountNumberField() {
		return accountNumberField;
	}

	// Creates and returns a panel for the a/c #, label, and entry field
	protected JPanel createFetchPanel() {
		JPanel jPanel = new JPanel();

		// Label for button
		JLabel accountNumberLabel = new JLabel("Enter account number: ", JLabel.RIGHT);

		// Create field for number entry + drop down for previous requests
		accountNumberField = new JComboBox();
		accountNumberField.setEditable(true);
		accountNumberField.setToolTipText("Enter an account number (19999 - 79999)");

		// Button with four images
		buttonFetch = new JButton(new ImageIcon("images/up.gif"));
		buttonFetch.setPressedIcon(new ImageIcon("images/down.gif"));
		buttonFetch.setRolloverIcon(new ImageIcon("images/rollover3.gif"));		
		buttonFetch.setDisabledIcon(new ImageIcon("images/disabled.gif"));
		buttonFetch.setToolTipText("Enter an account number (19999 - 79999)");
		
		// Turn off all borders 
		buttonFetch.setBorderPainted(false);
		buttonFetch.setFocusPainted(false);
		buttonFetch.setContentAreaFilled(false);

		// Add all to JPanel
		jPanel.add(accountNumberLabel);
		jPanel.add(accountNumberField);
		jPanel.add(buttonFetch);

		return jPanel;
	}

	// **********************************************************************
	// Creates and returns a JPanel suitable for displaying an account record
	// **********************************************************************
	protected JPanel createRecordPanel() {
		// *************************
		// Create the main JPanel...
		JPanel	jPanel = new JPanel(),

		// ... and the layout sub-JPanels
				topLeft = new JPanel(), topRight = new JPanel(),
				bottomLeft = new JPanel(), bottomRight = new JPanel();

		jPanel.setBorder(new EmptyBorder(borderSize, 0, borderSize, borderSize));

		topLeft.setBorder(new EmptyBorder(borderSize, borderSize, borderSize, borderSize));
		topRight.setBorder(new EmptyBorder(borderSize, borderSize, borderSize, borderSize));
		bottomLeft.setBorder(new EmptyBorder(borderSize, borderSize, borderSize, borderSize));
		bottomRight.setBorder(new EmptyBorder(borderSize, borderSize, borderSize, borderSize));

		Dimension d = new Dimension(400, 200);
		Dimension d1 = new Dimension(200, 200);

		topLeft.setPreferredSize(d1);
		topRight.setPreferredSize(d);
		bottomLeft.setPreferredSize(d1);
		bottomRight.setPreferredSize(d);


		titleField = new DisplayField(50, background);
		initialField = new DisplayField(50, background);
		fnameField = new DisplayField(100, background);
		surnameField = new DisplayField(100, background);
		address1Field = new DisplayField(100, background);
		address2Field = new DisplayField(100, background);
		address3Field = new DisplayField(100, background);
		phoneField = new DisplayField(50, background);
		others1Field = new DisplayField(100, background);
		others2Field = new DisplayField(50, background);
		others3Field = new DisplayField(50, background);
		others4Field = new DisplayField(50, background);
		noOfCardsField = new DisplayField(50, background);
		dateIssuedField = new DisplayField(100, background);
		reasonField = new DisplayField(50, background);
		cardCodeField = new DisplayField(50, background);
		approvedField = new DisplayField(70, background);
		special1Field = new DisplayField(50, background);
		special2Field = new DisplayField(50, background);
		special3Field = new DisplayField(50, background);
		acctStatusField = new DisplayField(50, background);
		chargeLimitField = new DisplayField(100, background);

		// ************************
		special1Field.setHorizontalAlignment(JLabel.CENTER);
		special2Field.setHorizontalAlignment(JLabel.CENTER);
		special3Field.setHorizontalAlignment(JLabel.CENTER);
		// ************************		

		// ***********
		// TABLE stuff
		// ***********

		// Create data model for a/c history table
		dataModel = new AccountHistoryTableModel();

		JTable tableView = new JTable(dataModel);

		// Retrieve the cell renderer for the table & force String entries to be centre aligned
		String s = new String();
		DefaultTableCellRenderer cellRenderer = (DefaultTableCellRenderer)tableView.getDefaultRenderer(s.getClass());
		cellRenderer.setHorizontalAlignment(JLabel.CENTER);

		// Use default background
		cellRenderer.setBackground(background);
	
		JScrollPane scrollpane = new JScrollPane(tableView);

		scrollpane.setPreferredSize(new Dimension(tableWidth, tableHeight));		
		
		others1Field.setMaximumSize(new Dimension(50, 50));



		// Create text labels
		JLabel	titleLabel = new JLabel("Title: ", JLabel.RIGHT),
				initialLabel = new JLabel("Initial: ", JLabel.RIGHT),
				surnameLabel = new JLabel("Surname: ", JLabel.RIGHT),
				fnameLabel = new JLabel("First name: ", JLabel.RIGHT),
				phoneLabel = new JLabel("Telephone: ", JLabel.RIGHT),
				addressLabel = new JLabel("Address: ", JLabel.RIGHT),
				othersLabel = new JLabel("Others Who May Charge: "),

				noOfCardsLabel = new JLabel("No. Cards Issued: ", JLabel.RIGHT),
				dateIssuedLabel = new JLabel("Date Issued: ", JLabel.RIGHT),
				reasonLabel = new JLabel("Reason: ", JLabel.RIGHT),
				cardCodeLabel = new JLabel("Card Code: ", JLabel.RIGHT),
				approvedLabel = new JLabel("Approved By: ", JLabel.RIGHT),
				specialLabel = new JLabel("Special Codes: ", JLabel.RIGHT),
				acctStatusLabel = new JLabel("Account Status: ", JLabel.RIGHT),
				chargeLimitLabel = new JLabel("Charge Limit: ", JLabel.RIGHT),
				acctHistoryLabel = new JLabel("Account History", JLabel.LEFT),

				padding1Label = new JLabel(""),
				padding2Label = new JLabel(""),
				padding3Label = new JLabel("");


		
		
		
		
		// ***********************
		// Address & personal info
		// ***********************
		GridLayout gridLeft = new GridLayout(8, 2);

		gridLeft.setVgap(verticalComponentGap);
		gridLeft.setHgap(horizontalComponentGap);
		topLeft.setLayout(gridLeft); 
		topLeft.add(titleLabel);
		topLeft.add(titleField);
		topLeft.add(initialLabel);
		topLeft.add(initialField);
		topLeft.add(fnameLabel);
		topLeft.add(fnameField);
		topLeft.add(surnameLabel);
		topLeft.add(surnameField);

		topLeft.add(addressLabel);
		topLeft.add(address1Field);
		
		topLeft.add(padding1Label);
		topLeft.add(address2Field);
		topLeft.add(padding2Label);
		topLeft.add(address3Field);
		topLeft.add(phoneLabel);
		topLeft.add(phoneField);


		// ***********************
		// Others who can charge
		// ***********************
		GridLayout gridRight = new GridLayout(8, 1);
		topRight.setLayout(gridRight);
		gridRight.setVgap(verticalComponentGap);
		gridRight.setHgap(horizontalComponentGap);

		topRight.add(othersLabel);
		topRight.add(others1Field);
		topRight.add(others2Field);
		topRight.add(others3Field);
		topRight.add(others4Field);


		// ***********************
		// Card details
		// ***********************
		GridLayout gridBottomLeft = new GridLayout(8, 2);
		bottomLeft.setLayout(gridBottomLeft);
		gridBottomLeft.setVgap(verticalComponentGap);
		gridBottomLeft.setHgap(horizontalComponentGap);

		bottomLeft.add(noOfCardsLabel);
		bottomLeft.add(noOfCardsField);

		bottomLeft.add(dateIssuedLabel);
		bottomLeft.add(dateIssuedField);

		bottomLeft.add(reasonLabel);
		bottomLeft.add(reasonField);

		bottomLeft.add(cardCodeLabel);
		bottomLeft.add(cardCodeField);

		bottomLeft.add(approvedLabel);
		bottomLeft.add(approvedField);

		JPanel specialP = new JPanel();
		specialP.setLayout(new GridLayout(1, 3));
		specialP.add(special1Field);
		specialP.add(special2Field);
		specialP.add(special3Field);

		bottomLeft.add(specialLabel);
		bottomLeft.add(specialP);

		bottomLeft.add(acctStatusLabel);
		bottomLeft.add(acctStatusField);

		bottomLeft.add(chargeLimitLabel);
		bottomLeft.add(chargeLimitField);
									
									 
		// ***********************		
		// Account History Table
		// ***********************
		bottomRight.add(acctHistoryLabel);
		bottomRight.add(scrollpane);


		// Master Layout
		GridLayout gLay = new GridLayout(2, 2);
		jPanel.setLayout(gLay);
		gLay.setVgap(verticalPanelGap);
		gLay.setHgap(horizontalPanelGap);
		jPanel.add(topLeft);
		jPanel.add(topRight);
		jPanel.add(bottomLeft);
		jPanel.add(bottomRight);
		
		//setPreferredSize(new Dimension(width, height));
		
		// Return the finished product
		return jPanel;
	}


	// Check the value of the a/c filed and return if appropriate
	public String getAccountNumber() {
		// Extract the text the user has either typed-in or selected from the list.
		String accountNumber = (String)getAccountNumberField().getSelectedItem();
		
		// Sift out entries not five chars in length
		if(accountNumber.length() != 5){
			return null;
		}
		else{
			// Check String for non-numeric characters
			for(int i=0; i < accountNumber.length(); i++){
				char c = accountNumber.charAt(i);
				int n = (int)c;
				if(n > 57 || n < 48){
					return null;
				}
				
			}
		}
		
		// Add legitimate selections to drop-down list if not already there
		boolean inList = false; 
		int elements = accountNumberField.getItemCount();
		for(int i=0; i < elements; i++){
			if(accountNumber.equals((String)accountNumberField.getItemAt(i)) == true){
				inList = true;;
			}
		}
		
		if(inList == false) accountNumberField.addItem(accountNumber);

		return accountNumber;
	}


	// Extracts info from AccountRecord object and writes to appropriate fields
	public void displayRecord(AccountRecord record) {
		titleField.setText(record.getTitle());
		initialField.setText(record.getInitial());
		fnameField.setText(record.getFName());
		surnameField.setText(record.getSName());
		address1Field.setText(record.getAddress1());
		address2Field.setText(record.getAddress2());
		address3Field.setText(record.getAddress3());
		phoneField.setText(record.getPhone());
		others1Field.setText(record.getAuthUser1());
		others2Field.setText(record.getAuthUser2());
		others3Field.setText(record.getAuthUser3());
		others4Field.setText(record.getAuthUser4());
		noOfCardsField.setText(record.getCards());
		dateIssuedField.setText(record.getDateIssued());
		reasonField.setText(record.getReason());
		cardCodeField.setText(record.getCardCode());
		approvedField.setText(record.getApprovedBy());
		special1Field.setText(record.getSpecialCode1());
		special2Field.setText(record.getSpecialCode2());
		special3Field.setText(record.getSpecialCode3());
		acctStatusField.setText(record.getStatus());
		chargeLimitField.setText(record.getLimit());
		setAccountHistory(record);
	}
	

	// Clears all fields
	public void clearDisplay() {
		titleField.setText("");
		initialField.setText("");
		fnameField.setText("");
		surnameField.setText("");
		address1Field.setText("");
		address2Field.setText("");
		address3Field.setText("");
		phoneField.setText("");
		others1Field.setText("");
		others2Field.setText("");
		others3Field.setText("");
		others4Field.setText("");
		noOfCardsField.setText("");
		dateIssuedField.setText("");
		reasonField.setText("");
		cardCodeField.setText("");
		approvedField.setText("");
		special1Field.setText("");
		special2Field.setText("");
		special3Field.setText("");
		acctStatusField.setText("");
		chargeLimitField.setText("");
		for(int i=0; i < 3; i++){
			for(int j=0; i < 5; j++){
				dataModel.setValueAt((Object)"", i, j);
			}
		}
	}

	// Fill in JTable entries
	private void setAccountHistory(AccountRecord record) {
		// Rerieve the account history object
		AccountHistory hist1 = record.getHistory1();
		AccountHistory hist2 = record.getHistory2();
		AccountHistory hist3 = record.getHistory3();

		// Create an array of objects to hold one row's worth of data
		Object[] newRow = new Object[5];

		newRow[0] = (Object) "Hello";
		newRow[1] = (Object) "I'm";
		newRow[2] = (Object) "Steve's";
		newRow[3] = (Object) "new";
		newRow[4] = (Object) "table!";

		dataModel.setValueAt((Object)hist1.balance(), 0, 0);
		dataModel.setValueAt((Object)hist1.billed(), 0, 1);
		dataModel.setValueAt((Object)hist1.amount1(), 0, 2);
		dataModel.setValueAt((Object)hist1.paid(), 0, 3);
		dataModel.setValueAt((Object)hist1.amount2(), 0, 4);

		dataModel.setValueAt((Object)hist2.balance(), 1, 0);
		dataModel.setValueAt((Object)hist2.billed(), 1, 1);
		dataModel.setValueAt((Object)hist2.amount1(), 1, 2);
		dataModel.setValueAt((Object)hist2.paid(), 1, 3);
		dataModel.setValueAt((Object)hist2.amount2(), 1, 4);

		dataModel.setValueAt((Object)hist3.balance(), 2, 0);
		dataModel.setValueAt((Object)hist3.billed(), 2, 1);
		dataModel.setValueAt((Object)hist3.amount1(), 2, 2);
		dataModel.setValueAt((Object)hist3.paid(), 2, 3);
		dataModel.setValueAt((Object)hist3.amount2(), 2, 4);

		Object o = (Object) hist1.balance(); // 		data[6] = new Integer(size(m));
		System.out.println("H1 balance = " + o.toString());
	}


	public void fillInDetails(String details) {
		// Check that the correct size buffer has been passed
		if(details.length() != recordLength){
			System.err.println("Invalid record length - closing application");
			System.exit(1);
		}
	}


	public void clickedAbout() {
		if(aboutDialog == null) createAboutDialog();

		if(aboutDialog.isShowing()) aboutDialog.setVisible(false);
		else aboutDialog.setVisible(true);
	}


	protected void createAboutDialog() {
		aboutDialog = new JDialog(this, "About \"Account Demo\"", true);

		aboutDialog.setSize(aboutWidth, aboutHeight);

		JTextArea text = new JTextArea(5, 40);
		text.setText(aboutText);
		text.setEditable(false);
		text.setLineWrap(true);
		text.setWrapStyleWord(true);
		JScrollPane textPane = new JScrollPane(text);

		JButton OK = new JButton("OK");
		OK.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				aboutDialog.dispose();
			}
		});
		OK.setMnemonic('o');
		
		aboutDialog.getContentPane().setLayout(new BorderLayout());
		aboutDialog.getContentPane().add("Center", textPane);
		aboutDialog.getContentPane().add("South", OK);
		
		aboutDialog.setLocation(aboutXpos, aboutYpos);	// Must work-out screen max & pos in relative middle

	}


	public static void main (String[] args) throws Exception {
		if(args.length != 5){
			print("Wrong number of arguments.\nUSAGE:\njava MQClient Hostname " +
				 "Channel QManager RequestQueue ReplyQueue");
			System.exit(0);
		}
		else print("Arguments:\n" + args[0] + "\n" + args[1] + "\n" + args[2] + "\n" + args[3] + "\n" + args[4]);
		try {
			new MQClient(args);
		}catch(Exception e){
			e.printStackTrace();
		}
	}


}	// Class Ends