/* Title:		OperationDlg.java
 * Version	
 * Author		Sada
 * Company: USDA-ARS
 * Date:    July, 2003
 * Description: OperationDlg screen displays the values of all parameters of the selected operation.
 * Paramter values can also be modified from here. Also, modified values can be saved as a new operation.
 * 
 */
package usda.weru.mcrew;

import com.klg.jclass.cell.JCCellInfo;
import java.awt.*;
import java.awt.event.*;
import de.schlichtherle.io.File;
import javax.swing.*;
import java.util.*;

import com.klg.jclass.cell.editors.*;
import com.klg.jclass.cell.renderers.*;
import com.klg.jclass.table.*;
import com.klg.jclass.table.data.*;
import javax.help.CSH;
import javax.help.HelpBroker;
import javax.help.HelpSet;

import usda.weru.util.*;
import usda.weru.weps.fuel.Fuel;
import usda.weru.weps.fuel.FuelChooser;

/**
 * OperationDlg screen displays the values of all parameters of the selected operation.
 * Paramter values can also be modified from here. Also, modified values can be saved as
 * a new operation.
 */
public class OperationDlg extends usda.weru.mcrew.gui.OperationDlg_n {

    static final int MIN_WIDTH = 820;
    static final int MIN_HEIGHT = 600;
    int sideOffset = 10;
    int componentOffSet = 5;
    Hashtable<String, String> c_tooltipTable;
    private JList mProcessGroupList;
    //DefaultListModel mNameListModel;
    DefaultListModel mIdListModel; // even though (presently) only action names are put in the JList, the corresponding 
    // identities are stored in mIdListModel for faster access to the appropriate actions.
    Vector mActions;
    int mSelectedIndex, mAdditionalIndex, listOffsetIndex;
    Identity mSelectedIdentity, mAdditionalIdentity;
    OperationObject mOprnObj; // holds a copy (clone) of Operation Object passed to the constructor
    OperationObject mOriginalOprn; // Holds the operation object passed. This is updated only if user clicks OK.
    String mOperationActionName;
    ActionJCTable mOperationTable, mMiddleTable, mLowerTable;
    /* The mOperationTable is fixed i.e. it always shows the operation parameter and is placed in the UpperPanel. */
    /**
     * This is the default group that is selected when the operation dialog screen appears.
     */
    public static final int kDefaultSelection = 0;
    /**
     * The foreground color of the text in each of the cells in operaation dialog tables.
     */
//    public static Color SelectedForegroundColor = Color.black;
    /**
     * The 
     */
//    public static Color SecondaryForegroundColor = Color.black;
    /**
     * The background color that shows selected rows in the tables and the process
     * list in the text area of an operation dialog.
     */
//    public static Color SelectedBackgroundColor = Color.blue;
    /**
     * The background color that shows selected group for a process in the text area
     * of an operation dialog.
     */
//    public static Color SecondaryBackgroundColor = Color.lightGray;
    /**
     * The foreground color of the text in each of the cells in operaation dialog tables.
     */
//    public static Color ForegroundColor = Color.black;
    /**
     * The background color of the cells in which the text is to be entered in various 
     * rows of the operation dialog table.
     */
//    public static Color BackGroundColor = Color.white;
    /**
     * String that separates the process or group Id from the actual value that is 
     * visible in the text area of the operation dialog.
     */
    public static final String sIdNameSeparator = ":";
    /**
     * String that indicates if there are no actions available.
     */
    public static final String sNoAction = "No Action";
    /**
     * String that shows the parameters that are associated with a group.
     */
    public static final String sGroupParameters = "Groups Parameters  ";
    /**
     * String that shows the parameters that are associated with a process.
     */
    public static final String sProcessParameters = "Process Parameters  ";
    /**
     * The parameters that are used for selecting the objects to be viewed in bottom 
     * panel i:e the process panel
     */
    public static final String sSelectionParameters = "Selection Parameters  ";
    /**
     * Indicates whether the data in any of the three tables of operation panels
     * has been changed. Set to true if changed else false.
     */
    protected boolean dataChanged = false;
    /**
     * Flag that indicates if the data in the notes of the Operation Drill Down Screen was
     * changed which helps in saving the values in the underlying datastructure - neha
     */
    protected boolean notesDataChanged = false;
    ManageData c_manage;
    RowInfo c_row;

    /**
     * Three argument constructor that needs the pointer to a frame in which it is
     * to be displayed, the operation object that hold the operation data together,
     * and the date string.
     * @param f The frame object in which the GUI is displayed.
     * @param pOprnObj The operation object that holds all the information to be
     * displayed in the operation dialog GUI.
     * @param pDate The date string to be set for the datefield.
     */
    public OperationDlg(java.awt.Frame f, OperationObject pOprnObj, String pDate, ManageData manage, RowInfo row) {
        super(f);
        c_manage = manage;
        c_row = row;
        //mNameListModel = new DefaultListModel();
        mOriginalOprn = pOprnObj;
//		mOprnObj = (OperationObject)mOriginalOprn.clone();
        mOprnObj = (OperationObject) mOriginalOprn;

        mIdListModel = new DefaultListModel(); // identities are converted to Actionnames in cellRenderer() functions

        JTF_operationName.setText(pOprnObj.getOperationName());
        JTF_date.setText(pDate);

        mOperationTable = new ActionJCTable(this);
        mMiddleTable = new ActionJCTable(this);
        mLowerTable = new ActionJCTable(this);

        //Intialize these booleans to false. Since they are static variables
        //their values will persist between different instantiations of OperationDlg
        //till Weps is closed - neha
        dataChanged = false;
        notesDataChanged = false;

        initialize();

        mProcessGroupList = new JList(mIdListModel);
        mProcessGroupList.setSelectedIndex(kDefaultSelection);
        mSelectedIndex = kDefaultSelection;
        mSelectedIdentity = (Identity) mIdListModel.get(mSelectedIndex); // set 0th item as default selected
        setAllSelections();

        mProcessGroupList.addMouseListener(new ListMouseAdapter());
        mProcessGroupList.setCellRenderer(new CustomCellRenderer());

        JSP_list.getViewport().setView(mProcessGroupList);

        //OperationParamPanel.add(mOperationTable);
        JSP_upperParam.getViewport().setView(mOperationTable);
        JSP_middleParam.getViewport().setView(mMiddleTable);
        JSP_lowerParam.getViewport().setView(mLowerTable);

        showTables();
        //setSize(700,500);
        //pack();
        //Set the tool tip help to be taken from this file
        Util.loadToolTips((Container) this, new File("mcrew_cfg", "mcrewtooltips.cfg"));
    }

    /**
     * This method initialises the operation table data with the meta data that is 
     * associated with identities as keys to the respective objects e:g Action objects 
     * or datastructures that hold these objects.
     */
    public void initialize() {
        int ListModelIndex = 0;

        mActions = mOprnObj.getAllActions();
        Vector mActionIdVec = mOprnObj.getAllIds();

        for (int i = 0; i < mActionIdVec.size(); i++) {

            Identity identity = (Identity) mActionIdVec.get(i);
            Action action = (Action) mActions.get(i);

            if (action.isOperation()) {
                mOperationTable.setData(action);

                mOperationActionName = identity.toString() + sIdNameSeparator + action.getActionName();
                JL_OperationAction.setText(mOperationActionName);
                listOffsetIndex++;  // Operation action not added to display list, so increment offset counter

                continue; // Theres no need to add Operation action into ProcessGroup action JList
            }

            //mNameListModel.add(ListModelIndex, actionName + "("+ identity.toString() + ")");
            mIdListModel.add(ListModelIndex, identity);
            ListModelIndex++;
        }

        c_tooltipTable = Util.loadToolTipsTable(new File("mcrew_cfg", "mcrewtooltips.cfg"));

        addHelp();


    }

    private void addHelp() {
        addCSH(Help.getHelpSet());
    } //end of addhelp()

    private void addCSH(HelpSet hs) {
        HelpBroker hb = hs.createHelpBroker();


        hb.enableHelpKey(getRootPane(), "operation_intro_html", hs);


        JB_help.addActionListener(new CSH.DisplayHelpAfterTracking(hs, "javax.help.Popup", null));

        //Add help ids to the components
        //CSH.setHelpIDString(JTP_main, "crop_drill_table_html");

        CSH.setHelpIDString(JTF_operationName, "operation_drill_operationname_html");
        CSH.setHelpIDString(operationNameLabel, "operation_drill_operationname_html");
        CSH.setHelpIDString(JP_toolbar, "operation_drill_toolbar_html");
        CSH.setHelpIDString(JP_upper, "operation_drill_operationparameters_html");
        CSH.setHelpIDString(JP_middle, "operation_drill_groupparameters_html");
        CSH.setHelpIDString(JP_lower, "operation_drill_processparameters_html");
        CSH.setHelpIDString(JTF_date, "operation_drill_date_html");
        CSH.setHelpIDString(JL_Date, "operation_drill_date_html");
        CSH.setHelpIDString(JLabel1, "operation_drill_list_html");
        CSH.setHelpIDString(JSP_list, "operation_drill_list_html");


        CSH.setHelpIDString(JB_cancel, "operation_toolbar_cancel_html");
        CSH.setHelpIDString(JB_saveAs, "operation_toolbar_save_html");
        CSH.setHelpIDString(JB_help, "operation_toolbar_help_html");
        CSH.setHelpIDString(JB_close, "operation_toolbar_return_html");


    }//end of addCSH

    /** If a process is selected, then this function finds the group to which
     * this program belongs to. It then sets both of them as selectedIndices.
     */
    public void setAllSelections() {
        int selections[] = new int[2]; //1- space for Selected and other for secondary identity index;

        mAdditionalIdentity = null;
        ActionMeta actionMeta = ConfigData.getObjectMeta(XMLConstants.soperation).getActionMeta(mSelectedIdentity);
        if (actionMeta == null) {
            return;
        }
        Vector groupId = actionMeta.getGroupId(); // Get the groups, this proces (if it is a processs) belongs to.

        // If selected item on is not a process, then getGroupId() returns null;
        int arrayLength = 0;
        Identity groupIdValue[] = {null, null, null, null, null, null, null, null};
        //groupIdValue.

        if (groupId != null) {
            //Highlight (grey) the first group this process belongs to
            arrayLength = groupId.size();

            for (int i = 0; i < arrayLength; i++) {
                groupIdValue[i] = (Identity) groupId.get(i);
            //Identity groupIdValue = (Identity)groupId.get(0);
            }

            //Start from the currently selected index - 1 and work up the model until an applicable group is found
            for (int listItem = mSelectedIndex - 1; listItem >= 0 && mAdditionalIdentity == null; listItem--) {
                //Loop over each index of groups applicable to this process
                for (int j = 0; j < groupId.size(); j++) {
                    if (groupIdValue[j].equals((Identity) mIdListModel.get(listItem))) {
                        mAdditionalIndex = listItem;
                        mAdditionalIdentity = (Identity) mIdListModel.get(listItem);
                        break;
                    }
                }
            }

            if (mAdditionalIdentity != null) {
                selections[0] = mSelectedIndex;
                selections[1] = mAdditionalIndex;

                mProcessGroupList.setSelectedIndices(selections);
            }
        }
        return;
    }

    /**
     * Basically this method display the tables in the operation dialog screen based on a
     * particular selection criteria. If a process is selectied, then the second table
     * (SelectionTable) displays the parameters of the group of the process. Third table
     * (AdditionalTable) displays the process' parameers. If the process is not associated
     * with any group, then the process' parameters are displayed in the second table
     * i.e. SelectionTable itself. When a group is directly selected from the list, then
     * the groups' parameters are displayed in SelectionTable.
     */
    public void showTables() {
        mLowerTable.clear();
        mMiddleTable.clear();

        JL_middlePanel.setText(sNoAction);
        JL_lowerPanel.setText(sNoAction);

        /* mSelectedIdentity always consists of the main selected one */
        if (mAdditionalIdentity != null) // this means a process is selected and it has a group. Group parameter 
        // values are displayed in the middle table.
        {
            Action action = mOprnObj.getAction(mAdditionalIndex + listOffsetIndex);
            mMiddleTable.setData(action);
            // mAdditionalTable.setData(action);
            JL_middlePanel.setText(sGroupParameters + mAdditionalIdentity.toString() + sIdNameSeparator + action.getActionName());
            // AdditionalActionLabel.setText(mAdditionalIdentity.toString() + sIdNameSeparator + action.getActionName());

            action = mOprnObj.getAction(mSelectedIndex + listOffsetIndex);
            mLowerTable.setData(action);
            JL_lowerPanel.setText(sProcessParameters + mSelectedIdentity.toString() + sIdNameSeparator + action.getActionName());

        }
        else {
            if (mSelectedIdentity != null) {
                Action action = mOprnObj.getAction(mSelectedIndex + listOffsetIndex);
                mMiddleTable.setData(action);

                JL_middlePanel.setText(sSelectionParameters + mSelectedIdentity.toString() + sIdNameSeparator + action.getActionName());
            //SelectionActionLabel.setText(mSelectedIdentity.toString() + sIdNameSeparator + action.getActionName());
            }
        }

        invalidate();
        repaint();
    }

    /**
     * This method is onvoked when the operation drilldown screen is closed.
     */
    public void closeWindow_actionPerformed(java.awt.event.WindowEvent evt) {
        //Actual Implementation in the classes that inherit this class
        closeWindow();
    }

    public void closeWindow() {
        //Make sure every table's edits are committed.
        mOperationTable.commitEdit(true);
        mMiddleTable.commitEdit(true);
        mLowerTable.commitEdit(true);


        int option = -200;
        //System.out.println("OperationDlg : closeWindow:dataChanged:"+dataChanged+"  notesDataChanged:"+notesDataChanged);

        if (dataChanged == true || notesDataChanged == true) {
            option = JOptionPane.showConfirmDialog(this, "Save changes made to the current Operation Info? ");
            //System.out.println("OperationDlg : closeWindow -- OPTION is : " + option );
            switch (option) {
                case JOptionPane.CANCEL_OPTION:
                    break;
                case JOptionPane.YES_OPTION:
                    mOperationTable.saveDataSource();
                    mMiddleTable.saveDataSource(); //i.e transfer the new data from mVDataSource to Action object (mAction)
                    mLowerTable.saveDataSource();
                    mOriginalOprn = mOprnObj;
                    c_manage.fireRowChanged(c_row);


                    break;
                case JOptionPane.NO_OPTION:
                    break;
            }
        }

        //If neither Cancel nor close option was selected, then close the window
        if (option != JOptionPane.CANCEL_OPTION && option != JOptionPane.CLOSED_OPTION) {
            this.setVisible(false);
            dispose();
        }

    }

    public void JBClose_actionPerformed(java.awt.event.ActionEvent event) {
        // to do: code goes here.
        //Save any final changes made
        closeWindow();
    }

    public void CancelButton_actionPerformed(java.awt.event.ActionEvent event) {
        // to do: code goes here.
        this.setVisible(false);
        dispose();

    }

    public void SaveAsButton_actionPerformed(java.awt.event.ActionEvent event) {
        // to do: code goes here.
        int option = -200;
        String options[] = {"<html>Save with current<br>crop/residue</html>",
            "<html>Save with no<br>crop/residue</html>"
        };
        // If the operation has a crop then ask if he wants to save the 
        // operation with the crop or without the crop - Neha.
        if (mOprnObj.hasCrop()) {
            option = JOptionPane.showOptionDialog(this, "Select an Option", "Select Save Option",
                    JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, null);
        }

        //System.out.println("OperationDlg-SaveAs-option value:"+option);
        if (option == JOptionPane.CLOSED_OPTION) {
            return;
        }
        //Save any final changes made
        mOperationTable.saveDataSource();
        mMiddleTable.saveDataSource(); //i.e transfer the new data from mVDataSource to Action object (mAction)
        mLowerTable.saveDataSource();

        File oprnDir = new File(ConfigData.getDirectoryName(XMLConstants.soperation));
        String oprnDirPath = oprnDir.getAbsolutePath();
        WepsFileChooser mfc = new WepsFileChooser(WepsFileChooser.OPERATION, oprnDirPath,
                WepsFileChooser.SAVE);
        //set the tooltip of "home" button to "Home" instead of "Desktop"
        mfc.homeToolTip(mfc);

        mfc.setCurrentDirectory(oprnDir); //new de.schlichtherle.io.File(ConfigData.INITIAL_DIR));
        //Set the title of the file chooser dialog appropriately acc to the option - Neha
        if (option == 0) {
            mfc.setDialogTitle("Save a new Operation (with " + mOprnObj.getCropName() + ")");
        }
        else {
            if (option == 1) {
                mfc.setDialogTitle("Save a new Operation (with no crop)");
            }
        }
        if (mfc.showDialog(this) != JFileChooser.APPROVE_OPTION) {
            return;
        }

        String newFileName = null;
        try {
            newFileName = mfc.getSelectedFile().getCanonicalPath();
        }
        catch (java.io.IOException e) {
            System.err.println("OprnDlg:Save As(): error " + e);
            return;
        }
        if (!newFileName.endsWith(".oprn")) {
            newFileName = newFileName + ".oprn";
        }
        if (option == 0) {
            //save with current crop/residue selected
            mOprnObj.writeXMLFile(newFileName, true, true);
        }
        else {
            if (option == 1) {
                //save with no crop/residue
                mOprnObj.writeXMLFile(newFileName, true, false);
            }
            else {
                //save the operation that does not have any crop
                mOprnObj.writeXMLFile(newFileName, false, false);
            }
        }
        ConfigData.getOpFileList().refreshFiles();

    }

    /**
     * This method adjust the components in the operation dialog so that the adjoining 
     * components are spaced uniformly w.r.t each other when a window or frame is 
     * resized.
     * @param evt The resize event that occurs on the window.
     */
    public void OperationDlgN_componentResized(java.awt.event.ComponentEvent evt) {
        // Add your handling code here:

        validate();
        Dimension size = evt.getComponent().getSize();

        if (size.getHeight() < MIN_HEIGHT) {
            size.height = MIN_HEIGHT;
        }
        if (size.getWidth() < MIN_WIDTH) {
            size.width = MIN_WIDTH;
        }

        this.setSize(size);
        size.height -= 50;
        size.width -= 30;
        JP_main.setSize(size);

        JP_toolbar.setSize((int) JP_main.getWidth() - sideOffset, 40);
        JP_toolbar.setLocation(componentOffSet, componentOffSet);

        JP_operationName.setSize((int) JP_main.getWidth() - sideOffset, 30);
        JP_operationName.setLocation(componentOffSet, (JP_toolbar.getHeight() + (2 * componentOffSet)));

        size.height -= (JP_operationName.getHeight() + JP_toolbar.getHeight() + (5 * componentOffSet));
        int yLocation = (JP_operationName.getHeight() + JP_toolbar.getHeight() + (3 * componentOffSet));

        JP_operDetails.setSize((((int) size.getWidth() / 3) - sideOffset), (int) size.getHeight());
        JP_operDetails.setLocation(sideOffset, yLocation);

        JSP_list.setSize(((int) JP_operDetails.getWidth() - sideOffset), ((int) JP_operDetails.getHeight() - (JL_Date.getHeight() + JLabel1.getHeight() + 5 * componentOffSet)));
        JSP_list.setLocation(componentOffSet, (JL_Date.getHeight() + JLabel1.getHeight() + 4 * componentOffSet));


        JP_upper.setSize(((((int) size.getWidth() * 2) / 3) - (2 * sideOffset)), ((int) JP_operDetails.getHeight() / 3 - (3 * componentOffSet)));
        JP_upper.setLocation(((int) JP_operDetails.getWidth() + 2 * sideOffset), yLocation);
        JSP_upperParam.setSize(((int) JP_upper.getWidth() - sideOffset), ((int) JP_upper.getHeight() - (JP_upperParams.getHeight() + componentOffSet)));

        JP_middle.setSize((int) JP_upper.getWidth(), (int) JP_upper.getHeight());
        JP_middle.setLocation(((int) JP_operDetails.getWidth() + 2 * sideOffset), (yLocation + (int) JP_upper.getHeight() + componentOffSet));
        JSP_middleParam.setSize(((int) JP_middle.getWidth() - sideOffset), ((int) JP_middle.getHeight() - (JP_middleParam.getHeight() + 2 * componentOffSet)));

        JP_lower.setSize((int) JP_upper.getWidth(), (int) JP_upper.getHeight());
        JP_lower.setLocation(((int) JP_operDetails.getWidth() + 2 * sideOffset), (yLocation + 2 * ((int) JP_upper.getHeight() + componentOffSet)));
        JSP_lowerParam.setSize(((int) JP_lower.getWidth() - sideOffset), ((int) JP_lower.getHeight() - (JP_lowerParam.getHeight() + 2 * componentOffSet)));

        validate();
        repaint();

    }

    class CustomCellRenderer extends JLabel implements ListCellRenderer {

        public Component getListCellRendererComponent(
                JList list,
                Object value, // identity value tfrom which Actionname is to be displayed
                int index, // cell index
                boolean isSelected, // is the cell selected
                boolean cellHasFocus) // the list and the cell have the focus
        {
            String actionName = "";
            ActionMeta actionMeta = ConfigData.getObjectMeta(XMLConstants.soperation).getActionMeta((Identity) value);
            if (actionMeta != null) {
                actionName = actionMeta.getActionName();
            }

            setText((Identity) value + sIdNameSeparator + actionName);

            if (isSelected) {
                if (((Identity) value).equals(mSelectedIdentity)) {
                    setBackground(list.getSelectionBackground());
                    setForeground(list.getSelectionForeground());
                }
                else {
                    setBackground(Color.lightGray);
                    setForeground(list.getForeground());
                }
            }
            else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }
            setEnabled(list.isEnabled());
            setFont(list.getFont());
            setOpaque(true);
            return this;
        }
    }

    class ListMouseAdapter extends MouseAdapter {

        public void mouseClicked(MouseEvent e) {
            int SelectedIndex = mProcessGroupList.locationToIndex(e.getPoint());
            if ((SelectedIndex >= mIdListModel.getSize()) || (SelectedIndex < 0)) {
                return;
            }
            mSelectedIndex = SelectedIndex;
            mSelectedIdentity = (Identity) mIdListModel.get(mSelectedIndex);
            setAllSelections();
            // Now before changing the data, the table values must be stored as the user might have changed the values.
            if (mMiddleTable.mDataChanged == true) {
                mMiddleTable.saveDataSource(); //i.e transfer the new data from mVDataSource to Action object (mAction)
            }

            if (mLowerTable.mDataChanged == true) {
                mLowerTable.saveDataSource();
            }


            showTables();
        }
    }

    static class ActionTableCSHManager implements CSH.Manager {

        private ActionJCTable c_table;

        public ActionTableCSHManager(ActionJCTable table) {
            c_table = table;
        }

        private void translateMouseEvent(MouseEvent me) {
            Object parent = me.getSource();
            Component comp = c_table;
            int x = 0;
            int y = 0;
            while (comp != parent) {
                x += comp.getX();
                y += comp.getY();
                comp = comp.getParent();
            }

            me.translatePoint(-x, -y);
        }

        public String getHelpIDString(Object comp, AWTEvent evt) {
            if (comp != c_table) {
                return null;
            }
            try {
                if (evt instanceof MouseEvent) {
                    MouseEvent me = (MouseEvent) evt;
                    translateMouseEvent(me);
                    int row = c_table.YtoRow2(me.getY());

                    String paramName = (String) c_table.parameterNames.elementAt(row);
                    return paramName + "_html";
                }
                else {
                    return null;
                }

            }
            catch (Exception e) {
                return null;
            }
        }

        public HelpSet getHelpSet(java.lang.Object comp, java.awt.AWTEvent e) {
            return Help.getHelpSet();
        }
    }

    class ActionJCTable extends JCTable implements JCEditCellListener, MouseMotionListener {

        public int YtoRow2(int y) {
            return YtoRow(y);
        }
        public String mHeaderRow[] = {"Parameter", "Value", "Units"};
        int PROMPTCOLUMN = 0;
        int VALUECOLUMN = 1;
        int UNITSCOLUMN = 2;
        boolean mDataChanged = false; //This is used to check if theres a need for saving data from VDataSource  to the action object
        JCEditableVectorDataSource mVDataSource;
        JCCellStyle mCellStyle, mValueCellStyle;
        Action mAction; // Specifies the action for which the data is being displyed
        JCStringCellEditor se;
        NotesOperation notes;
        OperationDlg parentDlg;
        

        public ActionJCTable(OperationDlg parentDlg) {
            this();
            this.parentDlg = parentDlg;
            CSH.addManager(new ActionTableCSHManager(this));
        }

        public ActionJCTable() {
            mVDataSource = new JCEditableVectorDataSource();
            setDataSource(mVDataSource);
            setTableLooks();
            mAction = null;

            addEditCellListener(this);
            addMouseMotionListener(this);



        }

        /************************************************************* neha */
        public void mouseMoved(MouseEvent mouseEvent) {
            try {
                int row = YtoRow(mouseEvent.getY());
                String paramName = (String) parameterNames.get(row);
                String tooltip = parentDlg.c_tooltipTable.get("OpnDrill:" + paramName);
                if (tooltip != null) {
                    setToolTipText("<html>" + tooltip + "</html>");
                }
                else {
                    setToolTipText("");
                }
            }
            catch (Exception e) {
            }
        }

        public void mouseDragged(MouseEvent mouseEvent) {
            return;
        }

        public void focusGained(FocusEvent ev) {
        }

        public void focusLost(FocusEvent ev) {
            Component comp = ev.getOppositeComponent();
            //Click a button if the table loses focus to the button
            if (ev.getSource() instanceof JCTable) {
                if (comp != null && comp instanceof AbstractButton) {
                    //I don't know why, but if we don't test for the button, it clicks the save as button.
                    if (((AbstractButton) comp).getText().contains("Notes")) {
                        ((AbstractButton) comp).doClick();
                    }
                }
                //We don't want to commit unless we lose focus from a cell editor
                return;
            }
            else {
                if (ev.getSource() instanceof BaseCellEditor) {
                    //Don't commit combo boxes.  Their event code handles the commit
                    if (comp instanceof JComboBox) {
                        return;
                    }
                    //Commit everything else
                    else {
                        this.commitEdit(true);
                    //System.out.println("editor Committed");
                    }
                    //If we lost focus to a button click it
                    if (comp != null && comp instanceof AbstractButton) {
                        ((AbstractButton) comp).doClick();
                    }
                }
            }
        }
        String beforeEditValue = "";
        String afterEditValue = "";

        public void beforeEditCell(JCEditCellEvent ev) {
            // //System.out.println("beforeEditCell");
            int row = ev.getRow();
            int column = ev.getColumn();
            beforeEditValue = (String) this.getDataSource().getTableDataItem(row, column);
        }

        public void editCell(JCEditCellEvent ev) {
            //  //System.out.println("EditCell");
        }

        public void afterEditCell(JCEditCellEvent ev) {
            // //System.out.println("afterEditCell");
            int row = ev.getRow();
            int column = ev.getColumn();

            afterEditValue = (String) this.getDataSource().getTableDataItem(row, column);
            if (beforeEditValue != null && afterEditValue != null) {
                //System.out.print("OperationDlg : afterEditCell():Before Edit: "+beforeEditValue+"  after Edit: "+afterEditValue);
                //If there is a change in the value of the cell after the edit, then ask the user
                // if he needs to save the change - Neha
                if (beforeEditValue.equals(afterEditValue) == false) {
                    //System.out.println("Before Edit value and after edit value are NOT same");
                    mDataChanged = true;
                    dataChanged = true;
                }
            }
        }

        /************************************************************* neha */
        private void setTableLooks() {
            setColumnLabelDisplay(true);
            setRowLabelDisplay(false);
            setDoubleBuffered(true);
            setAutoScroll(JCTableEnum.AUTO_SCROLL_BOTH);

            //setFocusIndicator(JCTableEnum.FOCUS_NONE);
            //setFrozenColumns(2); 
            setFrozenRows(1); // header line

            mCellStyle = (JCCellStyle) getDefaultCellStyle();
            mCellStyle.setCellBorder(new JCCellBorder(JCTableEnum.BORDER_OUT));
            mCellStyle.setEditable(false);
            mCellStyle.setBackground(Color.lightGray);

            mValueCellStyle = (JCCellStyle) getDefaultCellStyle().clone(); // for the column showing parameter values
            mValueCellStyle.setBackground(Color.white);
            mValueCellStyle.setEditable(true);
            setCellStyle(JCTableEnum.ALLCELLS, VALUECOLUMN, mValueCellStyle);


            if (se == null) {
                se = new JCStringCellEditor() {

                    @Override
                    public void initialize(AWTEvent ev, JCCellInfo info, Object o) {
                        super.initialize(ev, info, o);

                        SwingUtilities.invokeLater(new Runnable() {

                            @Override
                            public void run() {
                                requestFocusInWindow();
                                selectAll();
                            }
                        });
                    }
                };
                se.addFocusListener(this);
            }

            //set the cell editor for all the editable cells - neha
            mValueCellStyle.setCellEditor(se);
            se.addFocusListener(this);

            CellStyleModel labelStyleModel = getDefaultLabelStyle();
            labelStyleModel.setFont(new Font("Dialog", Font.BOLD, 12));
            labelStyleModel.setCellBorderSides(JCTableEnum.BORDERSIDE_ALL);
            //setCellStyle(-1, JCTableEnum.ALLCELLS, headerStyleModel);

            setMinWidth(JCTableEnum.ALL, 150);	// default width
            setMinWidth(0, 250);					// make param prompt wider
            setMinWidth(2, 100);
            setFocusColor(Color.red);


            /* // Not sure why setting editor and renderer this way is not working
            try{	
            setCellEditor(Class.forName("javax.swing.JComboBox"), 
            Class.forName("com.klg.jclass.cell.editors.JCComboBoxCellEditor")
            );
            setCellRenderer(Class.forName("javax.swing.JComboBox"), 
            Class.forName("com.klg.jclass.cell.renderers.JCComboBoxCellRenderer")
            );
            }catch(ClassNotFoundException e){
            System.err.println("OperationDlg:setTableLooks()"+ "Class not found exception");
            }
             */

            mVDataSource.setColumnLabels(mHeaderRow);
            mVDataSource.setNumColumns(mHeaderRow.length);
            mVDataSource.setNumRows(0);
        }

        /* Clears the tabel data. On clearing all cells in a JCtable, the coloumn header disppears.
         * This functions just set the number of rows to 1 i.e makes an empty row so that column labels won't disappear.
         */
        public void clear() {
            mVDataSource.clearCells();
            mAction = null;
            mVDataSource.setNumRows(0);
        }
        protected Vector<Object> parameterNames;

        public void setData(Action pAction) {
            mAction = pAction;
            parameterNames = mAction.getParameterNames();
            int numParams = parameterNames.size();

            if (numParams == 0) {
                System.err.println("ParamterJCTable:setData(): " + "Action " + pAction.getIdentity() + " has no parameters");
                mVDataSource.clearCells();

                return;
            }

            ActionMeta actionMeta = ConfigData.getObjectMeta(XMLConstants.soperation).getActionMeta(mAction.getIdentity());
            clearSelectedCells();
            //reset all data
            mVDataSource.clearCells();
            //reset all cell styles
            setCellStyle(JCTableEnum.ALLCELLS, JCTableEnum.ALLCELLS, mCellStyle);
            setCellStyle(JCTableEnum.ALLCELLS, VALUECOLUMN, mValueCellStyle);

            int row = 0, col = 0;

            for (int i = 0; i < numParams; i++) {
                col = 0;
                String paramName = (String) parameterNames.get(i);
                String paramValue;

                String paramPrompt = null;
                //String paramType = null;
                String displayAttribute = null;
                String valueAttribute = null;
                String format = null;
                //String units[] = new String[2];
                String units = null;
                Hashtable paramChoices = null;

                ParameterMeta paramMeta = null;
                Parameter parameter = mAction.getParameter(paramName);

                //paramName = parameter.get(XMLConstants.sname);

                paramValue = parameter.get(XMLConstants.svalue);

                // Col 0 = param prompt, Col 1 = param value, Col 2 = param units
                if (actionMeta != null) {
                    paramMeta = actionMeta.getParameterMeta(paramName);
                    if (paramMeta != null) {
                        paramPrompt = paramMeta.getPrompt(); // actionMeta.getParamPrompt(paramName);
                        //paramType = paramMeta.getType(); // actionMeta.getParamType(paramName);

                        units = paramMeta.getUnit(ConfigData.getDisplayUnit());
                        if (units == null) {
                            units = paramMeta.getUnit(XMLConstants.kPrimaryUnit);
                        }
                        /*
                        units[XMLConstants.kPrimaryUnit] = paramMeta.getUnit(XMLConstants.kPrimaryUnit);
                        units[XMLConstants.kAlternateUnit] = paramMeta.getUnit(XMLConstants.kAlternateUnit); // actionMeta.getParamUnit(paramName, XMLConstants.kAlternateUnit);
                        if(units[XMLConstants.kAlternateUnit] == null) //if the alternate unit is not present in any file 
                        units[XMLConstants.kAlternateUnit]  = units[XMLConstants.kPrimaryUnit] ;
                         */
                        displayAttribute = paramMeta.getAttribute(XMLConstants.sdisplayattribute); // actionMeta.getParamAttribute(paramName, XMLConstants.sdisplayattribute);
                        valueAttribute = paramMeta.getAttribute(XMLConstants.svalueattribute); // actionMeta.getParamAttribute(paramName, XMLConstants.svalueattribute);
                        format = paramMeta.getAttribute(XMLConstants.sformat);

                        paramChoices = paramMeta.getChoices(); // actionMeta.getParamChoices(paramName);
                    }
                }

                if (displayAttribute == null) /* For some reason, the attribute is not specifed in the file */ {
                    System.err.println("OperationDlg:setData(): " + "Theres no display attribute for parameter " + paramName + " in the *.lang.xml file");
                    displayAttribute = XMLConstants.sViewable;
                }
                else {
                    if (displayAttribute.equals(XMLConstants.sHidden)) {
                        continue;
                    } /* Hidden parameters should not be displayed on the table */
                }

                if (valueAttribute == null) {
                    System.err.println("OperationDlg:setData(): " + "Theres no value attribute for parameter " + paramName + " in the *.lang.xml file");
                    valueAttribute = XMLConstants.sint;
                }

                if ((paramPrompt == null) || (paramPrompt.length() == 0)) {
                    paramPrompt = paramName;
                }

                mVDataSource.setTableDataItem(paramPrompt, row, col++);

                /* If the parameter is choice list type, then instead of the actual value, 
                 * the various choices should go into the table.
                 */
                
                if (valueAttribute.equals(XMLConstants.schoice)) //(paramType.equals(XMLConstants.schoice)) )
                {
                    if (paramChoices == null) // due to reason such as parameter misspelled in lang file,...
                    {
                        System.err.println("OperationDlg:setData(); " + paramName + " has no Choices");
                        continue;
                    }

                    Enumeration enumChoices = paramChoices.elements();

                    Vector choiceList = new Vector();
                    while (enumChoices.hasMoreElements()) {
                        String choice = (String) enumChoices.nextElement();
                        //System.out.println("OperationDlg : ActionJCTable : setData() : Line  633 : My Choice value is : " + choice );
                        choiceList.add(choice);
                    }
                    Collections.sort(choiceList);

                    /* XXX - Not sure why this method of setting the combobox into the data source is NOT working*/
                    /*
                    choiceBox = new JComboBox(choiceList);
                    choiceBox.setSelectedItem(paramChoices.get(paramValue));
                    mVDataSource.setTableDataItem(choiceBox, row, col++);
                    //mVDataSource.setTableDataItem("HaHaHa", row, col++);
                    //System.out.println("Opr'nDlg:setData"+ "Setting data to comboBox");
                     */

                    /* XXX Temporary solution - as the above way of setting through combo box into the data source is not working
                     * In this solution, every cell has separate cell editor and cell renderer which is not a suggested way
                     */

                    JCComboBoxCellEditor comboEditor = new JCComboBoxCellEditor(choiceList.toArray());
                    JCComboBoxCellRenderer comboRenderer = new JCComboBoxCellRenderer(choiceList.toArray());
                    comboEditor.setSelectedItem(paramChoices.get(paramValue));
                    comboRenderer.setSelectedItem(paramChoices.get(paramValue));

                    JCCellStyle comboStyle = (JCCellStyle) mValueCellStyle.clone();
                    // JCCellStyle comboStyle = new JCCellStyle((JCCellStyle)getDefaultCellStyle().clone());
                    comboStyle.setCellEditor(comboEditor);
                    comboStyle.setCellRenderer(comboRenderer);
                    if ((displayAttribute != null) && (displayAttribute.equals(XMLConstants.sEditable))) {
                        comboStyle.setEditable(true);
                    }
                    else {
                        comboStyle.setEditable(false);
                        comboStyle.setBackground(ConfigData.getDisabledColor());
                    }

                    setCellStyle(row, col, comboStyle);

                    JComboBox comboBox = (JComboBox) ((comboStyle.getCellEditor()).getComponent());
                    comboBox.addItemListener(new ItemListener() {

                        public void itemStateChanged(ItemEvent ev) {
                            if (ev.getStateChange() == ItemEvent.SELECTED) {	////System.out.println("Item changed");
                                commitEdit(true);
                            }
                        }
                    });
                    //System.out.println("Table:setData() - ParamChoice = " + paramChoices.get(paramValue) + ", Value = " + paramValue);
                    mVDataSource.setTableDataItem(paramChoices.get((paramValue)), row, col++);
                /* END TEMPORARY SOLUTION*/

                }
                else if (valueAttribute.equals(XMLConstants.smultiline)) {
                    //System.out.println("SetData:MultiLine Text attribute for NOTES");
                    notes = new NotesOperation("Operation File Notes", parentDlg, this, paramValue, row, col);




                    JCCellStyle buttonStyle = (JCCellStyle) mValueCellStyle.clone();
                    buttonStyle.setCellEditor(new CropDlg.ButtonEditor());

                    if ((displayAttribute != null) && (displayAttribute.equals(XMLConstants.sEditable))) {
                        buttonStyle.setEditable(true);
                    }

                    buttonStyle.setBackground(ConfigData.getDisabledColor());
                    buttonStyle.setForeground(Color.BLACK);
                    setCellStyle(row, col, buttonStyle);

                    JButton button = (JButton) ((buttonStyle.getCellEditor()).getComponent());
                    button.setSize(60, 8);
                    button.setPreferredSize(new Dimension(60, 8));
                    // button.setBackground(Color.RED);
                    button.setOpaque(true);

                    if (displayAttribute.equals(XMLConstants.sEditable)) {
                        button.setText("Edit Notes");
                        notes.setEditable(true);
                    }
                    else{
                        button.setText("View Notes");
                        notes.setEditable(false);
                    }

                    buttonStyle.setCellRenderer(new CropDlg.ButtonRenderer(button.getText()));






                    button.addActionListener(new ActionListener() {

                        public void actionPerformed(ActionEvent ev) {
                            //System.out.println("setDataTab():Button pressed");
                            notesButton_clicked(ev);
                        }
                    });

                    mVDataSource.setTableDataItem(paramValue, row, col++);
                }
                else if (valueAttribute.equals(XMLConstants.sfuel)){
                    FuelComboBoxEditor fuelEditor = new FuelComboBoxEditor();
                    FuelComboBoxRenderer fuelRenderer = new FuelComboBoxRenderer();

//                    fuelEditor.setSelectedItem(paramChoices.get(paramValue));
//                    fuelRenderer.setSelectedItem(paramChoices.get(paramValue));

                    JCCellStyle fuelStyle = (JCCellStyle) mValueCellStyle.clone();
                    // JCCellStyle comboStyle = new JCCellStyle((JCCellStyle)getDefaultCellStyle().clone());
                    fuelStyle.setCellEditor(fuelEditor);
                    fuelStyle.setCellRenderer(fuelRenderer);
                    if ((displayAttribute != null) && (displayAttribute.equals(XMLConstants.sEditable))) {
                        fuelStyle.setEditable(true);
                    }
                    else {
                        fuelStyle.setEditable(false);
                        fuelStyle.setBackground(ConfigData.getDisabledColor());
                    }

                    setCellStyle(row, col, fuelStyle);
                    //set the value
                    mVDataSource.setTableDataItem(paramValue, row, col++);

                    

                    final FuelChooser fuelChooser = (FuelChooser) ((fuelStyle.getCellEditor()).getComponent());
                    fuelChooser.addItemListener(new ItemListener() {

                        @Override
                        public void itemStateChanged(ItemEvent ev) {
                            if (ev.getStateChange() == ItemEvent.SELECTED) {	////System.out.println("Item changed");
                                commitEdit(true);
                            }
                        }
                    });
                }
                else {
                    if (displayAttribute.equals(XMLConstants.sViewable)) // Viewable attribute means not Editable
                    {
                        JCCellStyle style = (JCCellStyle) mValueCellStyle.clone();
                        style.setEditable(false);
                        style.setBackground(ConfigData.getDisabledColor());
                        setCellStyle(row, col, style);
                    }

                    if (format != null) {
                        JCCellStyle style = (JCCellStyle) getCellStyle(row, col);
                        setCellStyle(row, col, (JCCellStyle) style.clone());
                        getCellStyle(row, col).setCellRenderer(new MyFormattedCellRenderer(format));
                    }

                    // convert the value to alternate unit before displaying
                    if ((ConfigData.getDisplayUnit() == XMLConstants.kAlternateUnit) && (paramMeta != null)) {
                        paramValue = paramMeta.convertToAlternateUnits(paramValue);

                    }
                    mVDataSource.setTableDataItem(paramValue, row, col++);

                }           

                mVDataSource.setTableDataItem(units, row, col++);
                //	mVDataSource.setTableDataItem(primaryUnit, row , col++);		
                row++;

            }

            /*
            if(numRows > 0)
            mVDataSource.setNumRows(numRows);
            else
            mVDataSource.setNumRows(1); //show atleast 1 row, else the headers disappear
             */
            mVDataSource.setNumRows(row);

        }

        public void notesButton_clicked(java.awt.event.ActionEvent evt) {
            int row = getCurrentRow();
            int col = getCurrentColumn();
            String text = (String) getDataSource().getTableDataItem(row, col);
            notes.setText(text);
            if (notes.notesPresent == false) {
                notes.setVisible(true);
                notes.notesPresent = true;
            }
            else {
                if (notes.isActive() == false) {
                    notes.toFront();
                    notes.setVisible(true);
                    notes.requestFocus();
                }//end of else
            }
        }

        /* Saves the new values from the dataSource into the Action (mAction) object
         *
         */
        public void saveDataSource() {
            /* When the table data is commited, only the data in mVDataSource is saved. The data in the mAction object
             * isn't modified.
             * If a data values is being displayed and edited in alternate units, then the value has to be converted to primary units 
             * before being saved.
             */
            if (mAction == null) {
                return;
            } // Theres no data in the table

            if (mDataChanged == false) // nothing to save
            {
                return;
            }

            dataChanged = true;
            mDataChanged = false; //reset the boolean varaible

            Vector parameterNames = mAction.getParameterNames();
            int numParams = parameterNames.size();

            int row = 0; /* Note that row is != numParams as some prameters might be hidden */

            ActionMeta actionMeta = ConfigData.getObjectMeta(XMLConstants.soperation).getActionMeta(mAction.getIdentity());

            // The table displays all the parameters from the this Action in the order obtained through the hashtable 
            //in setData()

            for (int i = 0; i < numParams; i++) {
                Parameter parameter = null;
                ParameterMeta paramMeta = null;

                String paramName = (String) parameterNames.get(i);
                //System.out.println("OperationDlg : saveDataSource(): Parameter Name is :---" + paramName);
                //String paramType = null;
                //String primaryUnit = null;
                String displayAttribute = null;
                String valueAttribute = null;
                Hashtable paramChoices = null;

                parameter = mAction.getParameter(paramName);
                if (parameter == null) {
                    System.err.println("OprnDlg:setData(): " + "Theres no parameter value for parameter " + paramName);
                    continue;
                }

                String oldValue = parameter.get(XMLConstants.svalue);
                //System.out.println("OperationDlg : saveDataSource(): " + "OLD value for parameter is :---" + oldValue);
                if (actionMeta != null) {
                    // paramType = actionMeta.getParamType(paramName);
                    // primaryUnit = actionMeta.getParamUnit(paramName, XMLConstants.kPrimaryUnit);
                    paramMeta = actionMeta.getParameterMeta(paramName);
                    if (paramMeta != null) {
                        displayAttribute = paramMeta.getAttribute(XMLConstants.sdisplayattribute); // actionMeta.getParamAttribute(paramName, XMLConstants.sdisplayattribute);
                        valueAttribute = paramMeta.getAttribute(XMLConstants.svalueattribute); //actionMeta.getParamAttribute(paramName, XMLConstants.svalueattribute);
                        paramChoices = paramMeta.getChoices(); // actionMeta.getParamChoices(paramName);
                    }
                }

                if ((displayAttribute != null) && (displayAttribute.equals(XMLConstants.sHidden))) {
                    continue;
                } // Hidden parameters should not be displayed on the table

                /*			
                if( (paramType != null) && (valueAttribute.equals(XMLConstants.schoice)) ) //(paramType.equals(XMLConstants.schoice)) )
                {
                paramChoices = actionMeta.getParamChoices(paramName);
                if(paramChoices == null) // due to reason such as parameter misspelled in lang file,...
                {	System.err.println("OprnDlg:setData(); " + paramName + " has no Choices");
                continue;
                }
                } */

                String newValue = (String) mVDataSource.getTableDataItem(row, VALUECOLUMN);
                //System.out.println("OperationDlg : saveDataSource(): " + " NEW value for parameter is :---" + newValue);
                row++;
                if (newValue == null) {
                    //System.out.println("OprnDlg:saveDataSource " + "Param '" + paramName + "' is null");

                    continue;
                }
                //String displayUnit = (String)mVDataSource.getTableDataItem(row, UNITSCOLUMN); // the units in which parameters are displayed

                /* choice list needs to be handled specially as the choices (strings) are displayed in the table whereas the 
                 * choice values (integers) are saved.
                 */
                if ((valueAttribute != null) && (valueAttribute.equals(XMLConstants.schoice)))//(paramType.equals(XMLConstants.schoice)) )
                {

                    if (paramChoices == null) // due to reasons such as parameter misspelled in lang file,...
                    {
                        System.err.println("OprnDlg:setData(); " + paramName + " has no Choices");
                        continue;
                    }

                    //get the key corresponding to the choice displayed
                    Enumeration keys = paramChoices.keys();
                    while (keys.hasMoreElements()) {
                        String keyVal = (String) keys.nextElement();
                        String toCompare = (String) paramChoices.get(keyVal);
                        if (toCompare.equals(newValue)) {
                            parameter.setValue(keyVal);
                            break;
                        }
                    }
                } // end if 
                else //all other types
                {
                    String valueToSet = newValue;

                    if (ConfigData.getDisplayUnit() != XMLConstants.kPrimaryUnit) // Conversions needed
                    {
                        if (paramMeta != null) {
                            valueToSet = paramMeta.convertToPrimaryUnits(newValue);
                        }

                    //System.out.println("OprnDlg:saveDataSource() " + "Converted new value " + newValue + " to " + valueToSet);

                    }

                    if (!(oldValue.equals(valueToSet))) {
                        /* Values should be written out in proper type i,e if user types in 5.00 for an integer value, 
                         * then it should be converted to 5 before putting the into the parameter
                         */

                        ////System.out.println("saveDataSource" + " Saving value " + paramName + " " + valueToSet);

                        String properTypeValue = valueToSet;
                        if (paramMeta != null) {
                            properTypeValue = paramMeta.convertToProperType(properTypeValue);
                        }
                        //System.out.println("OprnDlg:saveDataSource() " + "Proper Type Value is : " + properTypeValue);
                        parameter.setValue(properTypeValue);
                    }
                } // else all other types


            } // end of for
        }
    }

    static class NotesOperation extends usda.weru.mcrew.gui.NotesMan_n {

        public String title;
        //This tells us if the Notes frame is presently instantiated.
        public boolean notesPresent = false;
        public ActionJCTable tableRef;
        private int row;
        private int col;
        private String paramValue = "";

        /** Creates a new instance of NotesCrop */
        public NotesOperation(String t, java.awt.Dialog parent, Component tableParent, String paramValue, int row, int col) {
            super(parent, true);
            setSize(500, 300);
            setTitle(t);
            tableRef = (ActionJCTable) tableParent;
            this.paramValue = paramValue;
            this.row = row;
            this.col = col;
            JTA_Notes.setText(paramValue);
            tableRef.parentDlg.notesDataChanged = false;
        }

        public void JBSave_actionPerformed(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
            paramValue = JTA_Notes.getText();
            //   //System.out.println("NotesCrop:JBSave_actionPerformed:newValue:"+paramValue);
            //tableRef.mVDataSource.setTableDataItem(paramValue, row , tableRef.VALUECOLUMN);
            tableRef.mVDataSource.setTableDataItem(paramValue, row, col);
            tableRef.mDataChanged = true;
            tableRef.parentDlg.dataChanged = true;
            tableRef.parentDlg.notesDataChanged = true;
            notesPresent = false;

            this.dispose();
        }

        public void JBCancel_actionPerformed(java.awt.event.ActionEvent evt) {
            // TODO add your handling code here:
            notesPresent = false;
            tableRef.parentDlg.notesDataChanged = false;
            this.dispose();
        }

        public void setText(String text) {
            JTA_Notes.setText(text);
        }

        public void setEditable(boolean editable){
            JB_Save.setVisible(editable);
            JTA_Notes.setEditable(editable);
            JB_Cancel.setText(editable ? "Cancel" : "Close");
        }
    }
}