001    package org.objectweb.jac.aspects.gui.swing;
002    
003    import java.awt.Component;
004    import javax.swing.event.TableModelEvent;
005    import javax.swing.table.TableCellRenderer;
006    import org.apache.log4j.Logger;
007    
008    /**
009     * A table with variable height rows. The height of a row is the
010     * maximum preferred height of its cells.
011     */
012    public class JTable extends javax.swing.JTable {
013        static Logger logger = Logger.getLogger("gui.swing");
014    
015        /**
016         * Recompute row height on tableChanged events
017         */
018        public void tableChanged(TableModelEvent e) {
019            super.tableChanged(e);
020            setPreferredRowHeights(1);
021        }
022    
023        /**
024         * Compute preferred height of all rows
025         * @param margin margin in pixels to add at the top and bottom of
026         * each row
027         */
028        public void setPreferredRowHeights(int margin) {
029            for (int row=0; row<getRowCount(); row++) {
030                setPreferredRowHeight(row,margin);
031            }
032        }
033    
034        /**
035         * Compute the preferred height of a row
036         * @param row row index
037         * @param margin margin in pixels to add at the top and bottom of
038         * the row
039         */
040        public void setPreferredRowHeight(int row, int margin) {
041            // Get the current default height for all rows
042            int height = getRowHeight();
043          
044            // Determine highest cell in the row
045            for (int col=0; col<getColumnCount(); col++) {
046                try {
047                    TableCellRenderer renderer = getCellRenderer(row,col);
048                    if (renderer!=null) {
049                        Component comp = prepareRenderer(renderer,row,col);
050                        if (comp!=null) {
051                            comp.validate();
052                            int h = comp.getPreferredSize().height + 2*margin;
053                            height = Math.max(height,h);
054                        }
055                    }
056                } catch (Exception e) {
057                    logger.error("Failed to compute cell height for ("+row+","+col+")",e);
058                }
059            }
060            setRowHeight(row,height);
061        }
062    
063        public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
064            try {
065                return super.prepareRenderer(renderer,row,column);
066            } catch (Exception e) {
067                logger.error("Caught exception in prepareRenderer("+row+","+column+")",e);
068                return null;
069            }
070        }
071    }