Question

either this doesn't exist, or I'm not thinking/searching correctly because it's late...

I want to set a JTable column width in Swing based on a prototype value for the largest string I expect (or know) to exist in a particular column. I don't know the # of pixels since I don't necessarily know the font at compile time.

Is there a way to set a prototype value for column width purposes, the way there is for row height purposes? If so, how?

Was it helpful?

Solution

Have you tried creating a JLabel at run time and using its size to resize your table?

// create a label that will be using the run-time font
JLabel prototypeLabel = new JLabel("Not Applicable")

// get the labels preferred sizes
int preferredWidth = prototypeLabel.getPreferredSize().getWidth();
int preferredHeight = prototypeLabel.getPreferredSize().getHeight();

// set the sizes of the table's row and columns
myTable.setRowHeight(preferredHeight);

for(TableColumn column : myTable.getColumnModel.getColumns()){
   column.setPreferredWidth(preferredWidth);        
}

OTHER TIPS

You can try the following code:

/**
 * Sets the preferred width of the columns of a table from prototypes
 * @param table the target table
 * @param prototypes an array of prototypes, {@code null} values will be ignored
 * @param setMaxWidth {@code true} if the maximum column width should also be set
 */
public static void setWidthFromPrototype(JTable table, Object[] prototypes, boolean setMaxWidth) {
if (prototypes.length != table.getColumnCount())
  throw new IllegalArgumentException("The prototypes array should contain exactly one element per table column");
for (int i = 0; i < prototypes.length; i++) {
    if (prototypes[i] != null) {
        Component proto = table.getCellRenderer(0,i)
                .getTableCellRendererComponent(table, prototypes[i], false, false, 0, i);
        int prefWidth = (int) proto.getPreferredSize().getWidth() + 1;
        table.getColumnModel().getColumn(i).setPreferredWidth(prefWidth);
        if (setMaxWidth)
            table.getColumnModel().getColumn(i).setMaxWidth(prefWidth);
    }
}
}

SwingX extended JXTable/Column support setting prototypes for initial column width sizing, you can do so either after the columns have been created

for(int col = 0; ....) {
    table.getColumnExt(col).setPrototypeValue(myPrototype[col]
}

or by implementing a custom ColumnFactory which configures the columns on creation

ColumnFactory factory = new ColumnFactory() {
    @Override
    protected void configureTableColumn(TableModel model, TableColumnExt columnExt) {
        super(...);
        columnExt.setPrototypeValue(myPrototype[columnExt.getModelIndex()];
    }
}
table.setColumnFactory(factory);
table.setModel(myModel);

Instead of creating a Label, get the actual component from the TableCellRenderer and test the size on that:

// create the component that will be used to render the cell
Comp prototype = table.getDefaultRenderer(model.getColumnClass(i)).getTableCellRendererComponent(table, "Not Applicable", false, false, 0, i);

// get the labels preferred sizes
int preferredWidth = comp.getPreferredSize().getWidth();
int preferredHeight = comp.getPreferredSize().getHeight();

This is a single column example, you'll need to repeat this to get the size for each column (and also set it). See http://www.exampledepot.com/egs/javax.swing.table/PackCol.html for an example of this.

If you don't know the font at compile time then the width of any JTable column is always going to be unknown. As a sanity check, open a text document and play with different fonts whilst keeping the point size constant. The length of what is written varies on a font-by-font basis but the height doesn't.

The height of a JTable row should be able to be determined for any font size (in points) as it is a defined standard. It might take a bit of experimenting, though, given that JTable probably gives a bit of spacing inbetween cells.

If you can't guarantee neither the font size nor the font itself at compile time then I'm interested in what answers other people come up with :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top