import javax.swing.JTable;
import javax.swing.table.TableModel;
import javax.swing.table.TableColumnModel;

import javax.swing.Scrollable;
import javax.swing.SwingConstants;

import javax.swing.event.ChangeEvent;

import java.awt.Dimension;
import java.awt.Insets;

import java.awt.Component;


/** JTable that does not do any layout but takes the width from the TableColumnModel verbatim.
    Column widths can be set directly on the TableColumns.

    (getXXXWidth adjusted to this width, the TableColumn's properties are
    not used here (but minimum/maximum still constrain the TableColumn's width)).

    The auto resize mode value does not matter anymore.

    HorizontalHeader is used because a) it does not really make sense that
    the header still calculates its preferred etc. width based on the TableColumns',
    b) actually a JScrollPane irregularity causes layout/repaint problems otherwise.

    (C) 2003 Christian Kaufhold
*/
    
public class FixedWidthTable
    extends JTable
{
    public FixedWidthTable(TableModel data, TableColumnModel columns)
    {
        super(data, columns);

        setTableHeader(new HorizontalHeader(columns));
    }



    public Dimension getMinimumSize()
    {
        if (isMinimumSizeSet())
            return super.getMinimumSize();

        return preferredSize_impl();
    }


    public Dimension getMaximumSize()
    {
        if (isMaximumSizeSet())
            return super.getMaximumSize();

        return preferredSize_impl();
    }

    public Dimension getPreferredSize()
    {
        if (isPreferredSizeSet())
            return super.getPreferredSize();

        return preferredSize_impl();
    }


    private Dimension preferredSize_impl()
    {
        Dimension result = new Dimension(super.getPreferredSize());

        Insets n = getInsets();

        result.width = getColumnModel().getTotalColumnWidth() + n.left + n.right;

        return result;
    }
    


    public boolean getScrollableTracksViewportWidth()
    {
        return getParent().getWidth() > getPreferredSize().width; // do not underflow
    }

   
    public void columnMarginChanged(ChangeEvent e)
    {
        // Do not adjust preferred column width

        resizeAndRepaint();
    }


    public void doLayout()
    {
        // Do not adjust column widths
    }


    public void sizeColumnsToFit(int resizingColumn)
    {
        // Do not adjust column widths
    }


    // getCellRect is broken for RTL if the table's width is larger than the columns. Fix not included here. See FTable.




    public static void main(String[] args)
    {
        TableColumnModel data = new javax.swing.table.DefaultTableColumnModel();

        for (int i = 0; i < args.length; i++)
        {
            javax.swing.table.TableColumn c = new javax.swing.table.TableColumn(i);
            
            c.setHeaderValue(args[i]);

            data.addColumn(c);
        }


        JTable t = new FixedWidthTable(new javax.swing.table.DefaultTableModel(20, data.getColumnCount()), data);
       
        javax.swing.JFrame f = new javax.swing.JFrame();

        f.getContentPane().add(new javax.swing.JScrollPane(t));

        f.pack(); f.show();
    }
}







