JDK-7068740 : If you wrap a JTable in a JLayer you can't use the page up and page down cmds
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 7
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86
  • Submitted: 2011-07-20
  • Updated: 2013-12-17
  • Resolved: 2013-05-31
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.
JDK 7 JDK 8
7u40Fixed 8 b94Fixed
Description
FULL PRODUCT VERSION :
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) 64-Bit Server VM (build 21.0-b17, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
windows, linux

A DESCRIPTION OF THE PROBLEM :
Nothing happens when you page up and page down on a JTable wrapped in a JLayer in a JScrollPane. This is because of a problem in javax.swing.plaf.basic.BasicTableUI. If you look around line ~422 you will see this code:
if (!(table.getParent().getParent() instanceof
                            JScrollPane)) {
                        return;
                    }
Because the table has been wrapped in a JLayer, the parents parent is not a JScrollPane. Maybe we should walk up the parents until we find a JScrollPane?

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the code below and try and use page up and page down buttons. They will not work.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Selected cell in table moves and scroll pane scrolls if required.
ACTUAL -
Table doesn't move and selected cell in table doesn't move.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package test;

import javax.swing.*;
import javax.swing.plaf.LayerUI;
import javax.swing.table.DefaultTableModel;

public class JLayerTableTest extends JFrame {
    public JLayerTableTest() {
        super("JLayer Table Test");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        DefaultTableModel model = new DefaultTableModel() {
            @Override public int getRowCount() {return 100;}
            @Override public int getColumnCount() {return 3;}
            @Override public Object getValueAt(int row, int column) {return "(" + row + "," + column + ")";}
        };
        JTable table = new JTable(model);
        LayerUI<JComponent> layerUI = new LayerUI<>();
        JLayer<JComponent> layer = new JLayer<>(table, layerUI);
        JScrollPane scrollPane = new JScrollPane(layer);
        add(scrollPane);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override public void run() {new JLayerTableTest();}
        });
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
In my JTable I can override the getParent method and inspect the stack. If I am being called by the BasicTableUI in the appropriate method, I can return the parents parent. This works but getting the stack adversly affects the performance of the application.

Comments
the SwingUtilities.getUnwrappedParent() should be used to unwrap the table
24-05-2013