JDK-4473075 : JTable header rendering problem (after setting preferred size)
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version:
    1.3.0,1.3.1,1.4.0,5.0,5.0u10,6,7,7u6 1.3.0,1.3.1,1.4.0,5.0,5.0u10,6,7,7u6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2001-06-21
  • Updated: 2017-05-16
  • Resolved: 2015-03-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6 JDK 9
5.0-poolResolved 6-poolResolved 9 b59Fixed
Related Reports
Duplicate :  
Relates :  
Description
Name: bsC130419			Date: 06/21/2001


Found in: J2SE 1.3.0 (build 1.3.0-C)
Also in: J2SE 1.4.0-beta (build 1.4.0-beta-b65)

This appears to be a problem with the rendering of JTable headers, such that
the header does not redraw properly when the table and header are horizontally
scrolled.

Steps:
1) Create a JTable and a simple model with several columns.
2) Set the JTable setAutoResizeMode to JTable.AUTO_RESIZE_OFF.
3) Add the JTable to a JScrollPane.
4) Manually set the preferred size of the JTable's header.
5) Place the whole lot in a JFrame and display it.

Now, if you resize the window so that some of the JTable's columns do not fit
you get a scroll bar as expected.  Dragged the scroll bar to the right; the
header does not repaint the headers for the new columns that have become
visible (though the columns themselves look okay).  The header display becomes
corrupt.

It appears as though the all pixels for the previously visible part of the
header have been shifted left okay, but the right-most fragment of the old
visible header region has been redrawn on the far right, rather than a new
rectangular section representing the part of the header that has become visible.

The following sample code reproduces the problem in 1.3.0 and 1.4.0 beta.

-----

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableHeaderBug extends JFrame {

    private JTable jTable = new JTable();
    private JScrollPane jscpScroll;

    public TableHeaderBug() {
        jTable.setModel(new MyTableModel());
        jTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        jscpScroll = new JScrollPane(jTable);
        // Manually set preferred size of header...
        jTable.getTableHeader().setPreferredSize(
            new Dimension(jTable.getSize().width, 40)
        );
        setContentPane(jscpScroll);
        setSize(640, 480);
        setVisible(true);
    }

    public static void main(String[] args) {
        new TableHeaderBug();
    }

}

class MyTableModel extends AbstractTableModel {

    public int getRowCount() { return 100; }
    public int getColumnCount() { return 8; }
    public Object getValueAt(int r, int c) {
        return new Integer((r+1)*(c+1));
    }
    public String getColumnName(int c) {
        return "times by "+(c+1);
    }

}
(Review ID: 126803) 
======================================================================

Comments
- this is an issue reported against 7(7u), - there are now affected version 9 filed for this issue - 7u issues are transferred to Sustaining Nevertheless if someone have a report against 9 - please reopen and add affectedVersion 9 or 7u specific escalations might be reopen to Sustaining
10-08-2014

We've reviewed your bulk request (120 bugs) and are OK with deferring them to JDK 9. You can go ahead and update these to: - Set label to 8-defer-approved - FixVersion to 9 Thanks for doing a great job of summarizing the details for the bulk deferral for us! Kind regards, Mathias
19-09-2013

The criteria for deferral bulk request bugs: - Not P2 - Not tck-red or conformance labeled - Not regressions reported/labeled against jdk8 - Not findbugs, parfait, eht, fuzzing labeled - Not netbeans, licbug, cap, cap-8 labeled against jdk8
18-09-2013

The criteria for deferral bulk request bugs: - Not P2 - Not tck-red or conformance labeled - Not regressions reported/labeled against jdk8 - Not findbugs, parfait, eht, fuzzing labeled - Not netbeans, licbug, cap, cap-8 labeled against jdk8
18-09-2013

The criteria for deferral bulk request bugs: - Not P2 - Not tck-red or conformance labeled - Not regressions reported/labeled against jdk8 - Not findbugs, parfait, eht, fuzzing labeled - Not netbeans, licbug, cap, cap-8 labeled against jdk8
18-09-2013

The criteria for deferral bulk request bugs: - Not P2 - Not tck-red or conformance labeled - Not regressions reported/labeled against jdk8 - Not findbugs, parfait, eht, fuzzing labeled - Not netbeans, licbug, cap, cap-8 labeled against jdk8
18-09-2013

jdk8: SQE ok to defer!
17-09-2013

EVALUATION By the way, the provided test case is quite strange - the line // Manually set preferred size of header... jTable.getTableHeader().setPreferredSize( new Dimension(jTable.getSize().width, 40) equals to jTable.getTableHeader().setPreferredSize(0, 40) because the current jTable size is 0x0 anywaym we should keep in sync the size and the view position of the column header and its parent viewport itself the fix is not going to be trivial
14-09-2009

EVALUATION The new bug is filed 6571861: JTable header can be made shorter than JTable itself and assigned to JTable owner the fix for the current bug will not be specific for JTable but for JViewPort it and remove the garbage but should we allow to JTableHeader be shorter then JTable itself is up to JTable owner
02-08-2007

EVALUATION There are three scroll modes for the JViewport which can be changed with help of JViewport.setScrollMode() method with the SIMPLE_SCROLL_MODE the described problmes are not reproducible and it is clear why - with this mode the JViewport is fully repainted during scrolling the fun begins when it comes to two other optimized modes BACKINGSTORE_SCROLL_MODE and BLIT_SCROLL_MODE (the default one) The BLIT_SCROLL_MODE does Graphics.copyArea for the part of the view which is still visible after scrolling and then it repaints the small part of the component which was invisible before scrolling the problem that the JViewport.computeBlit() method tries to do the same routine for the case when the view is partly visible in the Viewport and the Viewport's background doesn't get painted instead we can see the view component's remains suggested fix - not to use blit if the view component is moved outside the viewport's bounds The BACKINGSTORE_SCROLL_MODE paints the view component to the back buffer and then copy it to the graphics and it exposes another problem - if the view component is moved outsided the JViewport bounds the viewport's bacground color is not respected we can see the white background of the back buffer image to make it worse this white color will be replaced with the actual viewport's background during the next repaints suggested fix - if we can't blit call the super.paint() method and force the actual paint of the component
13-06-2007

EVALUATION This problem isn't unique to JTableHeader. For example, consider the test case I've attached, Bug2.java. Run it the same way, resized so that the label header component shows "..." at the end, and then scroll. This appears to be a problem with how JScrollPane treats any header component with a fixed size like this. There are two things here: First, I don't understand why garbage is allowed to show up. We at least need to fix this. Second, perhaps JScrollPane needs to do better to ensure that the header is large enough to match the scrollable content. Re-assigning to the scrollpane owner.
24-05-2007

SUGGESTED FIX I don't agree with the suggested fix above. Please see my evaluation note.
24-05-2007

EVALUATION See also duplicate bug 6283018.
20-03-2007

SUGGESTED FIX Add this method to JTableHeader (maybe add @Override): /** * Returns the table header's preferred size. * The preferred width is at least as large as * the width of the associated table. * * @return the value of the preferredSize property * @see #setPreferredSize * @see JTable#getSize * @see JComponent#getPreferredSize */ public Dimension getPreferredSize(){ Dimension prefSize = super.getPreferredSize(); JTable table = getTable(); if (table != null) { Dimension tableSize = table.getSize(); if (tableSize.width > prefSize.width) { prefSize.width = tableSize.width; } } return prefSize; }
17-03-2006

EVALUATION I slightly modified the suggested fix. I've attached the fixed file (JTableHeader.java) and a running version of the test (JTable4473075.java). I've also put the diffs into the Suggested Fix area.
17-03-2006

EVALUATION Contribution-Forum:https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?messageID=11903&forumID=1463
10-03-2006

WORK AROUND Name: bsC130419 Date: 06/21/2001 Moving the call to getHeader.setPreferredSize() until the JTable has become visible, and then immediately calling revalidate() on the table seems to work, in the sample case given. However, this may not help in the general case. The original code in which the problem occurred is intended to be a re-usable JavaBean component; the user of the bean should not be forced to manually revalidate the component after it has been displayed. ======================================================================
29-09-2004