JTable and JScrollPane issues

I'm trying to distribute the columns of a JTable over the available width of a JScrollPane.

I have this code to achieve it:TableColumnModel columnModel = table.getColumnModel();

int columnCount = columnModel.getColumnCount();

int totalWidth = scrollPane.getWidth();

int columnWidth = totalWidth / columnCount;

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

TableColumn column = columnModel.getColumn(i);

column.setPreferredWidth(columnWidth);

}

If I run this in a test program it does as anticipated but if I run it my actual program it doesn't: http://users.pandora.be/nicks_auditorium/java/screenshot_1.JPG. This is the result of the test program: http://users.pandora.be/nicks_auditorium/java/screenshot_2.JPG

I don't understand why I doesn't behave as it should. I did notice that when I run it in the debugger, the scroll pane's width and height and its view port's are all 0.

Any ideas?

Test program:publicclass TestTableFrameextends javax.swing.JFrame{

public TestTableFrame(){

initComponents();

TableColumnModel columnModel = jTable1.getColumnModel();

int columnCount = columnModel.getColumnCount();

int totalWidth = jScrollPane1.getViewport().getWidth();

int columnWidth = totalWidth / columnCount;

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

TableColumn column = columnModel.getColumn(i);

column.setPreferredWidth(columnWidth);

}

}

privatevoid initComponents(){

jScrollPane1 =new javax.swing.JScrollPane();

jTable1 =new javax.swing.JTable();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jTable1.setModel(new javax.swing.table.DefaultTableModel(

new Object [][]{

{null, null, null,null},

{null, null, null,null},

{null, null, null,null},

{null, null, null,null}

},

new String []{

"Title 1","Title 2","Title 3","Title 4"

}

));

jScrollPane1.setViewportView(jTable1);

org.jdesktop.layout.GroupLayout layout =new org.jdesktop.layout.GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

.add(layout.createSequentialGroup()

.addContainerGap()

.add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)

.addContainerGap())

);

layout.setVerticalGroup(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

.add(layout.createSequentialGroup()

.addContainerGap()

.add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE)

.addContainerGap())

);

pack();

}

publicstaticvoid main(String args[]){

java.awt.EventQueue.invokeLater(new Runnable(){

publicvoid run(){

new TestTableFrame().setVisible(true);

}

});

}

private javax.swing.JScrollPane jScrollPane1;

private javax.swing.JTable jTable1;

}

Real code:publicclass TestScrollPaneextends JFrame{

public TestScrollPane()throws HeadlessException{

MessageDetailsPanel panel =new MessageDetailsPanel();

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

pack();

}

publicstaticvoid main(String[] args){

java.awt.EventQueue.invokeLater(new Runnable(){

publicvoid run(){

new TestScrollPane().setVisible(true);

}

});

}

}

publicclass MessageDetailsPanelextends javax.swing.JPanel{

public MessageDetailsPanel(){

initComponents();

logTable.setModel(new javax.swing.table.DefaultTableModel(

new Object [][]{

{null, null, null,null}

},

new String []{

"Title 1","Title 2","Title 3","Title 4"

}

));

TableColumnModel columnModel = logTable.getColumnModel();

int columnCount = columnModel.getColumnCount();

int totalWidth = logScrollPane.getViewport().getWidth();

int columnWidth = totalWidth / columnCount;

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

TableColumn column = columnModel.getColumn(i);

column.setPreferredWidth(columnWidth);

}

}

privatevoid initComponents(){

replyButton =new javax.swing.JButton();

forwardButton =new javax.swing.JButton();

subjectLabel =new javax.swing.JLabel();

subjectScrollPane =new javax.swing.JScrollPane();

subjectTextArea =new javax.swing.JTextArea();

contentLabel =new javax.swing.JLabel();

contentScrollPane =new javax.swing.JScrollPane();

contentTextArea =new javax.swing.JTextArea();

openCloseButton =new javax.swing.JButton();

firstSeparator =new javax.swing.JSeparator();

priorityLabel =new javax.swing.JLabel();

priorityTextField =new javax.swing.JTextField();

dateLabel =new javax.swing.JLabel();

dateTextField =new javax.swing.JTextField();

importanceLabel =new javax.swing.JLabel();

importanceTextField =new javax.swing.JTextField();

dueDateLabel =new javax.swing.JLabel();

dueDateTextField =new javax.swing.JTextField();

fromLabel =new javax.swing.JLabel();

fromTextField =new javax.swing.JTextField();

toLabel =new javax.swing.JLabel();

secondSeparator =new javax.swing.JSeparator();

logScrollPane =new javax.swing.JScrollPane();

logTable =new javax.swing.JTable();

commentTextField =new javax.swing.JTextField();

addCommentButton =new com.fpc.nokeos.core.client.jide.NokeosButton();

toTextField =new javax.swing.JTextField();

replyButton.setText("Reply");

replyButton.addActionListener(new java.awt.event.ActionListener(){

publicvoid actionPerformed(java.awt.event.ActionEvent evt){

replyButtonActionPerformed(evt);

}

});

forwardButton.setText("Forward");

forwardButton.addActionListener(new java.awt.event.ActionListener(){

publicvoid actionPerformed(java.awt.event.ActionEvent evt){

forwardButtonActionPerformed(evt);

}

});

subjectLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

subjectLabel.setLabelFor(subjectTextArea);

subjectLabel.setText("Subject:");

subjectTextArea.setBackground(javax.swing.UIManager.getDefaults().getColor("Panel.background"));

subjectTextArea.setEditable(false);

subjectTextArea.setLineWrap(true);

subjectTextArea.setWrapStyleWord(true);

subjectScrollPane.setViewportView(subjectTextArea);

contentLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

contentLabel.setLabelFor(contentTextArea);

contentLabel.setText("Content:");

contentTextArea.setBackground(javax.swing.UIManager.getDefaults().getColor("Panel.background"));

contentTextArea.setLineWrap(true);

contentTextArea.setWrapStyleWord(true);

contentScrollPane.setViewportView(contentTextArea);

openCloseButton.setText("Open/Close Message");

openCloseButton.addActionListener(new java.awt.event.ActionListener(){

publicvoid actionPerformed(java.awt.event.ActionEvent evt){

openCloseButtonActionPerformed(evt);

}

});

priorityLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

priorityLabel.setLabelFor(priorityTextField);

priorityLabel.setText("Priority:");

priorityTextField.setEditable(false);

dateLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

dateLabel.setLabelFor(dateTextField);

dateLabel.setText("Date:");

dateTextField.setEditable(false);

importanceLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

importanceLabel.setLabelFor(importanceTextField);

importanceLabel.setText("Importance:");

importanceTextField.setEditable(false);

dueDateLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

dueDateLabel.setLabelFor(dueDateTextField);

dueDateLabel.setText("Due date:");

dueDateTextField.setEditable(false);

fromLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

fromLabel.setLabelFor(fromTextField);

fromLabel.setText("From:");

fromTextField.setEditable(false);

toLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

toLabel.setLabelFor(toTextField);

toLabel.setText("To:");

logTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);

logScrollPane.setViewportView(logTable);

addCommentButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/graphics/add.gif")));

addCommentButton.addActionListener(new java.awt.event.ActionListener(){

publicvoid actionPerformed(java.awt.event.ActionEvent evt){

addCommentButtonActionPerformed(evt);

}

});

toTextField.setEditable(false);

org.jdesktop.layout.GroupLayout layout =new org.jdesktop.layout.GroupLayout(this);

this.setLayout(layout);

layout.setHorizontalGroup(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING).add(

layout.createSequentialGroup().addContainerGap().add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING).add(logScrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

179, Short.MAX_VALUE).add(

layout.createSequentialGroup().add(replyButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,

org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE).addPreferredGap(

org.jdesktop.layout.LayoutStyle.RELATED).add(forwardButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,

org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)).add(firstSeparator,

org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 179, Short.MAX_VALUE).add(

layout.createSequentialGroup().add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING).add(

org.jdesktop.layout.GroupLayout.LEADING,

layout.createSequentialGroup().add(importanceLabel).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)

.add(importanceTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 21, Short.MAX_VALUE)).add(

org.jdesktop.layout.GroupLayout.LEADING,

layout.createSequentialGroup().add(priorityLabel).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

priorityTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 21, Short.MAX_VALUE)))

.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING).add(

layout.createSequentialGroup().add(dateLabel).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)

.add(dateTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 22, Short.MAX_VALUE)).add(

layout.createSequentialGroup().add(dueDateLabel).addPreferredGap(

org.jdesktop.layout.LayoutStyle.RELATED).add(dueDateTextField,

org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 22, Short.MAX_VALUE)))).add(

layout.createSequentialGroup().add(fromLabel).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(fromTextField,

org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)).add(

layout.createSequentialGroup().add(toLabel).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(toTextField,

org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)).add(

layout.createSequentialGroup().add(contentLabel).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)

.add(contentScrollPane)).add(

org.jdesktop.layout.GroupLayout.TRAILING,

layout.createSequentialGroup().add(subjectLabel).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

subjectScrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)).add(

org.jdesktop.layout.GroupLayout.TRAILING, openCloseButton).add(secondSeparator, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

179, Short.MAX_VALUE).add(

layout.createSequentialGroup().add(commentTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 122, Short.MAX_VALUE)

.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(addCommentButton,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))).addContainerGap()));

layout.linkSize(new java.awt.Component[]{ contentLabel, fromLabel, importanceLabel, priorityLabel, subjectLabel, toLabel},

org.jdesktop.layout.GroupLayout.HORIZONTAL);

layout.linkSize(new java.awt.Component[]{ dateLabel, dueDateLabel}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

layout.linkSize(new java.awt.Component[]{ forwardButton, replyButton}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

layout.setVerticalGroup(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING).add(

layout.createSequentialGroup().add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING).add(replyButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,

org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE).add(forwardButton,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING).add(subjectScrollPane,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 47, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE).add(subjectLabel))

.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING).add(

layout.createSequentialGroup()

.add(contentScrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE).addPreferredGap(

org.jdesktop.layout.LayoutStyle.RELATED).add(openCloseButton)).add(contentLabel)).addPreferredGap(

org.jdesktop.layout.LayoutStyle.RELATED).add(firstSeparator, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 10,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE).add(priorityLabel).add(priorityTextField,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE).add(dateLabel).add(dateTextField,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE).add(importanceLabel).add(importanceTextField,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE).add(dueDateLabel).add(dueDateTextField,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE).add(fromLabel).add(fromTextField,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE).add(toLabel).add(toTextField,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

secondSeparator, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 10, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)

.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(logScrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 49,

Short.MAX_VALUE).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE).add(commentTextField,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,

org.jdesktop.layout.GroupLayout.PREFERRED_SIZE).add(addCommentButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,

org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)).addContainerGap()));

}

privatevoid addCommentButtonActionPerformed(java.awt.event.ActionEvent evt){

}

privatevoid forwardButtonActionPerformed(java.awt.event.ActionEvent evt){

}

privatevoid openCloseButtonActionPerformed(java.awt.event.ActionEvent evt){

}

privatevoid replyButtonActionPerformed(java.awt.event.ActionEvent evt){

}

private com.fpc.nokeos.core.client.jide.NokeosButton addCommentButton;

private javax.swing.JTextField commentTextField;

private javax.swing.JLabel contentLabel;

private javax.swing.JScrollPane contentScrollPane;

private javax.swing.JTextArea contentTextArea;

private javax.swing.JLabel dateLabel;

private javax.swing.JTextField dateTextField;

private javax.swing.JLabel dueDateLabel;

private javax.swing.JTextField dueDateTextField;

private javax.swing.JSeparator firstSeparator;

private javax.swing.JButton forwardButton;

private javax.swing.JLabel fromLabel;

private javax.swing.JTextField fromTextField;

private javax.swing.JLabel importanceLabel;

private javax.swing.JTextField importanceTextField;

private javax.swing.JScrollPane logScrollPane;

private javax.swing.JTable logTable;

private javax.swing.JButton openCloseButton;

private javax.swing.JLabel priorityLabel;

private javax.swing.JTextField priorityTextField;

private javax.swing.JButton replyButton;

private javax.swing.JSeparator secondSeparator;

private javax.swing.JLabel subjectLabel;

private javax.swing.JScrollPane subjectScrollPane;

private javax.swing.JTextArea subjectTextArea;

private javax.swing.JLabel toLabel;

private javax.swing.JTextField toTextField;

}

[26986 byte] By [NickDGa] at [2007-11-27 7:02:48]
# 1
Can't run your code since I aint using netbeans. But here's a quick suggestion, trying changing your table column layout mode, i.e. table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); This just might help
icewalker2ga at 2007-7-12 18:53:54 > top of Java-index,Desktop,Core GUI APIs...
# 2
> trying changing your table> column layout mode, i.e.> table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);> It is set already like that.
NickDGa at 2007-7-12 18:53:54 > top of Java-index,Desktop,Core GUI APIs...
# 3

> the scroll pane's width and height and its view port's are all 0.

Components don't have a size until the frame is visible or you have packed the frame.

In your demo it looks like you use the pack() method before calculating the column widths. In you real program it looks like you do the pack() after calculating the column widths.

camickra at 2007-7-12 18:53:54 > top of Java-index,Desktop,Core GUI APIs...
# 4

Yes, that's the reason! Thanks.

Unfortunately, it makes what I was trying to achieve a lot harder: I was asked to implement the functionality in our project that makes that all tables by default take up all available space and still have AUTO_RESIZE_OFF. If any of the columns is widened, the horizontal scroll bar must appear. I was thinking of extending JTable.

All our GUIs are developed as extending JPanel and they are wrapped in frames by our docking framework. As a consequence, I don't have packed frames when I want to set the column widths.

Do you see a way to accomplish this?

NickDGa at 2007-7-12 18:53:54 > top of Java-index,Desktop,Core GUI APIs...
# 5
> all tables by default take up all available spaceMaybe this approach will work: http://forum.java.sun.com/thread.jspa?forumID=57&threadID=5150554
camickra at 2007-7-12 18:53:55 > top of Java-index,Desktop,Core GUI APIs...
# 6

> > all tables by default take up all available space

>

> Maybe this approach will work:

No, it isn't really what I want.

I thought of using some listener and I did a test with AncestorListener and although my test program (see below) works ok, in the actual application there are places where it doesn't work, where the scroll pane still has 0 width.

Any more ideas? Thanks.

Test program: (this time using BorderLayout) public class MainJFrame extends javax.swing.JFrame {

public MainJFrame() {

initComponents();

}

private void initComponents() {

testJPanel1 = new testing.TestJPanel();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

getContentPane().add(testJPanel1, java.awt.BorderLayout.CENTER);

pack();

}

public static void main(String args[]) {

java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {

new MainJFrame().setVisible(true);

}

});

}

private testing.TestJPanel testJPanel1;

}

and

public class TestJPanel extends javax.swing.JPanel {

public TestJPanel() {

initComponents();

MyTable jTable1 = new MyTable();

jTable1.setModel(new javax.swing.table.DefaultTableModel(

new Object [][] {

{null, null, null, null},

{null, null, null, null}

},

new String [] {

"Title 1", "Title 2", "Title 3", "Title 4"

}

));

jTable1.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);

jScrollPane1.setViewportView(jTable1);

}

private void initComponents() {

jScrollPane1 = new javax.swing.JScrollPane();

setLayout(new java.awt.BorderLayout());

add(jScrollPane1, java.awt.BorderLayout.CENTER);

}

private javax.swing.JScrollPane jScrollPane1;

class MyTable extends JTable {

public MyTable() {

addAncestorListener(new javax.swing.event.AncestorListener() {

public void ancestorMoved(javax.swing.event.AncestorEvent evt) {

}

public void ancestorAdded(javax.swing.event.AncestorEvent evt) {

if (AUTO_RESIZE_OFF == getAutoResizeMode()) {

TableColumnModel columnModel = getColumnModel();

int totalWidth = getParent().getWidth();

int columnCount = columnModel.getColumnCount();

int columnWidth = totalWidth / columnCount;

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

columnModel.getColumn(i).setPreferredWidth(columnWidth);

}

}

}

public void ancestorRemoved(javax.swing.event.AncestorEvent evt) {

}

});

}

}

}

NickDGa at 2007-7-12 18:53:55 > top of Java-index,Desktop,Core GUI APIs...
# 7

> No, it isn't really what I want.

Then I don't understand what you want. There are two situations that I can think of that need to be handled:

a) when the frame is first displayed it appears you want the columns to be of equal size

b) what happens when the frame is resized? I assume you also want the table to fill the entire space and therefore the columns will need to be resize equally.

As far as I can tell the code I gave you satisfies both requirements. You set the preferred size of each column to some value. As the frame is resized the columns appear to me to be adjusted equally in size. If the frame becomes to small to show each column less that its preferred size then the horizontal scrollbar is displayed so you can still see all columns. If you don't like the horizontal scrollbar then you should be able to use a preferred size of say 5 pixels.

The other approach would be to use a ComponentListener on the scrollpane. Whenever it changes size you get the table added to the viewport and recalculate the columns sizes.

camickra at 2007-7-12 18:53:55 > top of Java-index,Desktop,Core GUI APIs...
# 8

What I wanted was to extend JTable so that with AUTO_RESIZE_OFF, when the table is displayed the columns nicely fit the available space. (so it looks as auto resize is on). When the user widens a column, the horizontal scroll bar appears. When the component is resized the columns shouldn't be laid out again, just leave the at the width that was initially calculated (or manually resized by the user).

As using the AncestorListener didn't work out, so I tried overriding doLayout() of JTable:private boolean sized = false;

@Override

public void doLayout() {

super.doLayout();

if(!sized && getWidth() > 0) {

sized = true;

int columnCount = getColumnModel().getColumnCount();

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

TableColumn column = getColumnModel().getColumn(i);

int width = getWidth() / columnCount);

column.setPreferredWidth(width);

getTableHeader().setResizingColumn(column);

column.setWidth(width);

}

}

}

I did some tests and although it looked promising at first, it seems to give rather random results. The first time doLayout() is called with a width isn't necessarily the width of the final displayed table, which then causes the calculations to be wrong.

I'm abandoning the idea to extend our table to make it fill the available space. Instead I'm going add a right-click menu to the table header with a check box menu item to enable/disable autoresizing. That way people can choose if they want a scroll bar or a perfectly filled table.

Thanks for your input anyway.

NickDGa at 2007-7-12 18:53:55 > top of Java-index,Desktop,Core GUI APIs...