/* * Copyright (c) 2011. iCarto * * This file is part of extNavTableForms * * extNavTableForms 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 3 of the License, or any later version. * * extNavTableForms 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 extNavTableForms. * If not, see <http://www.gnu.org/licenses/>. */ package es.icarto.gvsig.navtableforms; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Vector; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import org.apache.log4j.Logger; import com.hardcode.gdbms.driver.exceptions.ReadDriverException; import com.iver.andami.Launcher; import com.iver.andami.PluginServices; import com.iver.andami.ui.mdiManager.WindowInfo; import com.iver.cit.gvsig.exceptions.visitors.StopWriterVisitorException; import com.iver.cit.gvsig.fmap.layers.FLyrVect; import com.iver.cit.gvsig.fmap.layers.LayerEvent; import com.jeta.forms.components.image.ImageComponent; import com.jeta.forms.components.panel.FormPanel; import com.toedter.calendar.JDateChooser; import es.icarto.gvsig.navtableforms.calculation.Calculation; import es.icarto.gvsig.navtableforms.calculation.CalculationHandler; import es.icarto.gvsig.navtableforms.chained.ChainedHandler; import es.icarto.gvsig.navtableforms.forms.windowproperties.FormWindowProperties; import es.icarto.gvsig.navtableforms.forms.windowproperties.FormWindowPropertiesSerializator; import es.icarto.gvsig.navtableforms.gui.i18n.resource.I18nResource; import es.icarto.gvsig.navtableforms.gui.images.ImageHandler; import es.icarto.gvsig.navtableforms.gui.images.ImageHandlerManager; import es.icarto.gvsig.navtableforms.gui.tables.handler.BaseTableHandler; import es.icarto.gvsig.navtableforms.gui.tables.model.BaseTableModel; import es.icarto.gvsig.navtableforms.ormlite.ORMLite; import es.icarto.gvsig.navtableforms.ormlite.domainvalidator.ValidatorForm; import es.icarto.gvsig.navtableforms.utils.AbeilleParser; import es.udc.cartolab.gvsig.navtable.AbstractNavTable; import es.udc.cartolab.gvsig.navtable.dataacces.IController; import es.udc.cartolab.gvsig.navtable.format.DateFormatNT; @SuppressWarnings("serial") public abstract class AbstractForm extends AbstractNavTable implements IValidatableForm, II18nForm { private static final Logger logger = Logger.getLogger(AbstractForm.class); protected FormPanel formBody; private boolean isFillingValues; private boolean isSavingValues = false; private final List<BaseTableHandler> tableHandlers = new ArrayList<BaseTableHandler>(); HashMap<String, JComponent> widgets; private final ORMLite ormlite; private FillHandler fillHandler; private final I18nHandler i18nHandler; private final ValidationHandler validationHandler; private final DependencyHandler dependencyHandler; private final CalculationHandler calculationHandler; private final ChainedHandler chainedHandler; private ImageHandlerManager imageHandlerManager; private String title; public AbstractForm(FLyrVect layer) { super(layer); formBody = getFormPanel(); i18nHandler = new I18nHandler(this); widgets = AbeilleParser.getWidgetsFromContainer(formBody); ormlite = new ORMLite(getXMLPath()); validationHandler = new ValidationHandler(ormlite, this); dependencyHandler = new DependencyHandler(ormlite, widgets, this); calculationHandler = new CalculationHandler(); chainedHandler = new ChainedHandler(); imageHandlerManager = new ImageHandlerManager(); } @Override public WindowInfo getWindowInfo() { if (windowInfo == null) { super.getWindowInfo(); if (title != null) { windowInfo.setTitle(title); } for (FormWindowProperties fwp : getFormWindowProperties()) { if (fwp.getFormName().equalsIgnoreCase(getClass().getName())) { // WindowInfoSupport.getWindowInfo adds 40 to the // getWindowInfo declared // by IWindow objects final int ANDAMI_CORRECTION = 40; windowInfo.setHeight(fwp.getFormWindowHeight() - ANDAMI_CORRECTION); windowInfo.setWidth(fwp.getFormWindowWidth()); windowInfo.setX(fwp.getFormWindowXPosition()); windowInfo.setY(fwp.getFormWindowYPosition()); } } } return windowInfo; } @Deprecated /** * Use getFormPanel instead * @return */ public abstract FormPanel getFormBody(); public FormPanel getFormPanel() { return getFormBody(); } @Override public I18nResource[] getI18nResources() { return null; } @Override public I18nHandler getI18nHandler() { return i18nHandler; } public abstract String getXMLPath(); public String getFormWindowPropertiesXMLPath() { return Launcher.getAppHomeDir() + File.separator + "FormWindowProperties.xml"; } @Deprecated public Logger getLoggerName() { return Logger.getLogger(getClass()); } @Override public void validateForm() { validationHandler.validate(); } @Override public ValidatorForm getValidatorForm() { return validationHandler.getValidatorForm(); } @Override public JPanel getCenterPanel() { JPanel panel = new JPanel(new BorderLayout()); JScrollPane scrollPane = new JScrollPane(formBody); panel.add(scrollPane); return panel; } public String getValueFromLayer(String colName) { return layerController.getValue(colName); } protected void removeListeners() { validationHandler.removeListeners(widgets); dependencyHandler.removeListeners(); for (BaseTableHandler tableHandler : tableHandlers) { tableHandler.removeListeners(); } calculationHandler.removeListeners(); chainedHandler.removeListeners(); imageHandlerManager.removeListeners(); } @Override protected void initGUI() { super.initGUI(); i18nHandler.translateFormStaticTexts(); } @Override protected void initWidgets() { setListeners(); fillHandler = new FillHandler(getWidgets(), layerController, ormlite.getAppDomain()); for (JComponent c : getWidgets().values()) { if (c instanceof JDateChooser) { initDateChooser((JDateChooser) c); } } } private void initDateChooser(JDateChooser c) { SimpleDateFormat dateFormat = DateFormatNT.getDateFormat(); c.setDateFormatString(dateFormat.toPattern()); c.getDateEditor().setEnabled(false); c.getDateEditor().getUiComponent() .setBackground(new Color(255, 255, 255)); c.getDateEditor().getUiComponent() .setFont(new Font("Arial", Font.PLAIN, 11)); c.getDateEditor().getUiComponent().setToolTipText(null); } /** * This method has been deprecated in favor of formController, use instead * getFormController().getValuesOriginal() or * getFormController.getValuesChanged() */ @Deprecated public HashMap<String, String> getWidgetValues() { return layerController.getValuesChanged(); } /** * This method has been deprecated in favor of formController, use instead * getFormController().setValue(key, value) */ @Deprecated public void setWidgetValues(String key, String value) { layerController.setValue(key, value); } @Override public IController getFormController() { return layerController; } @Deprecated public HashMap<String, JComponent> getWidgetComponents() { return widgets; } @Override public Map<String, JComponent> getWidgets() { return widgets; } protected void setListeners() { validationHandler.setListeners(widgets); dependencyHandler.setListeners(); for (BaseTableHandler tableHandler : tableHandlers) { tableHandler.reload(); // When the layer is in edition mode, subforms must be disabled, // because if the user, adds a new subelement // with an fk or modifies the pk of the element it will fail // We remove it after the reload, to allow propper initializations, // and avoid NullPointerException when // removing the listeners or when layerEvent is called if (layer.isEditing()) { tableHandler.removeListeners(); } } calculationHandler.setListeners(); chainedHandler.setListeners(); imageHandlerManager.setListeners(); } @Override public void resetListeners() { super.resetListeners(); removeListeners(); setListeners(); } @Override public void fillEmptyValues() { setFillingValues(true); fillHandler.fillEmptyValues(); dependencyHandler.fillValues(); chainedHandler.fillEmptyValues(); imageHandlerManager.fillEmptyValues(); setFillingValues(false); } protected void fillSpecificValues() { String key = getPrimaryKeyValue(); if (key != null) { for (BaseTableHandler tableHandler : tableHandlers) { tableHandler.fillValues(key); } } } protected String getPrimaryKeyValue() { return null; } @Override public void fillValues() { setFillingValues(true); fillHandler.fillValues(); dependencyHandler.fillValues(); chainedHandler.fillValues(); imageHandlerManager.fillValues(); fillSpecificValues(); setFillingValues(false); validationHandler.validate(); } @Override public boolean isFillingValues() { return isFillingValues; } protected void setFillingValues(boolean b) { isFillingValues = b; } protected boolean validationHasErrors() { boolean hasError = validationHandler.hasValidationErrors(); if (hasError) { JOptionPane.showMessageDialog(this, validationHandler.getMessages(), PluginServices.getText(this, "Error de validacion"), JOptionPane.ERROR_MESSAGE); } return hasError; } protected boolean isSaveable() { if (validationHasErrors()) { return false; } return true; } /** * Use getFormController.getIndexesOfValuesChanged() instead */ @Deprecated protected Vector<Integer> getIndexesOfChangedValues() { int[] idxs = layerController.getIndexesOfValuesChanged(); Vector<Integer> indexes = new Vector<Integer>(); for (int i = 0; i < idxs.length; i++) { indexes.add(idxs[i]); } return indexes; } @Override public void setChangedValues() { int[] indexes = layerController.getIndexesOfValuesChanged(); if (indexes.length > 0) { setChangedValues(true); } else { setChangedValues(false); } enableSaveButton(isChangedValues()); } protected String[] getValues() { return layerController.getValuesChanged().values() .toArray(new String[0]); } @Override public boolean isSavingValues() { return isSavingValues; } public void setSavingValues(boolean bool) { isSavingValues = bool; } @Override public boolean saveRecord() throws StopWriterVisitorException { if (isSaveable()) { setSavingValues(true); try { layerController.update(getPosition()); setChangedValues(false); setSavingValues(false); return true; } catch (ReadDriverException e) { e.printStackTrace(); layerController.clearAll(); setChangedValues(false); setSavingValues(false); return false; } catch (StopWriterVisitorException e) { setSavingValues(false); throw e; } } return false; } @Override public void windowClosed() { super.windowClosed(); removeListeners(); writeFormWindowProperties(); } private void writeFormWindowProperties() { boolean update = false; List<FormWindowProperties> formWindowPropertiesList = getFormWindowProperties(); for (FormWindowProperties fwp : formWindowPropertiesList) { if (fwp.getFormName().equalsIgnoreCase(getClass().getName())) { fwp.setFormWindowHeight(windowInfo.getHeight()); fwp.setFormWindowWidth(windowInfo.getWidth()); fwp.setFormWindowXPosition(windowInfo.getX()); fwp.setFormWindowYPosition(windowInfo.getY()); update = true; break; } } if (!update) { FormWindowProperties fwpToAdd = new FormWindowProperties(); fwpToAdd.setFormName(getClass().getName()); fwpToAdd.setFormWindowHeight(windowInfo.getHeight()); fwpToAdd.setFormWindowWidth(windowInfo.getWidth()); fwpToAdd.setFormWindowXPosition(windowInfo.getX()); fwpToAdd.setFormWindowYPosition(windowInfo.getY()); formWindowPropertiesList.add(fwpToAdd); } String xml = FormWindowPropertiesSerializator .toXML(formWindowPropertiesList); try { FileWriter fileWriter = new FileWriter(new File( getFormWindowPropertiesXMLPath())); Writer writer = new BufferedWriter(fileWriter); writer.write(xml); writer.close(); } catch (IOException e) { e.printStackTrace(); } } private List<FormWindowProperties> getFormWindowProperties() { if (!new File(getFormWindowPropertiesXMLPath()).exists()) { return new ArrayList<FormWindowProperties>(); } else { return FormWindowPropertiesSerializator.fromXML(new File( getFormWindowPropertiesXMLPath())); } } @Override public Object getWindowProfile() { return null; } protected void setTitle(String title) { this.title = title; } @Override public void selectRow(int row) { } @Override protected void undoAction() { setChangedValues(false); try { layerController.read(getPosition()); } catch (ReadDriverException e) { logger.error(e.getMessage(), e.getCause()); layerController.clearAll(); } refreshGUI(); } @Override public FillHandler getFillHandler() { return fillHandler; } protected void addTableHandler(BaseTableHandler tableHandler) { tableHandlers.add(tableHandler); } public List<BaseTableHandler> getTableHandlers() { return tableHandlers; } protected void addCalculation(Calculation calculation) { calculationHandler.add(calculation); } protected void addChained(JComponent chained, JComponent parent) { chainedHandler.add(this, chained, parent); } protected void addChained(String chained, String parent) { chainedHandler.add(this, widgets.get(chained), widgets.get(parent)); } protected void addChained(JComponent chained, JComponent... parents) { chainedHandler.add(this, chained, Arrays.asList(parents)); } protected void addChained(String chained, String... parents) { List<JComponent> parentList = new ArrayList<JComponent>(); for (String parent : parents) { parentList.add(widgets.get(parent)); } chainedHandler.add(this, widgets.get(chained), parentList); } /** * Instead of create an implementation of ImageHandler that only sets a path * (FixedImageHandler) this utiliy method sets the image without doing * anything more * * @param imgComponent * . Name of the abeille widget * @param absPath * . Absolute path to the image or relative path from andami.jar */ protected void addImageHandler(String imgComponent, String absPath) { ImageComponent image = (ImageComponent) formBody .getComponentByName(imgComponent); ImageIcon icon = new ImageIcon(absPath); image.setIcon(icon); } protected void addImageHandler(ImageHandler imageHandler) { imageHandlerManager.addHandler(imageHandler); } @Override public void layerEvent(LayerEvent e) { layerEventTables(e); super.layerEvent(e); } private void layerEventTables(LayerEvent e) { // When the layer is in edition mode, subforms must be disabled, because // if the user, adds a new subelement // with an fk or modifies the pk of the element it will fail if (e.getEventType() == LayerEvent.EDITION_CHANGED) { if (layer.isEditing()) { for (BaseTableHandler bth : tableHandlers) { bth.removeListeners(); } } else { for (BaseTableHandler bth : tableHandlers) { final BaseTableModel bthModel = bth.getModel(); if (bthModel != null) { // This should never happen, but tablehandlers are not // correctly constructed and model field is not // correctly set bthModel.reloadUnderlyingData(); } bth.reload(); } } } } }