001    /*
002     * $Id: ColumnFactory.java,v 1.4 2005/10/10 18:03:03 rbair Exp $
003     *
004     * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005     * Santa Clara, California 95054, U.S.A. All rights reserved.
006     *
007     * This library is free software; you can redistribute it and/or
008     * modify it under the terms of the GNU Lesser General Public
009     * License as published by the Free Software Foundation; either
010     * version 2.1 of the License, or (at your option) any later version.
011     * 
012     * This library is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015     * Lesser General Public License for more details.
016     * 
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this library; if not, write to the Free Software
019     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020     */
021    package org.jdesktop.swingx.table;
022    
023    import java.awt.Component;
024    import java.awt.Dimension;
025    
026    import javax.swing.table.JTableHeader;
027    import javax.swing.table.TableCellRenderer;
028    import javax.swing.table.TableModel;
029    
030    import org.jdesktop.swingx.JXTable;
031    
032    /**
033     * Creates and configures TableColumns.
034     * 
035     * @author Jeanette Winzenburg
036     */
037    public class ColumnFactory {
038        
039        private static ColumnFactory columnFactory;
040        
041        public static synchronized ColumnFactory getInstance() {
042            if (columnFactory == null) {
043                columnFactory = new ColumnFactory();
044            }
045            return columnFactory;
046        }
047    
048        public static synchronized void  setInstance(ColumnFactory factory) {
049            columnFactory = factory;
050        }
051        
052        public TableColumnExt createTableColumn(int modelIndex) {
053            return new TableColumnExt(modelIndex);
054        }
055        
056        /**
057         * Configure column properties from TableModel.
058         * 
059         * @param model
060         * @param column
061         * @throws NPE if model or column == null
062         * @throws IllegalStateException if column does not have valid modelIndex
063         *   (in coordinate space of the tablemodel)
064         */
065        public void configureTableColumn(TableModel model, TableColumnExt column) {
066            if ((column.getModelIndex() < 0) 
067                    || (column.getModelIndex() >= model.getColumnCount())) 
068                throw new IllegalStateException("column must have valid modelIndex");
069            column.setHeaderValue(model.getColumnName(column.getModelIndex()));
070    
071        }
072        
073        public TableColumnExt createAndConfigureTableColumn(TableModel model, int modelIndex) {
074            TableColumnExt column = createTableColumn(modelIndex);
075            configureTableColumn(model, column);
076            return column;
077        }
078    
079        public void configureColumnWidths(JXTable table, TableColumnExt columnx) {
080            Dimension cellSpacing = table.getIntercellSpacing();
081            Object prototypeValue = columnx.getPrototypeValue();
082            if (prototypeValue != null) {
083                // calculate how much room the prototypeValue requires
084                TableCellRenderer renderer = table.getCellRenderer(0, table
085                        .convertColumnIndexToView(columnx.getModelIndex()));
086                Component comp = renderer.getTableCellRendererComponent(table,
087                        prototypeValue, false, false, 0, 0);
088                int prefWidth = comp.getPreferredSize().width + cellSpacing.width;
089    
090                // now calculate how much room the column header wants
091                renderer = columnx.getHeaderRenderer();
092                if (renderer == null) {
093                    JTableHeader header = table.getTableHeader();
094                    if (header != null) {
095                        renderer = header.getDefaultRenderer();
096                    }
097                }
098                if (renderer != null) {
099                    comp = renderer.getTableCellRendererComponent(table, columnx
100                            .getHeaderValue(), false, false, 0, table
101                            .convertColumnIndexToView(columnx.getModelIndex()));
102    
103                    prefWidth = Math.max(comp.getPreferredSize().width, prefWidth);
104                }
105                prefWidth += table.getColumnModel().getColumnMargin();
106                columnx.setPreferredWidth(prefWidth);
107            }
108    
109        }
110    
111        public void packColumn(JXTable table, TableColumnExt col, int margin, int max) {
112    
113            /* Get width of column header */
114            TableCellRenderer renderer = col.getHeaderRenderer();
115            if (renderer == null) 
116                renderer = table.getTableHeader().getDefaultRenderer();
117            
118            int width = 0;
119            
120            Component comp = renderer.getTableCellRendererComponent(table, col
121                    .getHeaderValue(), false, false, 0, 0);
122            width = comp.getPreferredSize().width;
123            
124            int column = table.convertColumnIndexToView(col.getModelIndex());
125            if(table.getRowCount() > 0)
126                renderer = table.getCellRenderer(0, column);
127            for (int r = 0; r < table.getRowCount(); r++) {
128                comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r,
129                        column), false, false, r, column);
130                width = Math.max(width, comp.getPreferredSize().width);
131            }
132            width += 2 * margin;
133    
134            /* Check if the width exceeds the max */
135            if( max != -1 && width > max )
136                width = max;
137            
138            col.setPreferredWidth(width);
139            
140        }
141    }