edu.ku.brc.af.ui.forms.formatters.DataObjAggregatorDlg.java Source code

Java tutorial

Introduction

Here is the source code for edu.ku.brc.af.ui.forms.formatters.DataObjAggregatorDlg.java

Source

/* Copyright (C) 2015, University of Kansas Center for Research
 * 
 * Specify Software Project, specify@ku.edu, Biodiversity Institute,
 * 1345 Jayhawk Boulevard, Lawrence, Kansas, 66045, USA
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package edu.ku.brc.af.ui.forms.formatters;

import static edu.ku.brc.ui.UIHelper.createButton;
import static edu.ku.brc.ui.UIHelper.createComboBox;
import static edu.ku.brc.ui.UIHelper.createI18NFormLabel;
import static edu.ku.brc.ui.UIHelper.createLabel;
import static edu.ku.brc.ui.UIRegistry.getResourceString;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionListener;

import org.apache.commons.lang.StringUtils;

import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import edu.ku.brc.af.core.db.DBFieldInfo;
import edu.ku.brc.af.core.db.DBTableInfo;
import edu.ku.brc.af.ui.forms.FormViewObj;
import edu.ku.brc.af.ui.forms.ViewFactory;
import edu.ku.brc.af.ui.forms.validation.DataChangeListener;
import edu.ku.brc.af.ui.forms.validation.DataChangeNotifier;
import edu.ku.brc.af.ui.forms.validation.FormValidator;
import edu.ku.brc.af.ui.forms.validation.UIValidatable;
import edu.ku.brc.af.ui.forms.validation.UIValidator;
import edu.ku.brc.af.ui.forms.validation.ValComboBox;
import edu.ku.brc.af.ui.forms.validation.ValSpinner;
import edu.ku.brc.af.ui.forms.validation.ValTextField;
import edu.ku.brc.ui.CustomDialog;
import edu.ku.brc.ui.DocumentAdaptor;
import edu.ku.brc.ui.UIHelper;

/**
 * @author Ricardo
 *
 * @code_status Alpha
 *
 */
public class DataObjAggregatorDlg extends CustomDialog implements DataChangeListener {
    protected Frame aggDlgFrame;
    protected DBTableInfo tableInfo;
    protected DataObjAggregator selectedAggregator;
    protected boolean newAggregator;
    protected DataObjFieldFormatMgr dataObjFieldFormatMgrCache;
    protected UIFieldFormatterMgr uiFieldFormatterMgrCache;

    // UI controls
    protected JComboBox displayCbo;
    protected JComboBox fieldOrderCbo;
    protected ValTextField nameText;
    protected ValTextField titleText;
    protected ValTextField sepText;
    protected ValSpinner countSpinner;
    protected ValTextField endingText;

    // listeners
    protected DocumentListener[] textChangedDL = new DocumentListener[5];
    protected ListSelectionListener aggregatorListSL = null;
    protected ItemListener checkBoxListener = null;
    protected ActionListener cboAL = null;

    protected boolean hasChanged = false;
    protected boolean isNameInError = false;
    protected FormValidator validator = new FormValidator(null);
    protected boolean isNew = false;

    /**
     * @throws HeadlessException
     */
    public DataObjAggregatorDlg(final CustomDialog parentDlg, final DBTableInfo tableInfo,
            final DataObjFieldFormatMgr dataObjFieldFormatMgrCache,
            final UIFieldFormatterMgr uiFieldFormatterMgrCache, final DataObjAggregator selectedAggregator)
            throws HeadlessException {
        super(parentDlg, getResourceString("DOA_DLG_TITLE"), true, OKCANCELHELP, null);

        this.tableInfo = tableInfo;
        this.dataObjFieldFormatMgrCache = dataObjFieldFormatMgrCache;
        this.uiFieldFormatterMgrCache = uiFieldFormatterMgrCache;
        this.selectedAggregator = selectedAggregator;
        this.helpContext = "DOA_EDITOR";

        validator.addDataChangeListener(this);
        validator.addEnableRule("DOA_ENDING", "DOA_COUNT.getIntValue() > 0");
    }

    /**
     * @param key
     * @return
     */
    protected JLabel createI18NFormLabelBold(final String key) {
        JLabel lbl = createI18NFormLabel(key);
        Font lblFont = lbl.getFont().deriveFont(Font.BOLD);
        lbl.setFont(lblFont);
        return lbl;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.CustomDialog#createUI()
     */
    @Override
    public void createUI() {
        super.createUI();

        isNew = StringUtils.isEmpty(selectedAggregator.getName());
        validator.setNewObj(isNew);

        CellConstraints cc = new CellConstraints();

        // panel for aggregator editing controls
        // display combobox with available data obj formatters
        PanelBuilder displayPB = new PanelBuilder(new FormLayout("f:p:g,min", "p"));

        displayCbo = createComboBox();
        JButton displayDlgBtn = createButton("...");
        displayPB.add(displayCbo, cc.xy(1, 1));
        displayPB.add(displayDlgBtn, cc.xy(2, 1));

        fieldOrderCbo = createComboBox();

        ActionListener displayDlgBtnAL = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // subtract 1 from selected index to account for empty entry at the beginning
                // if selected index is zero, then select "new" entry in the dialog, which is the last one

                boolean newFormatter;
                DataObjSwitchFormatter dosf;
                if (displayCbo.getSelectedIndex() == 0) {
                    // no formatter selected: create a new one and pass it to the dialog so the user can edit it
                    newFormatter = true;
                    dosf = new DataObjSwitchFormatter(null, null, true, false, tableInfo.getClassObj(), "");
                } else {
                    // pass selected formatter to the dialog so the user can edit it
                    newFormatter = false;
                    dosf = (DataObjSwitchFormatter) displayCbo.getSelectedItem();
                }
                DataObjFieldFormatDlg dlg = new DataObjFieldFormatDlg(null, tableInfo, dataObjFieldFormatMgrCache,
                        uiFieldFormatterMgrCache, dosf);
                dlg.createUI();

                if (dlg.isEditable()) {
                    dlg.setVisible(true);

                    // set combo selection to formatter selected in dialog
                    if (dlg.getBtnPressed() == OK_BTN) {
                        selectedAggregator.setFormatName(dosf.getName());
                        if (newFormatter) {
                            // must add new DO formatter and then select it
                            dataObjFieldFormatMgrCache.addFormatter(dosf);
                        }
                        // update the display combo, adding the new formatter and selecting it
                        // if that's the case
                        updateDisplayCombo();
                    }
                }
            }
        };
        displayDlgBtn.addActionListener(displayDlgBtnAL);

        // text fields
        titleText = new ValTextField(10);
        nameText = new ValTextField(10) {
            @Override
            public ErrorType validateState() {
                ErrorType state = super.validateState();
                if (state == ErrorType.Valid) {
                    return isNameInError ? ErrorType.Error : ErrorType.Valid;
                }
                return state;
            }
        };
        sepText = new ValTextField(10);
        endingText = new ValTextField(10);
        countSpinner = new ValSpinner(0, 10, true, false);

        countSpinner.setValue(0);

        JButton valBtn = FormViewObj.createValidationIndicator(this, validator);
        PanelBuilder valInfoBtnPB = new PanelBuilder(new FormLayout("f:p:g,p", "p"));
        valInfoBtnPB.add(valBtn, cc.xy(2, 1));
        validator.setValidationBtn(valBtn);

        PanelBuilder pb = new PanelBuilder(
                new FormLayout("r:p,2px,p,f:p:g", UIHelper.createDuplicateJGoodiesDef("p", "2px", 11)));
        int y = 1;

        JLabel tableTitleLbl = createI18NFormLabel("FFE_TABLE");
        JLabel tableTitleValueLbl = createLabel(tableInfo.getTitle());
        tableTitleValueLbl.setBackground(Color.WHITE);
        tableTitleValueLbl.setOpaque(true);

        pb.add(tableTitleLbl, cc.xy(1, y));
        pb.add(tableTitleValueLbl, cc.xyw(3, y, 2));
        y += 2;

        pb.addSeparator(" ", cc.xyw(1, y, 3));
        y += 2;

        pb.add(createI18NFormLabelBold("DOA_NAME"), cc.xy(1, y));
        add(pb, nameText, "DOA_NAME", "DOA_NAME.getText().length() > 0", cc.xyw(3, y, 2));
        y += 2;

        pb.add(createI18NFormLabelBold("DOA_TITLE"), cc.xy(1, y));
        add(pb, titleText, "DOA_TITLE", "DOA_TITLE.getText().length() > 0", cc.xyw(3, y, 2));
        y += 2;

        pb.add(createI18NFormLabelBold("DOA_DISPLAY"), cc.xy(1, y));
        pb.add(displayPB.getPanel(), cc.xyw(3, y, 2));
        y += 2;

        pb.add(createI18NFormLabelBold("DOA_SEP"), cc.xy(1, y));
        add(pb, sepText, "DOA_SEP", "DOA_SEP.getText().length() > 0", cc.xyw(3, y, 2));
        y += 2;

        pb.add(createI18NFormLabelBold("DOA_COUNT"), cc.xy(1, y));
        add(pb, countSpinner, "DOA_COUNT", null, cc.xyw(3, y, 2));
        y += 2;

        pb.add(createI18NFormLabel("DOA_ENDING"), cc.xy(1, y));
        add(pb, endingText, "DOA_ENDING", "DOA_ENDING.getText().length() > 0", cc.xyw(3, y, 2));
        y += 2;

        pb.add(createI18NFormLabel("DOA_SORT_BY"), cc.xy(1, y));
        add(pb, fieldOrderCbo, "DOA_DEFAULT", null, cc.xy(3, y));
        y += 2;

        pb.add(valInfoBtnPB.getPanel(), cc.xyw(3, y, 2));
        y += 2;

        pb.setBorder(BorderFactory.createEmptyBorder(14, 14, 0, 14));

        contentPanel = pb.getPanel();
        mainPanel.add(contentPanel, BorderLayout.CENTER);

        fillWithObjAggregator(selectedAggregator);

        updateUIEnabled();

        addComboBoxActionListeners();

        if (!isNew) {
            ViewFactory.changeTextFieldUIForDisplay(nameText, false);
        }

        validator.resetFields();
        validator.setEnabled(true);
        validator.setHasChanged(false);

        pack();

        if (isNew) {
            nameText.getDocument().addDocumentListener(new DocumentAdaptor() {
                @Override
                public void changedUpdate(DocumentEvent e) {
                    isNameInError = dataObjFieldFormatMgrCache.getAggregator(nameText.getText()) != null;
                    validator.validateForm();
                    updateUIEnabled();
                }
            });
        }
    }

    /**
     * @param pb
     * @param comp
     * @param ident
     * @param valRule
     * @param cc
     */
    protected void add(final PanelBuilder pb, final JComponent comp, final String ident, final String valRule,
            final CellConstraints cc) {
        pb.add(comp, cc);
        if (comp instanceof UIValidatable) {
            if (comp instanceof ValTextField) {
                validator.hookupTextField((ValTextField) comp, ident, true, UIValidator.Type.Changed, valRule,
                        false);

            } else if (comp instanceof ValComboBox) {
                DataChangeNotifier dcn = validator.hookupComponent(comp, ident, UIValidator.Type.Changed, valRule,
                        false);
                ((ValComboBox) comp).getComboBox().addActionListener(dcn);

            } else if (comp instanceof ValSpinner) {
                DataChangeNotifier dcn = validator.hookupComponent(comp, ident, UIValidator.Type.Changed, valRule,
                        false);
                ((ValSpinner) comp).addChangeListener(dcn);
            }
            validator.addUILabel(ident, UIHelper.createI18NLabel(ident));

            if (comp instanceof UIValidatable) {
                ((UIValidatable) comp).setRequired(true);
            }
        }
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.CustomDialog#setVisible(boolean)
     */
    public void setVisible(final boolean visible) {
        if (visible) {
            createUI();

            Dimension size = getPreferredSize();
            size.width = Math.max(400, size.width);
            setSize(size);
        }
        super.setVisible(visible);
    }

    /**
     * 
     */
    private void addComboBoxActionListeners() {
        if (cboAL == null) {
            cboAL = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if (e.getSource() == displayCbo) {
                        Object item = displayCbo.getSelectedItem();
                        if (item instanceof DataObjSwitchFormatter) {
                            // display format changed
                            DataObjSwitchFormatter fmt = (DataObjSwitchFormatter) item;
                            selectedAggregator.setFormatName(fmt.getName());
                            setHasChanged(true);
                        }
                    } else if (e.getSource() == fieldOrderCbo) {
                        Object item = fieldOrderCbo.getSelectedItem();
                        if (item instanceof DBFieldInfo) {
                            // order by field changed
                            DBFieldInfo fi = (DBFieldInfo) item;
                            selectedAggregator.setOrderFieldName(fi.getName());
                            setHasChanged(true);
                        }
                    }
                }
            };
        }

        displayCbo.addActionListener(cboAL);
        fieldOrderCbo.addActionListener(cboAL);
    }

    /*
     * Populates the display format combo with available formatters for this table 
     */
    protected void updateDisplayCombo() {
        // save selected aggregator because that one will be reset when elements are removed from combo box model
        DataObjAggregator tempAgg = selectedAggregator;

        // clear combo box list
        DefaultComboBoxModel cboModel = (DefaultComboBoxModel) displayCbo.getModel();
        cboModel.removeAllElements();

        // add formatters to display combo box
        List<DataObjSwitchFormatter> fmts = dataObjFieldFormatMgrCache.getFormatterList(tableInfo.getClassObj());

        // add an empty entry at the beginning so the user can clear the selection if he wants to
        cboModel.addElement(getResourceString("NONE"));

        if (fmts.size() == 0) {
            return;
        }

        int selectedFieldIndex = 0;
        for (int i = 0; i < fmts.size(); ++i) {
            DataObjSwitchFormatter currentFormat = fmts.get(i);
            cboModel.addElement(currentFormat);
            if (tempAgg != null && currentFormat.getName().equals(tempAgg.getFormatName())) {
                // found the selected field
                // current combo index is (i+1) because of empty entry at the beginning
                selectedFieldIndex = i + 1;
            }
        }

        // set selected field
        displayCbo.setSelectedIndex(selectedFieldIndex);
    }

    /*
     * Populates the field value combo with fields and leaves the right one selected
     */
    protected void updateFieldValueCombo() {
        // clear combo box list
        DefaultComboBoxModel cboModel = (DefaultComboBoxModel) fieldOrderCbo.getModel();
        cboModel.removeAllElements();

        // add an empty entry at the beginning so the user can clear the selection if he wants to
        cboModel.addElement(getResourceString("NONE"));

        // add fields to combo box
        List<DBFieldInfo> fields = tableInfo.getFields();
        int selectedFieldIndex = 0;
        for (int i = 0; i < fields.size(); ++i) {
            DBFieldInfo currentField = fields.get(i);
            cboModel.addElement(currentField);
            if (selectedAggregator != null
                    && currentField.getName().equals(selectedAggregator.getOrderFieldName())) {
                // found the selected field
                // current combo index is (i+1) because of empty entry at the beginning
                selectedFieldIndex = i + 1;
            }
        }

        // set selected field
        fieldOrderCbo.setSelectedIndex(selectedFieldIndex);
    }

    /**
     * @param hasChanged the hasChanged to set
     */
    public void setHasChanged(boolean hasChanged) {
        this.hasChanged = hasChanged;

        if (this.hasChanged != hasChanged) {
            setWindowModified(true);
        }
        updateUIEnabled();
    }

    /*
     * Populates the dialog controls with data from a given formatter
     */
    protected void fillWithObjAggregator(final DataObjAggregator agg) {
        selectedAggregator = agg;

        titleText.setText(agg.getTitle());
        nameText.setText(agg.getName());
        sepText.setText(agg.getSeparator());
        endingText.setText(agg.getEnding());
        countSpinner.setValue(agg.getCount() != null ? agg.getCount() : 0);

        updateDisplayCombo();
        updateFieldValueCombo();
        updateUIEnabled();
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.CustomDialog#okButtonPressed()
     */
    @Override
    protected void okButtonPressed() {
        selectedAggregator.setTitle(titleText.getText());
        selectedAggregator.setName(nameText.getText());
        selectedAggregator.setSeparator(sepText.getText());
        selectedAggregator.setEnding(endingText.getText());
        if (isNew) {
            selectedAggregator.setDefault(false);
        }
        selectedAggregator.setCount((Integer) countSpinner.getValue());
        super.okButtonPressed();
    }

    public DataObjAggregator getSelectedAggregator() {
        return selectedAggregator;
    }

    /**
     * 
     */
    protected void vaidateForm() {
        validator.processFormRules();
        validator.validateForm();
        validator.processFormRules();
    }

    /**
     * 
     */
    protected void updateUIEnabled() {
        endingText.setEnabled(((Integer) countSpinner.getValue()) > 0);

        //isInError = vaidateForm();
        okBtn.setEnabled(hasChanged && validator.isFormValid() && !isNameInError);
    }

    /**
     * @return the hasChanged
     */
    public boolean hasChanged() {
        return hasChanged;
    }

    /* (non-Javadoc)
     * @see edu.ku.brc.ui.forms.validation.DataChangeListener#dataChanged(java.lang.String, java.awt.Component, edu.ku.brc.ui.forms.validation.DataChangeNotifier)
     */
    public void dataChanged(String name, Component comp, DataChangeNotifier dcn) {
        vaidateForm();
        setHasChanged(true);
    }

    //-------------------------------------------------------------------------
    protected class DataObjAggregatorDlgDocumentListener implements DocumentListener {
        protected JTextField source;
        protected Method setter;

        public DataObjAggregatorDlgDocumentListener(JTextField source, Method setter) {
            this.source = source;
            this.setter = setter;
        }

        public void removeUpdate(DocumentEvent e) {
            changed(e);
        }

        public void insertUpdate(DocumentEvent e) {
            changed(e);
        }

        public void changedUpdate(DocumentEvent e) {
            changed(e);
        }

        protected void changed(@SuppressWarnings("unused") DocumentEvent e) {
            try {
                // equivalent to calling selectedAggregator.setter(source.getText())
                setter.invoke(selectedAggregator, source.getText());
                setHasChanged(true);
            } catch (IllegalAccessException iae) {
                edu.ku.brc.af.core.UsageTracker.incrHandledUsageCount();
                edu.ku.brc.exceptions.ExceptionTracker.getInstance().capture(DataObjAggregatorDlg.class, iae);
                edu.ku.brc.af.core.UsageTracker.incrHandledUsageCount();
                edu.ku.brc.exceptions.ExceptionTracker.getInstance().capture(DataObjAggregatorDlg.class, iae);
                throw new RuntimeException("Illegal Access Exception: " + iae.getMessage());
            } catch (InvocationTargetException ite) {
                edu.ku.brc.af.core.UsageTracker.incrHandledUsageCount();
                edu.ku.brc.exceptions.ExceptionTracker.getInstance().capture(DataObjAggregatorDlg.class, ite);
                edu.ku.brc.af.core.UsageTracker.incrHandledUsageCount();
                edu.ku.brc.exceptions.ExceptionTracker.getInstance().capture(DataObjAggregatorDlg.class, ite);
                throw new RuntimeException("Invocation Target Exception: " + ite.getMessage());
            }
        }
    }
}