com.aw.swing.mvp.binding.component.support.table.JTableModel.java Source code

Java tutorial

Introduction

Here is the source code for com.aw.swing.mvp.binding.component.support.table.JTableModel.java

Source

/*
 * Copyright (c) 2007 Agile-Works
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Agile-Works. ("Confidential Information").
 * You shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement you
 * entered into with Agile-Works.
 */
package com.aw.swing.mvp.binding.component.support.table;

import com.aw.core.util.DeleteableList;
import com.aw.support.beans.AWPropertyComparator;
import com.aw.swing.mvp.binding.component.support.ButtonColumn;
import com.aw.swing.mvp.binding.component.support.ChangeValueListener;
import com.aw.swing.mvp.binding.component.support.ColumnInfo;
import com.aw.swing.mvp.grid.EditingRowPolicy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.support.MutableSortDefinition;
import org.springframework.util.StringUtils;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.net.URL;
import java.util.*;

/**
 * @author gmateo
 *         15/10/2004
 */
public class JTableModel extends AbstractTableModel {
    protected final Log logger = LogFactory.getLog(getClass());

    public static ImageIcon COLUMN_UP;
    public static ImageIcon COLUMN_DOWN;
    public static ImageIcon COLUMN;

    /**
     * Values that will be shown in the JTable
     */
    private List values;
    /**
     * Array of column information
     */
    private ColumnInfo[] columnsInfo;

    EditingRowPolicy editingRowPolicy;

    private int indexSortColumn = -1;
    private boolean sortAsc = true;
    private boolean isReadOnly = false;

    public JTableModel(ColumnInfo[] columnsInfo) {
        this.columnsInfo = columnsInfo;
        //        COLUMN_UP = createImageIcon("sortUp.png", "Sort UP");
        //        COLUMN_DOWN = createImageIcon("sortDown.png", "Sort Down");
        COLUMN_UP = createImageIcon("sort2Up.png", "Sort UP");
        COLUMN_DOWN = createImageIcon("sort2Down.png", "Sort Down");
        COLUMN = createImageIcon("sort2.png", "");

    }

    public JTableModel(ColumnInfo[] columnsInfo, List lista) {
        this(columnsInfo);
        values = lista;
    }

    /**
     * Returns the name of the column at the given column index.
     * This is used to initialize the table's column header name.
     * Note: this name does not need to be unique; two columnNames in a table
     * can have the same name.<p>
     *
     * @param columnIndex the index of the column
     * @return the name of the column
     * @throws NullPointerException if the optional column names array
     *                              has not been set in the constructor. In this case API users
     *                              must override this method.
     * @see #getColumnCount()
     * @see #getRowCount()
     */
    public String getColumnName(int columnIndex) {
        return columnsInfo[columnIndex].getColumnHeader();
    }

    private ColumnInfo getColumnInfo(String colFieldName) {
        for (int i = 0; i < columnsInfo.length; i++) {
            ColumnInfo columnInfo = columnsInfo[i];
            if (colFieldName.equals(columnInfo.getFieldName())) {
                return columnInfo;
            }
        }
        throw new IllegalStateException(
                "The column:<" + colFieldName + "> does not exist in the column info array.");
    }

    public ColumnInfo getColumnInfo(int columnIndex) {
        return columnsInfo[columnIndex];
    }

    /**
     * Return the number of columnNames
     *
     * @return
     */
    public int getColumnCount() {
        return columnsInfo.length;
    }

    /**
     * Return the number of rows
     *
     * @return
     */
    public int getRowCount() {
        return values.size();
    }

    /**
     * Get the value set in specific position.
     * If there is a CVLProvider for this column, this method return the value for this key.
     *
     * @param rowIndex
     * @param columnIndex
     * @return
     */
    public Object getValueAt(int rowIndex, int columnIndex) {
        if (rowIndex >= values.size())
            return null;
        Object object = values.get(rowIndex);
        Object value = columnsInfo[columnIndex].getValue(object, columnIndex, rowIndex);
        return value;
    }

    /**
     * Return the row which has the index sent as parameter
     * @param index
     * @return
     */
    public Object getRowAt(int index) {
        if (values.size() > 0) {
            return values.get(index);
        }
        return null;
    }

    /**
     * Add a row to the list that is shown
     *
     * @param row
     */
    public void addRow(Object row) {
        int valuesSize = values.size();
        values.add(row);
        fireTableRowsInserted(valuesSize, valuesSize);
    }

    /**
     * Add a row to the list that is shown
     *
     * @param row
     */
    public void addRow(int idx, Object row) {
        values.add(idx, row);
        fireTableRowsInserted(idx, idx);
    }

    /**
     * Add a list to the list that is shown
     */
    public void addAllRows(List rows) {
        int valuesSize = values.size();
        values.addAll(rows);
        fireTableRowsInserted(valuesSize, valuesSize + rows.size());
    }

    /**
     * Update the value of a row
     *
     * @param index
     * @param row
     */
    public void updateRow(int index, Object row) {
        values.remove(index);
        values.add(index, row);
        fireTableRowsUpdated(index, index);
    }

    /**
     * Remove the selected row
     *
     * @param rowIndex
     */
    public void removeRow(int rowIndex) {
        values.remove(rowIndex);
        fireTableRowsDeleted(rowIndex, rowIndex);
    }

    public Class getColumnClass(int c) {
        if (getValueAt(0, c) == null)
            return String.class;
        return getValueAt(0, c).getClass();
    }

    /*
     * Don't need to implement this method unless your table's
     * editable.
     */
    public boolean isCellEditable(int row, int col) {
        if (isReadOnly)
            return false;
        boolean rowIsReadOnly = false;
        if (editingRowPolicy != null) {
            editingRowPolicy.setCurrentColInfo(columnsInfo[col]);
            Object rowObject = values.get(row);
            rowIsReadOnly = !editingRowPolicy.isEditable(rowObject, columnsInfo[col].getFieldName());
        }
        return !rowIsReadOnly && (columnsInfo[col].isEditable() || columnsInfo[col] instanceof ButtonColumn);
    }

    /*
     * Don't need to implement this method unless your table's
     * data can change.
     */
    public void setValueAt(Object value, int row, int col) {
        if (values == null || values.size() == 0) {
            return;
        }
        boolean editable = isCellEditable(row, col);
        if (logger.isDebugEnabled()) {
            logger.debug(
                    "Setting value at Row:" + row + " Col:" + col + " editable:" + editable + " Value:" + value);
        }
        if (editable) {
            Object object = values.get(row);
            columnsInfo[col].setValue(object, value, row);
            if (values instanceof DeleteableList) {
                ((DeleteableList) values).addModifiedRow(object);
            }
            fireTableCellUpdated(row, col);
            List<ChangeValueListener> changeValueListenerList = columnsInfo[col].getChangeValueListenerList();
            for (ChangeValueListener changeValueListener : changeValueListenerList) {
                if (changeValueListener != null) {
                    String[] modifiedColFieldNames = changeValueListener.getModifiedCols();
                    int[] modifiedCols = getColIdxFor(modifiedColFieldNames);
                    for (Integer modifiedCol : modifiedCols) {
                        fireTableCellUpdated(row, modifiedCol.intValue());
                    }
                }
            }
            if (columnsInfo[col].isFillEmptyWithLastValue() && !settingAuto) {
                settingAuto = true;
                columnsInfo[col].setFillingEmptyWithLastValueInProcess(true);
                for (int i = 0; i < getValues().size(); i++) {
                    if (i != row) {
                        Object val = getValueAt(i, col);
                        if (val == null || ((val instanceof String) && !StringUtils.hasText((String) val))) {
                            setValueAt(value, i, col);
                        }
                    }
                }
                settingAuto = false;
                columnsInfo[col].setFillingEmptyWithLastValueInProcess(false);
            }
        }
    }

    boolean settingAuto = false;

    private int[] getColIdxFor(String[] modifiedColFieldNames) {
        int[] modifiedCols = new int[modifiedColFieldNames.length];
        for (int i = 0; i < modifiedColFieldNames.length; i++) {
            String colFieldName = modifiedColFieldNames[i];
            ColumnInfo columnInfo = getColumnInfo(colFieldName);
            modifiedCols[i] = columnInfo.getIdx();
        }
        return modifiedCols;
    }

    /**
     * Sort the shown values
     */
    public void sort() {
        Collections.sort(values);
        fireTableDataChanged();
    }

    /**
     * Sort the shown values using the comparator sent as a parameter
     *
     * @param comparator
     */
    public void sort(Comparator comparator) {
        if (comparator == null) {
            return;
        }
        Collections.sort(values, comparator);
        fireTableDataChanged();
    }

    /**
     * Sort the shown values using the comparator sent as a parameter
     */
    public void sortByColumn(int indexColumn) {
        if (indexSortColumn == indexColumn) {
            sortAsc = !sortAsc;
        } else {
            indexSortColumn = indexColumn;
        }
        ColumnInfo colInfo = columnsInfo[indexColumn];
        final String fieldName = colInfo.getFieldName();
        MutableSortDefinition mutableSortDefinition = new MutableSortDefinition(fieldName, true, sortAsc);
        AWPropertyComparator propertyComparator = new AWPropertyComparator(mutableSortDefinition,
                colInfo.getFormatter());
        Collections.sort(values, propertyComparator);
        fireTableDataChanged();
    }

    public List getValues() {
        if (values != null) {
            return values;
        }
        return new ArrayList();
    }

    public void setValues(List values) {
        this.values = values;
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                fireTableDataChanged();
            }
        });
    }

    public Icon getColumnIcon(int index) {
        if (indexSortColumn == index) {
            return sortAsc ? COLUMN_UP : COLUMN_DOWN;
        }
        return COLUMN;
    }

    /**
     * Returns an ImageIcon, or null if the path was invalid.
     *
     * @param path
     * @param description
     * @return
     */
    protected ImageIcon createImageIcon(String path, String description) {
        URL imgURL = getClass().getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL, description);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }

    public void setEditingRowPolicy(EditingRowPolicy editingRowPolicy) {
        this.editingRowPolicy = editingRowPolicy;
    }

    public void removeAllRows() {
        Iterator iterator = values.iterator();
        while (iterator.hasNext()) {
            Object o = iterator.next();
            iterator.remove();
        }
        fireTableDataChanged();
    }

    public void setReadOnly(boolean readOnly) {
        isReadOnly = readOnly;
    }

    public boolean hasEditingRowPolicy() {
        return editingRowPolicy != null;
    }
}