JTable header with custom Default Renderer does not scroll inside JScrollPane - java

I have a JTable inside a JScrollPane, inside a JTabbedPane. The table header scrolls fine until I set a custom default renderer for it that dynamically changes the width and height of the header cells, i.e.:
table.getTableHeader().setDefaultRenderer(new MyHeaderRenderer());
... where MyHeaderRenderer extends a JLabel and its getTableCellRendererComponent() method sets the preferred size like this:
table.getTableHeader().setPreferredSize(new Dimension(width, height));
After settings the custom renderer the table body continues scrolling correctly, but the header stays fixed to the upper left corner of the JScrollPane. I believe the renderer is repainting the header continuously in that position.
How could I fix this?
Thanks.

My problem was that I had lots of columns with long header texts, so I created a header renderer to set the height and width of the header cells according to the length of the cell text.
As it turns out, you can't resize the header cells by setting the preferred size of the table header itself or you'll end up with a header always fixed to the upper left corner of the table.
Regarding this matter, I found no solution.
I tried setting preferredSize outside the renderer: it didn't work, which means the problem is not the continuous rendering.
I tried using a JTextArea instead of a JLabel: it made no difference.
I tried overriding the JTable doLayout() method: it didn't work.
I fixed the issue by removing:
table.getTableHeader().setPreferredSize(new Dimension(width, height));
... and adding these code lines to the getTableCellRendererComponent() method:
table.getColumnModel().getColumn(column).setPreferredWidth(width); //sets the width
setPreferredSize(new Dimension(width, height)); //sets the height of the JLabel returned by the renderer
This was the best I could think of. If anyone finds a better solution, please share it :-)

I faced the same problem and found a workaround.
JTable header is a separate component, that stored inside parent JScrollPane ColumnHeader. So, instead of overriding header preferred size we can set preferred size of JScrollPane ColumnHeader.
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.getColumnHeader().setPreferredSize(new Dimension(0, height));
Fortunately, JScrollPane ignores column header width, so you can safely set zero here.

Related

JXTable width to adjust according to content

I have a JXTable that is created like this:
JScrollPane scrollPane = new JScrollPane();
contentPanel.add(scrollPane, BorderLayout.CENTER);
tbl = new JXTable();
tbl.setColumnSelectionAllowed(true);
tbl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tbl.setEditable(false);
scrollPane.setViewportView(tbl);
The problem is that when it gets filled, all the columns are squashed to fit into the table. I expected the columns to be adjusted according to the width of the column header or column value (which ever is broader) and then for a horizontal scroll bar to be displayed that will enable me to scroll left or right.
How do I bridge this problem?
You should use the packAll method: this resizes columns to fit the viewport; if horizontal scrolling is enabled, columns will get their preferred width.

making a jtable bigger to fit all data

I currently have a JTable inside a JscrollPane inside a JPanel. No matter what I set the size of either of those 3 elements, the table always shows up as the same size. The JPanel is in BorderLayout and I am packing the frame. the reason I want to do this is because some of the data in my columns doesn't fit without having to make other columns way too small.
override table.getPreferredScrollableViewportSize(new Dimension(int, int));
change JPanels default LayoutManager FlowLayout (implemented in API) to BorderLayout or GridLayout
You can change the JScroller preferred size because a table is often put inside of a scroller.
scrollerPhone.setPreferredSize(new Dimension(600, 400));

How to resize table of database in swing frame?

I am trying to resize the widths of the columns in a JTable.
I would need to resize them when the program is running to see the full column header names.
I want to resize table of database showing in swing frame.
I have tried
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS)
But I didn't get the desired output because when I use this I have a horizontal scrollbar to scroll to the columns that are off screen. But I want the size of the whole table to become approximately equal to the size of frame.
How can I make the columns as wide as they need to be to display all the text?
But I want the size of the whole table to become approximately equal to the size of frame.
JTable table = ...;
JFrame frame = ...;
JPanel contentPane = new JPanel( new BorderLayout() );
contentPane.add( new JScrollPane( table ), BorderLayout.CENTER );
frame.setContentPane( contentPane );
How can I make the columns as wide as they need to be to display all the text?
Unfortunately, the maximum width of the JTable will be limited to the size of the JFrame, and there is no mechanism to push from your JTable the desired width to the JFrame when your JTable is contained in a JScrollPane.
What you could do is try to give your JScrollPane the correct width. I haven't tried this, but I suspect that giving your scrollpane the same width as the preferred width of your table (when autoresize is on) should solve this (+ perhaps some extra width for the vertical scrollbar). Note however that this will only work if you allow your JFrame in which the JScrollPane is contained to grow in width as well.

Java. Swing. JScrollPane's JViewport size changed

I have a customText component in a JScrollPane. When the text is empty and there are no scrollbars, I can see all the text. But when the scrollbars become visible, some text is "hidden" behind these scrollbars.
Maybe I can listen to JViewPort size changes and set preferredsize for my text component?
JComponent component = getResTextArea();
component.setPreferredSize(RES_TEXT_AREA_PREFFERED_SIZE);
JScrollPane scrollPane = new JScrollPane(component);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.getVerticalScrollBar().setUnitIncrement(UNIT_INCREMENT);
panel.add(scrollPane);
I see how size of the viewport changes when text exceeds the panel's visible area and scrollbars being shown.
EDIT. My custom component is a subclass of JEditorPane.
The best way to implement this would be for your custom component to implement javax.swing.Scrollable, with getScrollableTracksViewportWidth() returning true. This will lock the width of your JComponent to the width of the viewport.

Is it possible to place the header row of a JViewport at the bottom?

I'm using a JViewport for viewing some data and I'd like the header row to be placed at the bottom of the JViewport rather than the top.
The viewport never scrolls horizontally so the issue of where the scroll bar would go isn't a problem.
I suspect I'm going to have to make my own JViewport-like class which has the header row at the bottom; but before I go off and write that I thought I'd ask.
You can use a panel with a BorderLayout. Add the table to the scrollpane, then add the scrollpane to the center of the panel. Then get the header and add it to the south. Then get the vertical scrollbar and add it to the east.

Categories