TableHeader Resizing Problem

Hello everyone.

I am trying to work out a header_resizable table with specified header height,

but when drag the next to the last column's header make the last one dispeared.

I've got a workaround by making the header's preferredSize wide enough,

but want to know what the gulus will do in this situation.

Can anybody explain me why this happaned, and teach me the ultimate solution?

Thanks for any reply in advance.

Here is the so-called SSCCE.

import java.awt.BorderLayout;

import java.awt.Dimension;

import javax.swing.JFrame;

import javax.swing.JScrollPane;

import javax.swing.JTable;

import javax.swing.table.DefaultTableModel;

publicclass TableHeaderResizeTestextends JFrame{

private TableHeaderResizeTest(){

int colNum = 4;

int rowNum = 4;

String[] columnNames =new String[colNum];

String[][] tableData =new String[rowNum][colNum];

for (int i = 0; i < columnNames.length; i++){

columnNames[i]="COLUMN"+i;

}

for (int i = 0; i < tableData.length; i++){

for (int j = 0; j < tableData[i].length; j++){

tableData[i][j] ="R"+i+"C"+j;

}

}

JTable jt =new JTable();

JScrollPane jsp =new JScrollPane(jt);

jsp.setPreferredSize(new Dimension(400,200));

jt.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

DefaultTableModel dtm =new DefaultTableModel(tableData,columnNames);

jt.setModel(dtm);

for (int i = 0; i < colNum; i++){

jt.getColumnModel().getColumn(i).setPreferredWidth(200);

}

Dimension d = jt.getTableHeader().getPreferredSize();

//if wide enough, it seemed help to excute normally

//d.width =1000000;

d.height = 40;

jt.getTableHeader().setPreferredSize(d);

getContentPane().setLayout(new BorderLayout());

getContentPane().add(jsp,BorderLayout.CENTER);

}

publicstaticvoid main(String[] args){

JFrame f =new TableHeaderResizeTest();

f.setTitle("JTableExTest");

f.pack();

f.setDefaultCloseOperation(EXIT_ON_CLOSE);

f.setLocationRelativeTo(null);

f.setResizable(true);

f.setVisible(true);

}

}

The problem is: If you drag the COLUMN2 to some extent, the COLUMN3 will disapear.

[3989 byte] By [morning3evening4a] at [2007-11-27 11:10:38]
# 1

I believe the problem is that when you set the preferred size of the header, it never changes size even when you change the widths of the columns. So you don't want to manually set the preferred size.

If you want extra space in the header then the easiest approach would be to add an EmptyBorder to the renderer. Unfortunately the default renderer was poorly written and every time the cell is renderered it resets the Border to the default Border.

So you basically need to create a custom renderer. Here is one way to do this:

JTableHeader header = table.getTableHeader();

TableCellRenderer defaultRenderer = header.getDefaultRenderer();

header.setDefaultRenderer( new MyTableHeaderRenderer(defaultRenderer) );

...

class MyTableHeaderRenderer implements TableCellRenderer

{

private TableCellRenderer tableCellRenderer;

private Border border;

public MyTableHeaderRenderer(TableCellRenderer tableCellRenderer)

{

this.tableCellRenderer = tableCellRenderer;

JLabel label = (JLabel)tableCellRenderer;

Border current = UIManager.getBorder("TableHeader.cellBorder");

Border empty = new EmptyBorder(10, 0, 10, 0);

border = new CompoundBorder(current, empty);

}

public Component getTableCellRendererComponent(JTable table, Object value,

boolean isSelected, boolean hasFocus, int row, int column)

{

Component c = tableCellRenderer.getTableCellRendererComponent(table, value,

isSelected, hasFocus, row, column);

JLabel l = (JLabel) c;

l.setBorder(border);

return c;

}

}

camickra at 2007-7-29 13:42:58 > top of Java-index,Desktop,Core GUI APIs...
# 2

Thanks for your reply, camickr .

I have tried your suggestion , but i am afraid it doesn't turn out to be perfectly.

When i extend some column header, the last column header' s text will disapear, even having added the compound border.

By the way , my java is 1.42_03 and OS is WinXp.

If there is no better solution, i prefer to set the header's preferredsize wide enough.

Anyway , thany you for your suggestion.

morning3evening4a at 2007-7-29 13:42:58 > top of Java-index,Desktop,Core GUI APIs...
# 3

> By the way , my java is 1.42_03 and OS is WinXp.

I'm using 1.4.2_06 on XP

> If there is no better solution,

Works perfect for me.

If you need further help then you need to create a "Short, Self Contained, Compilable and Executable, Example Program (SSCCE)",

see http://homepage1.nifty.com/algafield/sscce.html,

that demonstrates the incorrect behaviour, because I can't guess exactly what you are doing based on the information provided.

Don't forget to use the "Code Formatting Tags",

see http://forum.java.sun.com/help.jspa?sec=formatting,

so the posted code retains its original formatting.

camickra at 2007-7-29 13:42:58 > top of Java-index,Desktop,Core GUI APIs...
# 4

OK, i want further help if possible, and here is my SSCCE.

It works not very fine for me , maybe i missed something.

I am sorry that it is a little long .

import java.awt.BorderLayout;

import java.awt.Component;

import java.awt.Dimension;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JScrollPane;

import javax.swing.JTable;

import javax.swing.UIManager;

import javax.swing.border.Border;

import javax.swing.border.CompoundBorder;

import javax.swing.border.EmptyBorder;

import javax.swing.table.DefaultTableModel;

import javax.swing.table.JTableHeader;

import javax.swing.table.TableCellRenderer;

public class TableHeaderResizeTest extends JFrame {

private TableHeaderResizeTest(){

int colNum = 4;

int rowNum = 4;

String[] columnNames = new String[colNum];

String[][] tableData = new String[rowNum][colNum];

for (int i = 0; i < columnNames.length; i++) {

columnNames[i]= "COLUMN"+i;

}

for (int i = 0; i < tableData.length; i++) {

for (int j = 0; j < tableData[i].length; j++) {

tableData[i][j] = "R"+i+"C"+j;

}

}

JTable jt = new JTable();

jt.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

DefaultTableModel dtm = new DefaultTableModel(tableData,columnNames);

jt.setModel(dtm);

for (int i = 0; i < colNum; i++) {

jt.getColumnModel().getColumn(i).setPreferredWidth(200);

}

JTableHeader header = jt.getTableHeader();

TableCellRenderer defaultRenderer = header.getDefaultRenderer();

header.setDefaultRenderer( new MyTableHeaderRenderer(defaultRenderer) );

Dimension d = header.getPreferredSize();

//if wide enough, it seemed help to excute normally

//d.width =1000000;

d.height = 40;

header.setPreferredSize(d);

JScrollPane jsp = new JScrollPane(jt);

jsp.setPreferredSize(new Dimension(400,200));

getContentPane().setLayout(new BorderLayout());

getContentPane().add(jsp,BorderLayout.CENTER);

}

private class MyTableHeaderRenderer implements TableCellRenderer

{

private TableCellRenderer tableCellRenderer;

private Border border;

public MyTableHeaderRenderer(TableCellRenderer tableCellRenderer)

{

this.tableCellRenderer = tableCellRenderer;

//JLabel label = (JLabel)tableCellRenderer;

Border current = UIManager.getBorder("TableHeader.cellBorder");

Border empty = new EmptyBorder(10, 0, 10, 0);

border = new CompoundBorder(current, empty);

}

public Component getTableCellRendererComponent(JTable table, Object value,

boolean isSelected, boolean hasFocus, int row, int column)

{

Component c = tableCellRenderer.getTableCellRendererComponent(table, value,

isSelected, hasFocus, row, column);

JLabel l = (JLabel) c;

l.setBorder(border);

return c;

}

}

public static void main(String[] args) {

JFrame f = new TableHeaderResizeTest();

f.setTitle("TableHeaderResizeTest");

f.pack();

f.setDefaultCloseOperation(EXIT_ON_CLOSE);

f.setLocationRelativeTo(null);

f.setResizable(true);

f.setVisible(true);

}

}

Message was edited by:

morning3evening4

morning3evening4a at 2007-7-29 13:42:58 > top of Java-index,Desktop,Core GUI APIs...
# 5

> It works not very fine for me , maybe i missed something.

What did I say in the first two sentences of my original reply?

camickra at 2007-7-29 13:42:58 > top of Java-index,Desktop,Core GUI APIs...
# 6

I got it !

Wow , what a fool I am.

Thank you camickr !

morning3evening4a at 2007-7-29 13:42:58 > top of Java-index,Desktop,Core GUI APIs...