
/**
* 
* dbBrowser
*
* sanjay sthapit, 5/98
*
*/	 

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.awt.Color;
import java.util.Vector;
import java.util.*;
import com.sun.java.swing.*;
import com.sun.java.swing.table.*;
import com.sun.java.swing.event.*;
import com.sun.java.swing.border.*;
import java.sql.*;

public class dbBrowser implements LayoutManager {
    static String[] ConnectOptionNames = { "Connect" };
    static String   ConnectTitle = "Connection Information";

    Dimension   origin = new Dimension(0, 0);

    TableSorter sorter;
    JDBCAdapter dataBase;

	int			myColumnCount;
	String		lastSelect;

	JMenuBar	mb;
	JMenu		file_m;
   	JMenuItem	exit_mi;
   	JMenuItem	new_mi;
	JMenu		table_m;
   	JMenuItem	table_mi[];
	JMenuItem	clrTable;
	JMenuItem	newRow;
	JMenuItem	delRow;


	// connection dialog box components
    JPanel      connectionPanel;
	JLabel      userNameLabel;
    JTextField  userNameField;
    JLabel      passwordLabel;
    JTextField  passwordField;
    JTextArea   queryTextArea;
    JComponent  queryAggregate;
    JLabel      serverLabel;
    JTextField  serverField;
    JLabel      driverLabel;
    JTextField  driverField;

	// man db browser components
	int			maxCols = 20;
    JPanel      mainPanel;
    JButton     fetchButton;
    JButton     showConnectionInfoButton;
    JFrame      frame; // The query/results window.
	JTable		tableView;
    JScrollPane tableAggregate;
	JLabel		tableChoiceLabel;
	JComboBox	tableChoice;
	JButton		selButton;
	JButton		insButton;
	JButton		delButton;
	JButton		updButton;
	JButton		clrButton;
	JComboBox	colVal[]	= new JComboBox[maxCols];
	JCheckBox	colChoice[]	= new JCheckBox[maxCols];
	JTextArea	messageArea;					  
    JScrollPane messageAggregate;

	JTabbedPane	qTab;
	qConstruct	qCon;



    /**
     * Brigs up a JDialog using JOptionPane containing the connectionPanel.
     * If the user clicks on the 'Connect' button the connection is reset.
     */
    void activateConnectionDialog() {
		if(JOptionPane.showOptionDialog(tableAggregate, connectionPanel, ConnectTitle,
			JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE,
			null, ConnectOptionNames, ConnectOptionNames[0]) == 0) {
				msg("\n\n   *** DB URL = " + serverField.getText() + " ***\n");
				connect();
				frame.setTitle("dbBrowser - " + serverField.getText());
				frame.setVisible(true);
			}
		else if(!frame.isVisible())
		    System.exit(0);
	}


	// 
	// create connection dialog box for connection to db
	//
    public void createConnectionDialog() {
		// Create the labels and text fields.
		userNameLabel = new JLabel("User name: ", JLabel.RIGHT);
 		userNameField = new JTextField("guest");

		passwordLabel = new JLabel("Password: ", JLabel.RIGHT);
		passwordField = new JTextField("");
	
	    serverLabel = new JLabel("Database URL: ", JLabel.RIGHT);
		serverField = new JTextField("jdbc:odbc:northwind");

		driverLabel = new JLabel("Driver: ", JLabel.RIGHT);
		driverField = new JTextField("sun.jdbc.odbc.JdbcOdbcDriver");


		connectionPanel = new JPanel(false);
		connectionPanel.setLayout(new BoxLayout(connectionPanel,BoxLayout.X_AXIS));

		JPanel namePanel = new JPanel(false);
		namePanel.setLayout(new GridLayout(0, 1));
		namePanel.add(userNameLabel);
		namePanel.add(passwordLabel);
		namePanel.add(serverLabel);
		namePanel.add(driverLabel);

		JPanel fieldPanel = new JPanel(false);
		fieldPanel.setLayout(new GridLayout(0, 1));
		fieldPanel.add(userNameField);
		fieldPanel.add(passwordField);
		fieldPanel.add(serverField);
        fieldPanel.add(driverField);

		connectionPanel.add(namePanel);
		connectionPanel.add(fieldPanel);
    }


	//
	// construct browser
	//
    public dbBrowser() {
		createConnectionDialog();
		
        buildMenuBar();
		buildTable();
		buildSimpleQ();												   
		buildMessageArea();												   
		buildQTab();										   
		buildMainPanel();

        // Create a Frame and put the main panel in it.
        frame = new JFrame("dbBrowser");
        frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
        frame.setBackground(Color.lightGray);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setVisible(false);
        frame.setBounds(200, 50, 800, 900);
        frame.setJMenuBar(mb);
	
		activateConnectionDialog();
    }


	// --------------------------------------------------------
	//       *** listeners for events to components ***
	// --------------------------------------------------------

    class QueryChangeListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
            //fetch();
		}
    }
	
    class colValListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
            // dummy. strange things happen if action listener
			// not specified

			// note: strange things STILL happen!!
		}
    }
	
	// action for select button
    class selButtonListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			int selColCount = 0;
			int qualCount	= 0;
			String desCols	= "";
			String desQuals	= "";
			String myQuery	= "";

			for (int i = 0; i < myColumnCount; i++) {
				// add the checked columns to query
				if (colChoice[i].isSelected()) {
					if (selColCount == 0)
						desCols = dataBase.getColumnName(i);
					else
						desCols = desCols + ", " + dataBase.getColumnName(i);
					selColCount++;
				}

				// add the entered filters to query
				String mytemp = colVal[i].getSelectedItem().toString();

				if (mytemp == "(any/all)") {
					if (qualCount == 0)
						desQuals = dataBase.getColumnName(i) + " = *";
					else
						desQuals = " and " + dataBase.getColumnName(i) + " = *";
					qualCount++;
				}
				else if (mytemp != null && mytemp != " " && mytemp != "") {
					if (qualCount == 0)
						desQuals = dataBase.getColumnName(i) + " = " +
								   dataBase.dbRepresentation(i,colVal[i].getSelectedItem());
					else
						desQuals = desQuals + " and " + dataBase.getColumnName(i) +
								   " = " + dataBase.dbRepresentation(i,colVal[i].getSelectedItem());
					qualCount++;
				}
			}
			// if no column checked, select all columns
			if (selColCount < 1)
				desCols = "*";

			myQuery = "SELECT " + desCols + " FROM \"" + tableChoice.getSelectedItem() + "\"";
			// add filters if any
			if (qualCount > 0) 
				myQuery = myQuery + " WHERE " + desQuals;
			fetch(myQuery);
		}
    }
	
	// action for insert button
    class insButtonListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			int		selColCount = 0;
			String	desCols		= "";
			String	desVals		= "";
			String	myQuery		= "";

			for (int i = 0; i < myColumnCount; i++) {
				String mytemp = colVal[i].getSelectedItem().toString();

				if (mytemp != null && mytemp != " " && mytemp != "") {
					if (selColCount == 0) {
						desCols = dataBase.getColumnName(i);
						desVals = dataBase.dbRepresentation(i,colVal[i].getSelectedItem());
					}
					else {
						desCols = desCols + ", " + dataBase.getColumnName(i);
						desVals = desVals + ", " + 
								  dataBase.dbRepresentation(i,colVal[i].getSelectedItem());
					}
					selColCount++;
				}
			}

			if (selColCount < 1) {
				msg("dbBrowser error: at least one column must be filled to insert");
				return;
			}

			myQuery = "INSERT INTO \"" + tableChoice.getSelectedItem() + "\" ("
						+ desCols + ") VALUES (" + desVals + ")";
			fetch(myQuery);
			fetch(lastSelect);
			fillColumnChoices();
		}
    }

	// action for delete button
    class delButtonListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			int		selColCount = 0;
			String	desCols		= "";
			String	myQuery		= "";

			for (int i = 0; i < myColumnCount; i++) {
				String mytemp = colVal[i].getSelectedItem().toString();

				if (mytemp != null && mytemp != " " && mytemp != "") {
					if (selColCount == 0) {
						desCols = dataBase.getColumnName(i) + "= " 
									+ dataBase.dbRepresentation(i,colVal[i].getSelectedItem());
					}
					else {
						desCols = desCols + "and " + dataBase.getColumnName(i) 	+ " = " + 
								  dataBase.dbRepresentation(i,colVal[i].getSelectedItem());
					}
					selColCount++;
				}
			}

			if (selColCount < 1) {
				msg("dbBrowser error: at least one column must be filled to delete");
				return;
			}

			myQuery = "DELETE FROM \"" + tableChoice.getSelectedItem() 
						+ "\" WHERE " + desCols;
			fetch(myQuery);
			fetch(lastSelect);
			fillColumnChoices();
		}
    }

	// action for update button
    class updButtonListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			int selColCount = 0;
			int qualCount	= 0;
			String desCols	= "";
			String desQuals	= "";
			String myQuery	= "";

			for (int i = 0; i < myColumnCount; i++) {
				// add the checked columns to query
				if (colChoice[i].isSelected()) {
					if (selColCount == 0)
						desCols = dataBase.getColumnName(i) + 
									" = " +
									dataBase.dbRepresentation(i,colVal[i].getSelectedItem());
					else
						desCols = desCols + ", " + 
									dataBase.getColumnName(i) +
									" = " +
									dataBase.dbRepresentation(i,colVal[i].getSelectedItem());
;
					selColCount++;
				}

				else {
					// add the entered filters to query
					String mytemp = colVal[i].getSelectedItem().toString();

					if (mytemp == "(any/all)") {
						if (qualCount == 0)
							desQuals = dataBase.getColumnName(i) + " = *";
						else
						desQuals = " and " + dataBase.getColumnName(i) + " = *";
						qualCount++;
					}
					else if (mytemp != null && mytemp != " " && mytemp != "") {
						if (qualCount == 0)
							desQuals = dataBase.getColumnName(i) + " = " + 
										dataBase.dbRepresentation(i,colVal[i].getSelectedItem());
						else
							desQuals = desQuals + " and " + dataBase.getColumnName(i) + " = " + 
									dataBase.dbRepresentation(i,colVal[i].getSelectedItem());
						qualCount++;
					}
				}
			}
			// if no column checked, select all columns
			if (selColCount < 1) {
				msg("dbBrowser error: no column marked for update");
				return;
			}

			myQuery = "UPDATE \"" + tableChoice.getSelectedItem() + 
						"\" SET " + desCols;
			// add filters if any
			if (qualCount > 0) 
				myQuery = myQuery + " WHERE " + desQuals;
			msg(myQuery);
			fetch(myQuery);
			fetch(lastSelect);
			fillColumnChoices();
		}
    }
	
	// action for clear button
    class clrButtonListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			fillColumnChoices();
		}
    }
	
	// action for new table selection
	class TableChangeListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
            if (e.getActionCommand() == "comboBoxChanged" && 
				tableChoice.getSelectedItem() != null) {
				// view table and update column checkboxes and combo boxes
				String myquery = "SELECT * from \"" + tableChoice.getSelectedItem() + "\"";
				fetch(myquery);
				tableChoiceLabel.setText(tableChoice.getSelectedItem().toString());
				dataBase.currentTable = tableChoice.getSelectedItem().toString();
				fillColumnChoices();
			}
		}
    }


	// action for menu items
	class MenuListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			// msg("\"" + e.getActionCommand() + "\" action detected in menu\"");

			if (e.getActionCommand() == "new_dbase") {
				try {
					dataBase.close();
					clearColumnChoices();
					activateConnectionDialog();
				}
				catch (SQLException ex) {
					msg(ex.toString());
				}
			}

			else if (e.getActionCommand() == "exit") {
				try {
				   dataBase.close();			
				   System.out.println("dbBrowser done.");					   
				   System.exit(0);
				}
				catch (SQLException ex) {
					msg(ex.toString());
				}
			}

			else if (e.getActionCommand() == "newRow") {
				int cnt = dataBase.getColumnCount();
				ResultSetMetaData mdata;
				
				try {
					mdata = dataBase.resultSet.getMetaData();

					for (int i = 0; i < cnt; i++) {
						if (mdata.isNullable(i+1) > 0) {
							String myquery = "INSERT INTO " +
											  tableChoice.getSelectedItem().toString() +
											  "(" + dataBase.getColumnName(i) + 
											  ") VALUES(null)";
							fetch(myquery);
							fetch(lastSelect);
							return;
						}
					}
					msg("dbBrowser error: no columns nullable");
				} 
				catch (SQLException ex) {
					msg(ex.toString());
				}
			}

			else if (e.getActionCommand() == "delRow") {
				int rowCnt		= tableView.getSelectedRowCount();
				int selRow[]	= tableView.getSelectedRows();
				int colCnt		= dataBase.getColumnCount();
				String tableName= tableChoice.getSelectedItem().toString();

				for (int i = 0; i < rowCnt; i++) { 													
					String myquery = "DELETE FROM \"" + tableName + "\" WHERE ";
					// We don't have a model of the schema so we don't know the
					// primary keys or which columns to lock on.we'll just lock 
					// on everything.
					for(int col = 0; col<dataBase.getColumnCount(); col++) {
						String colName = dataBase.getColumnName(col);
						if (colName.equals("")) { 
							continue;
						}
						if (col != 0) {
							myquery = myquery + " AND ";
						}
						myquery = myquery + colName +" = "+
							dataBase.dbRepresentation(col, dataBase.getValueAt(selRow[i], col));
					}
					fetch(myquery);
				}
				fetch(lastSelect);
				fillColumnChoices();
			}

			else if (e.getActionCommand() == "clrTable") {
				String tableName= tableChoice.getSelectedItem().toString();

				fetch("SELECT * from \"" + tableName + "\"");
			}

			else if (e.getActionCommand() != null) {
				// table changed
				// hack alert!! 
				// this changes the tableChoice combo box to the right thing
				// which does the rest
				int tempCount = tableChoice.getItemCount();
				for (int i = 0; i < tempCount; i++) {
					if (e.getActionCommand() == tableChoice.getItemAt(i).toString())
						tableChoice.setSelectedIndex(i);
				}
			}

		}
    }


 	// --------------------------------------------------------
	//       *** db methods ***
	// --------------------------------------------------------

	 public void connect() {
       dataBase = new JDBCAdapter(serverField.getText(),
									driverField.getText(),
									userNameField.getText(),
									passwordField.getText(),
									this);
       sorter.setModel(dataBase);
	   buildTableMenu();
	}

    public void fetch(String myquery) {
		// save the last select for clears
		if (myquery.regionMatches(true, 0, "SELECT", 0, 6))
			lastSelect = myquery;
		msg(myquery);
		dataBase.executeQuery(myquery);
        // dataBase.executeQuery(queryTextArea.getText());
    }


	// --------------------------------------------------------
	//       *** self-defined component creators ***
	// --------------------------------------------------------

	public void buildSimpleQ() {
 		// table choice list box
		tableChoiceLabel	= new JLabel("TABLE", JLabel.CENTER);
		tableChoiceLabel.setForeground(Color.blue);
		tableChoice			= new JComboBox();
		tableChoice.setBackground(Color.yellow);
        tableChoice.addActionListener(new TableChangeListener());

		// query buttons
		selButton	= new JButton("Select");
		selButton.setBorder(new BevelBorder(BevelBorder.RAISED));
        selButton.addActionListener(new selButtonListener());
		insButton	= new JButton("Insert");
		insButton.setBorder(new BevelBorder(BevelBorder.RAISED));
        insButton.addActionListener(new insButtonListener());
		delButton	= new JButton("Delete");
		delButton.setBorder(new BevelBorder(BevelBorder.RAISED));
        delButton.addActionListener(new delButtonListener());
		updButton	= new JButton("Update");
		updButton.setBorder(new BevelBorder(BevelBorder.RAISED));
        updButton.addActionListener(new updButtonListener());
		clrButton	= new JButton("Clear");
		clrButton.setBorder(new BevelBorder(BevelBorder.RAISED));
        clrButton.addActionListener(new clrButtonListener());

		// column choice components
		for (int i = 0; i < maxCols; i++) {
			colChoice[i]	= new JCheckBox("Column " + (i+1));
			colVal[i]		= new JComboBox();
			colChoice[i].setEnabled(false);
			colVal[i].setBackground(Color.white);
			colVal[i].setEditable(true);
			colVal[i].setEnabled(false);
			colVal[i].addActionListener(new colValListener());
		}
	}


	public void buildMessageArea() {
		// message display area
		messageArea	= new JTextArea("Messages from browser...\n", 50, 50);
		messageArea.setEditable(false);
		messageArea.setBackground(Color.cyan);
		messageAggregate = new JScrollPane(messageArea);
		messageAggregate.setBorder(new LineBorder(Color.black));
	}


	public void buildQTab() {
		qTab = new JTabbedPane();
		qCon = new qConstruct(this);
		qTab.addTab("Query", null, qCon.qPan1, "fire query");
		qTab.addTab("Columns", null, qCon.qPan2, "specify columns");
		qTab.addTab("Filters", null, qCon.qPan3, "filter query");
	}


	public void buildMainPanel() {
		// panel that contains all components
        mainPanel = new JPanel();

		// add all components to the main panel.
        // mainPanel.add(fetchButton);
        // mainPanel.add(showConnectionInfoButton);
        // mainPanel.add(queryAggregate);
		mainPanel.add(tableChoiceLabel);
		// mainPanel.add(tableChoice);
		mainPanel.add(selButton);
		mainPanel.add(insButton);
		mainPanel.add(delButton);
		mainPanel.add(updButton);
		mainPanel.add(clrButton);
		for (int i = 0; i < maxCols; i++) {
			mainPanel.add(colVal[i]);
			mainPanel.add(colChoice[i]);
		}
        mainPanel.add(qTab);
        mainPanel.add(tableAggregate);
		mainPanel.add(messageAggregate);
        mainPanel.setLayout(this);
	}


	public void buildTable() { 
        sorter = new TableSorter(this);

        // Create the table
        tableView = new JTable(sorter);

        // Install a mouse listener in the TableHeader as the sorter UI.
        sorter.addMouseListenerToHeaderInTable(tableView);
		
		tableAggregate = JTable.createScrollPaneForTable(tableView);
        tableAggregate.setBorder(new BevelBorder(BevelBorder.LOWERED));
    }


	// build table menu
	public void buildTableMenu()
	{
	   Vector	tableNames		= dataBase.getTableNames(null, null, dataBase.getTableTypes());
	   int		tableNamesCount	= tableNames.size();

	   // build table menu
	   table_m.removeAll();
	   tableChoice.removeAllItems();

	   clrTable	= new JMenuItem("Clear Table");
	   clrTable.setActionCommand("clrTable");
	   clrTable.addActionListener(new MenuListener());
	   table_m.add(clrTable);

	   newRow	= new JMenuItem("Insert row");
	   newRow.setActionCommand("newRow");
	   newRow.addActionListener(new MenuListener());
	   table_m.add(newRow);

	   delRow	= new JMenuItem("Delete row(s)");
	   delRow.setActionCommand("delRow");
	   delRow.addActionListener(new MenuListener());
	   table_m.add(delRow);

	   table_m.addSeparator();

	   table_mi = new JMenuItem[tableNamesCount];
	   for (int i = 0; i < tableNamesCount; i++) {
		   tableChoice.addItem(tableNames.elementAt(i));
		   table_mi[i] = new JMenuItem(tableNames.elementAt(i).toString());
		   table_mi[i].addActionListener(new MenuListener());
		   table_m.add(table_mi[i]);
	   }
	}


	// build menu bar
    public void buildMenuBar()
	{
		mb = new JMenuBar();

		// ** file menu	**
		file_m = new JMenu("File", true);
		mb.add(file_m);
		new_mi = new JMenuItem("Database...");
		file_m.add(new_mi);
		file_m.addSeparator();
		exit_mi = new JMenuItem("Exit");
		file_m.add(exit_mi);
		//Set action commands for a few menu items.
		new_mi.setActionCommand("new_dbase");
		exit_mi.setActionCommand("exit");
		//Register as an ActionListener for all menu items.
		new_mi.addActionListener(new MenuListener());
		exit_mi.addActionListener(new MenuListener());

		// ** table menu **
		table_m = new JMenu("Table", true);
		mb.add(table_m);
	}


	// --------------------------------------------------------
	//                     *** misc ***
	// --------------------------------------------------------

	public void msg(String message) {
		messageArea.append(message + "\n");
	}

	public void clearColumnChoices() {
		// re-init all column choices
		for (int i = 0; i < maxCols; i++) {
			colChoice[i].setText("Column " + (i+1));
			colVal[i].removeAllItems();
			colChoice[i].setEnabled(false);
			colVal[i].setEnabled(false);
		}
	}

	public void fillColumnChoices() {
		clearColumnChoices();

		// fill in appropriate column choices
		myColumnCount = dataBase.getColumnCount();
		if (myColumnCount > maxCols)
			myColumnCount = maxCols;
		int myrowCount = dataBase.getRowCount();
		Object temp;
		for (int i = 0; i < myColumnCount; i++) {
			colChoice[i].setText(dataBase.getColumnName(i));
			colChoice[i].setEnabled(true);
			colVal[i].addItem(" ");
			colVal[i].addItem("(any/all)");

			for (int j = 0; j < myrowCount; j++) {
				int myflag = 0;
				temp = dataBase.getValueAt(j, i);
				for (int k = 0; k < colVal[i].getItemCount(); k++) {
					if (temp.equals(null) || temp.equals(colVal[i].getItemAt(k)))
						myflag = 1;
				}
				if (myflag == 0)
					colVal[i].addItem(temp);
			}

			colVal[i].setEnabled(true);
			colChoice[i].setSelected(false);
			colVal[i].setSelectedIndex(0);
		}
	}


	// --------------------------------------------------------
	//       *** placement of components in browser ***
	// --------------------------------------------------------

    public Dimension preferredLayoutSize(Container c){return origin;}

    public Dimension minimumLayoutSize(Container c){return origin;}
    
	public void addLayoutComponent(String s, Component c) {}
    
	public void removeLayoutComponent(Component c) {}
    
	public void layoutContainer(Container c) {
        Rectangle b		= c.getBounds();
        int inset		= 4;
        int topHeight	= inset;

        // showConnectionInfoButton.setBounds(b.width-2*inset-120, inset, 120, 25);
        // fetchButton.setBounds(b.width-2*inset-120, 60, 120, 25);

        // queryAggregate.setBounds(inset, inset, b.width-2*inset - 150, 80);

		int topHeight2 = topHeight;

		// tableChoice
		int tbcW = 120;
		int tbcH = 25;
		tableChoiceLabel.setBounds(inset, topHeight, tbcW, tbcH);
		topHeight += tbcH + 5;
		// tableChoice.setBounds(inset, inset + topHeight, tbcW, tbcH);
		// topHeight += tbcH + 5;

		// query buttons
		int bW	= (int) tbcW/2;
		int bH	= 20;
		selButton.setBounds(inset + (int)(tbcW/4), inset + topHeight, bW, bH);
		topHeight += bH + inset;
		insButton.setBounds(inset + (int)(tbcW/4), inset + topHeight, bW, bH);
		topHeight += bH + inset; 
		delButton.setBounds(inset + (int)(tbcW/4), inset + topHeight, bW, bH);
		topHeight += bH + inset;											  
		updButton.setBounds(inset + (int)(tbcW/4), inset + topHeight, bW, bH);
		topHeight += bH + inset;
		topHeight += 10 + inset;
		clrButton.setBounds(inset + (int)(tbcW/4), inset + topHeight, bW, bH);
		topHeight += bH + 20;

		// column choice checkboxes and combo boxes
		int myindex;
		int ccW		= 125;
		int ccH		= 20;
		int xoffset = b.width - 5*(ccW + inset);

		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 5; j++) {
				myindex = i*5 + j;
				colChoice[myindex].setBounds(xoffset + j*(ccW + inset), 
											 inset + topHeight2,
											 ccW, 
											 ccH);
				colVal[myindex].setBounds(xoffset + j*(ccW + inset), 
										  inset + topHeight2 + ccH,
										  ccW, 
										  ccH);
			}
			topHeight2 += 2*ccH + inset;
		}

		// query constructor
		int qtH = 200;
        qTab.setBounds(new Rectangle(inset,
                                     inset + topHeight,
                                     b.width-2*inset,
                                     qtH));
		topHeight += qtH + 10;

		// results table
		int rtH = b.height - 3*inset - topHeight - 75;
        tableAggregate.setBounds(new Rectangle(inset,
                                               inset + topHeight,
                                               b.width-2*inset,
                                               rtH));
		topHeight += rtH + 10;

		// messages display panel
		messageAggregate.setBounds(inset, inset + topHeight, 
							  b.width-2*inset, b.height - topHeight - 2*inset);
    }

}

