Where have my JTable headings gone?

Hi,

I need to make a gui which has a series of tables and headings arranged in a frame. I've managed to do it with GridBagLayout I think,

but there is a strange side effect. The headings for the table columns seem to dissappear, as seen in the code below. If you take any of the tables and put them on a panel without GridBagLayout, the headings re-appear. What is going on!?!!

import javax.swing.*;

import java.awt.*;

class ScrollerTestextends JFrame{

String[] columnNames ={"Column 1",

"Column 2",

"Column 3",

"Column 4",

"Column 5"};

Object[][] data ={

{"P1","A",

"B",new Integer(5),new Boolean(false)},

{"P2","A",

"B",new Integer(3),new Boolean(true)},

{"P3","A",

"B",new Integer(2),new Boolean(false)},

{"P4","A",

"b",new Integer(20),new Boolean(true)},

{"P5","A",

"b",new Integer(10),new Boolean(false)}

};

public ScrollerTest(){

JTable table1 =new JTable(data, columnNames);

JTable table2 =new JTable(data, columnNames);

JTable table3 =new JTable(data, columnNames);

JTable table4 =new JTable(data, columnNames);

JLabel label1 =new JLabel("Table 1");

JLabel label2 =new JLabel("Table 2");

JLabel label3 =new JLabel("Table 3");

JLabel label4 =new JLabel("Table 4");

JPanel myPanel =new JPanel();

myPanel.setLayout(new GridBagLayout());

GridBagConstraints c =new GridBagConstraints();

c.insets =new Insets(0,0,10,0);

c.gridx = 0;

c.gridy = 0;

c.anchor = GridBagConstraints.WEST;

myPanel.add(label1,c);

c.insets =new Insets(0,0,30,0);

c.gridx = 0;

c.gridy = 1;

c.anchor = GridBagConstraints.CENTER;

myPanel.add(table1,c);

c.insets =new Insets(0,0,10,0);

c.gridx = 0;

c.gridy = 2;

c.anchor = GridBagConstraints.WEST;

myPanel.add(label2,c);

c.insets =new Insets(0,0,30,0);

c.gridx = 0;

c.gridy = 3;

c.anchor = GridBagConstraints.CENTER;

myPanel.add(table2,c);

c.insets =new Insets(0,0,10,0);

c.gridx = 0;

c.gridy = 4;

c.anchor = GridBagConstraints.WEST;

myPanel.add(label3,c);

c.insets =new Insets(0,0,30,0);

c.gridx = 0;

c.gridy = 5;

c.anchor = GridBagConstraints.CENTER;

myPanel.add(table3,c);

c.insets =new Insets(0,0,10,0);

c.gridx = 0;

c.gridy = 6;

c.anchor = GridBagConstraints.WEST;

myPanel.add(label4,c);

c.insets =new Insets(0,0,30,0);

c.gridx = 0;

c.gridy = 7;

c.anchor = GridBagConstraints.CENTER;

myPanel.add(table4,c);

JScrollPane scroller =new JScrollPane();

scroller.getViewport().add(myPanel);

scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);

scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

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

this.getContentPane().add(scroller);

this.setSize(new Dimension(300, 300));

this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

this.setVisible(true);

}

publicstaticvoid main(String [] args){new ScrollerTest();}

}

[6014 byte] By [Arwela] at [2007-11-27 7:42:18]
# 1
You must first place the JTable in a JScrollPane, then add the scroll pane to your panel. In your code, you added the table directly to the panel.
KelVarnsona at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...
# 2

Hi,

Yes, this is the behaviour I'm after. There's no need for the user to have an individual scroll for each of the 4 tables (too confusing). Instead I just want to be able to scroll the whole panel and look at each table as required. So 4 tables onto panel then into scrollpane. What I dont understand is why GridBagLAyout seems to make the column headings disappear...

Cheers,

Arwel

Arwela at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...
# 3

Your issue has nothing to do with GridBagLayout.

By default, a JTable's header will not appear unless it is in a JScrollpane. If you simply don't want to do this (why?), there is a workaround. The JTable tutorial explains:

http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#show

KelVarnsona at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...
# 4

> There's no need for the user to have an individual scroll for each of the 4 tables (too confusing)

Many would argue this point.

What if I want to see row 2 of table 1 and row 28 of table 2, while glancing at row 57 of table 3? With your one universal scroll, this would be awkward at best, if not impossible.

KelVarnsona at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...
# 5

I can see the point totally. But these four tables are not used often in this application (I'm thinking this panel will just pop up from amenu, and then close after use), so some inconvenience with looking at them is not too much of a problem.

But thanks for the JScrollpane advice. I tried it and it almost works. The modified code below at least gives me the headings for the first table, but the JScrollpane is huge! So I need to changhe its size right,and I can't figure out what to do. Am I supposed to be changing the scrollpane size, or is it a layout manager thing? Ideally, I need to get the a size attributr from the table, and somehow using that to set the scrollpane size. Somehow. (Help?!)

public ScrollerTest() {

JTable table1 = new JTable(data, columnNames);

JTable table2 = new JTable(data, columnNames);

JTable table3 = new JTable(data, columnNames);

JTable table4 = new JTable(data, columnNames);

JLabel label1 = new JLabel("Table 1");

JLabel label2 = new JLabel("Table 2");

JLabel label3 = new JLabel("Table 3");

JLabel label4 = new JLabel("Table 4");

JPanel myPanel = new JPanel();

myPanel.setLayout(new GridBagLayout());

GridBagConstraints c = new GridBagConstraints();

c.insets = new Insets(0,0,10,1);

c.gridx = 0;

c.gridy = 0;

c.anchor = GridBagConstraints.WEST;

myPanel.add(label1,c);

c.insets = new Insets(0,0,30,0);

c.gridx = 0;

c.gridy = 1;

c.anchor = GridBagConstraints.CENTER;

JScrollPane tablePane = new JScrollPane(table1);

myPanel.add(tablePane,c);

c.insets = new Insets(0,0,10,0);

c.gridx = 0;

c.gridy = 2;

c.anchor = GridBagConstraints.WEST;

myPanel.add(label2,c);

c.insets = new Insets(0,0,30,0);

c.gridx = 0;

c.gridy = 3;

c.anchor = GridBagConstraints.CENTER;

myPanel.add(table2,c);

c.insets = new Insets(0,0,10,0);

c.gridx = 0;

c.gridy = 4;

c.anchor = GridBagConstraints.WEST;

myPanel.add(label3,c);

c.insets = new Insets(0,0,30,0);

c.gridx = 0;

c.gridy = 5;

c.anchor = GridBagConstraints.CENTER;

myPanel.add(table3,c);

c.insets = new Insets(0,0,10,0);

c.gridx = 0;

c.gridy = 6;

c.anchor = GridBagConstraints.WEST;

myPanel.add(label4,c);

c.insets = new Insets(0,0,30,0);

c.gridx = 0;

c.gridy = 7;

c.anchor = GridBagConstraints.CENTER;

myPanel.add(table4,c);

JScrollPane scroller = new JScrollPane();

scroller.getViewport().add(myPanel);

scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);

scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

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

this.getContentPane().add(scroller);

this.setSize(new Dimension(300, 300));

this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

this.setVisible(true);

}

[/code]

Arwela at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...
# 6
p.s.All the tables are always 5 colums wide, so theres never a problem of seeing row 58 of one and 2 of another, by the way.
Arwela at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...
# 7

> p.s.

> All the tables are always 5 colums wide, so theres never a problem of

> seeing row 58 of one and 2 of another, by the way.

I don't think you understood my point (or, perhaps I was unclear).

If you put each table into their own JScrollPane, and showed maybe only 5 rows of each table (or whatever number is appropriate), then the user could scroll each scroll pane to the appropriate row for that table, and be able to see the desired data for each table all at the same time (perhaps for comparison purposes), without having to scroll the page up and down constantly.

The amount of columns is irrelevant, by the way.

With your way, let's assume that each table has:

100 rows for table 1,

460 rows for table 2,

60 rows for table 3,

570 rows for table 4,

1100 rows for table 5.

Now lets consider that I want to compare the data in row 9 of table 1 with the data in 56 of table 3, and row 513 of table 5. It is impossible. They will never be on the screen at the same time (which is the point I was trying to make). I would have to "page scroll" up and down several times, which is undesirable in my opinion. If each table could scroll all by themselves, it suddenly becomes very do-able.

Trying to avoid page scrolling (if you can) seems to be a common, accepted idiom of UI design. Of course, there are times when you want that, but that is typically an exception, not the norm.

Just my 2c.

KelVarnsona at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...
# 8

Hi,

No honest, I understand the point. Its just that in this application, these three tables in particular are never very big, and just because of the information that they contain there is never really much need to compare information between these three tables at the same time. The user will typically require information from just one of them, and not very often at that.

There are other big tables in the app tho, and they have thir own scrollbanes in their own frames.

My thinking is that giving each a scrollable area is just unnecessary clutter. You can just scroll a window with three small tables on it to the bit you want without too much bother, and then move on. If there were hundreds of rows in each table then for enough, but there wont be (always < 10)

Message was edited by:

Arwel

Arwela at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...
# 9

> No honest, I understand the point. Its just that in this application,

> these three tables in particular are never very big, and just because of

> the information that they contain there is never really much need to

> compare information between these three tables at the same time.

> The user will typically require information from just one of them, and

> not very often at that.

Fair enough.

In that case, you still need to put each table in a scroll pane in order to see the headers. Then set the horizontal and vertical scrollbar policies to NEVER.

KelVarnsona at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...
# 10

Thanks for that. I've done that and can now see the headers.

The only bit left is to get the size of the scrollpane right. How can I set the size of the JScrollpane so that its just big enough to hold a table?

In the code above the first table shows the headers but the JScrollpane occupies an area that is way to big. I can't figure out if this is caused by the settings of the scrollpane or if its to do with the grid on the gridbaglayout.

How can I set the (non scrolling!) jscrollpane to be exactly the size required to contain the table?

Arwela at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...
# 11

I got ut!!! :o)

THis now works. Thanks for the help everyone....

c.insets = new Insets(0,0,30,0);

c.gridx = 0;

c.gridy = 1;

c.anchor = GridBagConstraints.CENTER;

JScrollPane tablePane = new JScrollPane(table1);

tablePane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);

tablePane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

tablePane.setPreferredSize(table1.getPreferredSize());

myPanel.add(tablePane,c);

Arwela at 2007-7-12 19:23:08 > top of Java-index,Desktop,Core GUI APIs...