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

net.sf.cuf.ui.table.TableProperties Maven / Gradle / Ivy

The newest version!
package net.sf.cuf.ui.table;

import java.util.Properties;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import javax.swing.JTable;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

/**
 * Helper for setting and getting JTable-Properties such as Order of Columns or Columnwidths.
 *
 * @author  Jörg Eichhorn, sd&m AG
 */
public class TableProperties
{
    // default prefix
    private static final String TABLE     = "TABLE";
    // Propertykey to use for tablewidth
    private static final String WIDTH_KEY = ".WIDTH.";
    // Propertykey to use for tableColumIndex
    private static final String INDEX_KEY = ".INDEX.";
    // Propertykey to use for sort order
    private static final String ORDER_KEY = ".ORDER_";
    private static final String ORDER_SUF = ".";
    // Values for sort order
    private static final String ASC_VAL = "ASCENDING";
    private static final String DESC_VAL = "DESCENDING";

    /**
     * We provide only static helpers
     */
    private TableProperties()
    {
    }

    /**
     * @link dependency
     * @stereotype access
     */
    /*#JTable lnkJTable;*/

    /**
     * Load (i.e. initialize) the Table with specified Properties.
     *
     * @param pTable the JTable to load the Properties into
     * @param pProperties the Properties to use for pTable
     * @param pPrefix an optional Prefix to use for the Propertykeys.
     *        If null, pTable.getName() will be used
     */
    public static void load(final JTable pTable, final Properties pProperties, final String pPrefix)
    {
        // check params first
        if (pTable == null) throw new IllegalArgumentException("pTable must not be null");
        if (pProperties == null) throw new IllegalArgumentException("pProperties must not be null");
        // safe to use pTable and pProperties now

        // setup prefix
        String prefix = (pPrefix == null ? pTable.getName() : pPrefix);
        prefix = (prefix == null ? TABLE : prefix);

        // tableColumns are managed by a tableColumnModel
        TableModel model = pTable.getModel();
        TableColumnModel tableColumnModel= pTable.getColumnModel();

        // flag if we detected corrupt data
        boolean dataCorrupt= false;

        // fetch users column-widths from properties
        // We have to do this before we start removing columns from the column model.
        for (int modelIndex = 0; modelIndex < model.getColumnCount(); modelIndex++)
        {
            String key              = prefix + WIDTH_KEY + modelIndex;
            String columnWidthString= pProperties.getProperty(key);
            int    columnWidth;


            try
            {
                columnWidth= Integer.parseInt(columnWidthString);
            }
            catch (NumberFormatException ex)
            {
                // ignore preferences
                dataCorrupt= true;
                break;
            }

            int viewIndex = pTable.convertColumnIndexToView(modelIndex);
            tableColumnModel.getColumn(viewIndex).setPreferredWidth(columnWidth);
        }

        // setup int-array for users column-ordering
        int[] userPosition = new int[model.getColumnCount()];
        for (int i = 0; i < userPosition.length; i++) userPosition[i] = -1;

        // fetch users column-ordering from properties into array
        for (int modelIndex = 0, n= userPosition.length; modelIndex < n; modelIndex++)
        {
            String key = prefix + INDEX_KEY + modelIndex;
            String viewIndexString = pProperties.getProperty(key);

            if (viewIndexString != null)
            {
                try
                {
                    int viewIndex= Integer.parseInt(viewIndexString);

                    if (viewIndex>=n)
                    {
                        // ignore preferences
                        dataCorrupt= true;
                        break;
                    }
                    if (viewIndex >= 0)
                    {
                        userPosition[modelIndex] = viewIndex;
                    }
                }
                catch (NumberFormatException e)
                {
                    // ignore preferences
                    dataCorrupt= true;
                    break;
                }
            }
        }

        // check if it is better to ignore preferences
        if (dataCorrupt)
        {
            //noinspection UseOfSystemOutOrSystemErr
            System.err.println("table properties corrupt");
            return;
        }

        SortingTable sortingTable= null;
        if (pTable instanceof SortingTable)
        {
            sortingTable= (SortingTable)pTable;
        }

        // check if userPosition is o.k. (no duplicated indexes, no index
        // larger than size, no missing indexes)
        Set usedIndexes= new HashSet(userPosition.length);
        for (int modelIndex = 0; modelIndex < userPosition.length; modelIndex++)
        {
            if ((userPosition[modelIndex]>=userPosition.length) || (userPosition[modelIndex]<-1))
            {
                userPosition[modelIndex]= -1;
            }
            else if (userPosition[modelIndex] != -1)
            {
                Integer userPositionInteger= userPosition[modelIndex];
                if (usedIndexes.contains(userPositionInteger))
                {
                    userPosition[modelIndex]= -1;
                }
                else
                {
                    usedIndexes.add(userPositionInteger);
                }
            }

        }

        // move tablecolumns around
        moveTableColumns(pTable, userPosition);

        // hide columns
        if (sortingTable!=null)
        {
            for (int modelIndex = 0; modelIndex < userPosition.length; modelIndex++)
            {
                if (userPosition[modelIndex]<0)
                {
                    sortingTable.setColumnVisible(modelIndex, false);
                }
            }
        }

        // restore load last sortorder, if tableModel is a TableSorter
        if (model instanceof TableSorter)
        {
            TableSorter sorter = (TableSorter) model;

            for (int prio = 0; prio < sorter.getColumnCount(); prio++)
            {
                for (int column = 0; column < sorter.getColumnCount(); column++)
                {
                    String key = prefix + ORDER_KEY + prio + ORDER_SUF + column;

                    String sortOrder = pProperties.getProperty(key);

                    if (sortOrder != null)
                    {

                        sorter.sortByColumn(column, sortOrder.equalsIgnoreCase(ASC_VAL));
                    }
                }
            }
        }
    }

    /**
     * Store Table into specified Properties.
     *
     * @param pTable the JTable to store into the Properties
     * @param pProperties the Properties to use for pTable
     * @param pPrefix an optional Prefix to use for the Propertykeys.
     *  If null pTable.getName() will be used
     */
    public static void store(final JTable pTable, final Properties pProperties, final String pPrefix)
    {
        // FIXME: irgendwo hier ist noch ein Bug, manchmal wird beim
        //        rausschreiben ein Spalte doppelt vergeben?!

        // check params first
        if (pTable == null) throw new IllegalArgumentException("pTable must not be null");
        if (pProperties == null) throw new IllegalArgumentException("pProperties must not be null");
        // safe to use pTable and pProperties now

        // setup prefix
        String prefix = (pPrefix == null ? pTable.getName() : pPrefix);
        prefix = (prefix == null ? TABLE : prefix);

        // remove all old data
        Iterator it= pProperties.keySet().iterator();
        while (it.hasNext())
        {
            Object o = it.next();
            if ((o==null) ||
                o.toString().startsWith(prefix))
            {
                it.remove();
            }
        }


        // store width and modelIndex of each tablecolumn into pProperties.
        // we need the tableColumnModel for this.
        TableModel model = pTable.getModel();
        TableColumnModel tableColumnModel = pTable.getColumnModel();
        for (int modelIndex = 0; modelIndex < model.getColumnCount(); modelIndex++)
        {
            int viewIndex = pTable.convertColumnIndexToView(modelIndex);

            pProperties.put(prefix + INDEX_KEY + modelIndex, String.valueOf(viewIndex));

            if (viewIndex >= 0)
            {
                pProperties.put(prefix + WIDTH_KEY + modelIndex, String.valueOf(tableColumnModel.getColumn(viewIndex).getWidth()));
            }
            else if (pTable instanceof SortingTable)
            {
                pProperties.put(prefix + WIDTH_KEY + modelIndex, String.valueOf(((SortingTable) pTable).getInvisibleColumn(modelIndex).getWidth()));
            }
        }

        // store current sortorder, if tableModel is a TableSorter
        if (model instanceof TableSorter)
        {
            TableSortInfo sortedColumns = ((TableSorter) model).getSortInfo();

            for (int prio = 0; prio < sortedColumns.size(); prio++)
            {
                String orderVal = sortedColumns.isAscending(prio) ? ASC_VAL : DESC_VAL;
                pProperties.put(prefix + ORDER_KEY + prio + ORDER_SUF + sortedColumns.getColumn(prio), orderVal);
            }
        }
    }

    /**
     * Move columns in tableColumnModel around, so that they are in the order given by array userPosition.
     *
     * @param pTable our JTable containing the columns to move around
     * @param pUserPosition int-array with users column-ordering
     */
    private static void moveTableColumns(final JTable pTable, final int[] pUserPosition)
    {
        // current position of tablecolumn is in actualPosition
        int[] actualPosition = new int[pUserPosition.length];

        boolean done = false;

        while (!done)
        {
            // what's the current order of our columns?
            for (int modelIndex = 0; modelIndex < actualPosition.length; modelIndex++)
            {
                actualPosition[modelIndex] = pTable.convertColumnIndexToView(modelIndex);
            }

            // Let's assume that everything is alright
            done = true;
            for (int modelIndex = 0; modelIndex < pUserPosition.length; modelIndex++)
            {
                if (pUserPosition[modelIndex] > 0 && actualPosition[modelIndex] != pUserPosition[modelIndex])
                {
                    // oops, one columns not where we want it: move it
                    pTable.moveColumn(actualPosition[modelIndex], pUserPosition[modelIndex]);
                    // sorry, not done yet
                    done = false;
                    // moveColumn() changed order of columns, start again
                    break;
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy