All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jaxx.runtime.validator.swing.SwingValidatorMessageTableModel Maven / Gradle / Ivy

There is a newer version: 3.0-alpha-6
Show newest version
/*
 * #%L
 * JAXX :: Validator
 * %%
 * Copyright (C) 2008 - 2014 Code Lutin, Tony Chemit
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */
package jaxx.runtime.validator.swing;

import jaxx.runtime.SwingUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.validator.NuitonValidatorScope;
import org.nuiton.validator.bean.simple.SimpleBeanValidatorEvent;
import org.nuiton.validator.bean.simple.SimpleBeanValidatorListener;

import javax.swing.JComponent;
import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * The model of the table of errors.
 *
 * The model listens validators messages and update his internal model from it.
 *
 * @author Tony Chemit - [email protected]
 * @since 1.3
 */
public class SwingValidatorMessageTableModel
        extends AbstractTableModel
        implements SimpleBeanValidatorListener {

    private static final long serialVersionUID = 1L;

    /** Logger */
    private static Log log =
            LogFactory.getLog(SwingValidatorMessageTableModel.class);

    public static final String[] columnNames =
            {"validator.scope", "validator.field", "validator.message"};

    public static final Class[] columnClasses =
            {NuitonValidatorScope.class, String.class, String.class};

    /** list of registred validators */
    protected transient List> validators;

    /** list of messages actual displayed */
    protected List data;

    public SwingValidatorMessageTableModel() {
        validators = new ArrayList>();
        data = new ArrayList();
    }

    /**
     * Register a validator for this model.
     *
     *
     * Note: a validator can not be register twice in the same model.
     *
     * @param validator the validator to register
     */
    public void registerValidator(SwingValidator validator) {
        if (validators.contains(validator)) {
            throw new IllegalArgumentException(
                    "the validator " + validator + " is already registred in "
                    + this);
        }
        validators.add(validator);
        validator.addSimpleBeanValidatorListener(this);
    }

    public void addMessages(SwingValidator validator,
                            String fieldName,
                            NuitonValidatorScope scope,
                            String... messages) {
        addMessages(validator, fieldName, scope, true, messages);
    }

    public void addMessages(JComponent editor,
                            String fieldName,
                            NuitonValidatorScope scope,
                            String... messages) {
        addMessages(editor, fieldName, scope, true, messages);
    }

    public void removeMessages(JComponent editor, NuitonValidatorScope scope) {

        if (editor == null) {
            // no editor, so nothing to do
            return;
        }
        // do it in reverse mode (only one pass in that way since index
        // will stay coherent while removing them)

        for (int i = getRowCount() - 1; i > -1; i--) {
            SwingValidatorMessage error = data.get(i);
            if (editor.equals(error.getEditor()) &&
                (scope == null || error.getScope() == scope)) {
                // remove the message
                data.remove(i);
                fireTableRowsDeleted(i, i);
            }
        }
    }

    public void removeMessages(SwingValidator validator,
                               String fieldName,
                               NuitonValidatorScope scope,
                               String... messages) {
        removeMessages(validator, fieldName, scope, true, messages);
    }

    public void removeMessages(JComponent editor,
                               String fieldName,
                               NuitonValidatorScope scope) {
        removeMessages(editor, fieldName, scope, true);
    }

    public void clear() {
        int i = data.size();
        if (i > 0) {
            data.clear();
            fireTableRowsDeleted(0, i - 1);
        }
    }

    public void clearValidators() {
        for (SwingValidator v : validators) {
            v.removeSimpleBeanValidatorListener(this);
        }
        validators.clear();
    }

    /**
     * Obtain the message for a given row.
     *
     * @param rowIndex the row index
     * @return the message for the given row index
     */
    public SwingValidatorMessage getRow(int rowIndex) {
        SwingUtil.ensureRowIndex(this, rowIndex);
        return data.get(rowIndex);
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        // cells are never editable in this model
        return false;
    }

    @Override
    public Class getColumnClass(int columnIndex) {
        SwingUtil.ensureColumnIndex(this, columnIndex);
        return columnClasses[columnIndex];
    }

    @Override
    public String getColumnName(int column) {
        SwingUtil.ensureColumnIndex(this, column);
        return columnNames[column];
    }

    @Override
    public void onFieldChanged(SimpleBeanValidatorEvent event) {
        String[] toDelete = event.getMessagesToDelete();
        String[] toAdd = event.getMessagesToAdd();
        String field = event.getField();
        NuitonValidatorScope scope = event.getScope();
        boolean mustAdd = toAdd != null && toAdd.length > 0;
        boolean mustDel = toDelete != null && toDelete.length > 0;

        if (log.isTraceEnabled()) {
            log.trace("----------------------------------------------------------");
            log.trace(field + " - (" + getRowCount() + ") toAdd     " + mustAdd);
            log.trace(field + " - (" + getRowCount() + ") toDelete  " + mustDel);
        }

        SwingValidator validator = (SwingValidator) event.getSource();

        if (mustDel) {

            // removes datas and notify if no messages to add
            removeMessages(validator, field, scope, !mustAdd, toDelete);
        }

        if (mustAdd) {

            // add new messages, sort datas and notify
            addMessages(validator, field, scope, true, toAdd);
        }
    }

    @Override
    public int getRowCount() {
        return data.size();
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        SwingUtil.ensureColumnIndex(this, columnIndex);
        SwingUtil.ensureRowIndex(this, rowIndex);

        SwingValidatorMessage row = data.get(rowIndex);
        if (columnIndex == 0) {
            // the icon
            return row.getScope();
        }
        if (columnIndex == 1) {
            // the field
            return row.getField();
        }
        if (columnIndex == 2) {
            // the message
            return row.getMessage();
        }

        // should never come here
        return null;
    }

    protected void addMessages(SwingValidator validator,
                               String fieldName,
                               NuitonValidatorScope scope,
                               boolean sort,
                               String... messages) {

        JComponent editor = validator == null ?
                            null :
                            validator.getFieldRepresentation(fieldName);
        // add new errors
        for (String error : messages) {
            SwingValidatorMessage row =
                    new SwingValidatorMessage(
                            validator,
                            fieldName,
                            error,
                            scope,
                            editor
                    );
            data.add(row);
            if (!sort) {
                fireTableRowsInserted(data.size() - 1, data.size() - 1);
            }
        }

        if (sort) {

            // resort datas
            Collections.sort(data);

            // notify
            fireTableDataChanged();
        }
    }

    protected void addMessages(JComponent editor,
                               String fieldName,
                               NuitonValidatorScope scope,
                               boolean sort,
                               String... messages) {

        // add new errors
        for (String error : messages) {
            SwingValidatorMessage row =
                    new SwingValidatorMessage(
                            null,
                            fieldName,
                            error,
                            scope,
                            editor
                    );
            data.add(row);
            if (!sort) {
                fireTableRowsInserted(data.size() - 1, data.size() - 1);
            }
        }

        if (sort) {

            // resort datas
            Collections.sort(data);

            // notify
            fireTableDataChanged();
        }
    }

    protected void removeMessages(SwingValidator validator,
                                  String fieldName,
                                  NuitonValidatorScope scope,
                                  boolean notify,
                                  String... messages) {

        List messagesToDel =
                new ArrayList(Arrays.asList(messages));

        // do it in reverse mode (only one pass in that way since index
        // will stay coherent while removing them)

        for (int i = getRowCount() - 1; i > -1; i--) {
            SwingValidatorMessage error = data.get(i);
            if (validator.equals(error.getValidator()) &&
                error.getScope() == scope &&
                error.getField().equals(fieldName) &&
                messagesToDel.contains(error.getMessage())) {
                // remove the message
                data.remove(i);
                if (notify) {
                    fireTableRowsDeleted(i, i);
                }
            }
        }
    }

    protected void removeMessages(JComponent editor,
                                  String fieldName,
                                  NuitonValidatorScope scope,
                                  boolean notify) {

        // do it in reverse mode (only one pass in that way since index
        // will stay coherent while removing them)

        for (int i = getRowCount() - 1; i > -1; i--) {
            SwingValidatorMessage error = data.get(i);
            if (editor.equals(error.getEditor()) &&
                (scope == null || error.getScope() == scope) &&
                error.getField().equals(fieldName)) {
                // remove the message
                data.remove(i);
                if (notify) {
                    fireTableRowsDeleted(i, i);
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy