JDK-8202702 : Clearing selection on JTable causes disappearance of a row
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 9,10,11
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux_ubuntu
  • CPU: x86_64
  • Submitted: 2018-05-04
  • Updated: 2019-12-02
  • Resolved: 2018-08-16
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 12
12 b14Fixed
Related Reports
Duplicate :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Kubuntu 17.10 (64-Bit) with JDK 10.0.1:

java 10 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)

A DESCRIPTION OF THE PROBLEM :
A mouse listener will be used to set the row(of a JTable) underneath the mouse cursor to the selected state. After using the clearSelection() method from JTable, when the mouse moves out of the current selected row, and the next row is not selectable, the previous selected row will be excluded from drawing and hence disappears.

Using this technique worked until latest JDK 8!

REGRESSION : Last worked in version 10.0.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See the sample code, which reproduces the problem.

I found out that same code in BasicTableUI has changed, which may cause the problem. In BasicTableUI.paint(...) there is the following check:

if (rMax != (table.getRowCount() - 1) &&
                    (table.getSelectedRow() == -1)) {
                rMax = rMax - 1;
            }

In situations where rMax is 1, this causes rMax to be 0 and the subsequently call of paintCells(...) excludes the cells of the row from being drawn because the inner loop with paintCell(... )is not running.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Rows do not disappear when selection is cleared and the mouse leaves this row.
ACTUAL -
Row is disappearing when mouse leaves the selected row and the next row underneath the cursor is not selectable. 

---------- BEGIN SOURCE ----------
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;

public class TableTest {
	
	private static String[] rows = new String[] {
			"Row1", "Row2", "Row3", "Row4", "Row5", 
			"Row6", "Row7", "Row8", "Row9", "Row10"}; 
	
	public static void main(final String[] args) {
		
		final DefaultTableModel model = new DefaultTableModel();
		model.addColumn("Test", rows);
		final JTable table = new JTable(model);
		table.setRowHeight(25);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		final MouseAdapter adapt = new MouseAdapter() {
			
			private boolean isRowSelectable(int rowIndex) {
				return rowIndex % 2 == 0;
			}
			@Override
			public void mouseMoved(final MouseEvent pE) {
				final int row = table.rowAtPoint(pE.getPoint());
				if (row > -1  && this.isRowSelectable(row)) {
					table.setRowSelectionInterval(row, row);
				} else {
					table.clearSelection();
				}
			}
			@Override
			public void mouseEntered(final MouseEvent pE) {
				final int row = table.rowAtPoint(pE.getPoint());
				if (row > -1 && this.isRowSelectable(row)) {
					table.setRowSelectionInterval(row, row);
				} else {
					table.clearSelection();
				}
			}
			@Override
			public void mouseExited(final MouseEvent pE) {
				table.clearSelection();
			}
		};
		table.addMouseListener(adapt);
		table.addMouseMotionListener(adapt);
		
		final JFrame frame = new JFrame();
		frame.setSize(800, 300);
		frame.add(table);
		frame.setVisible(true);
	}
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Overwriting the getSelectedRow() method in JTable and returning -2 instead of -1 in case of a cleared selection  bypasses the check in BasicTableUI.paint(...) and the rows will not disappear.

FREQUENCY : always



Comments
The issue is reproduced in the latest of JDK builds. Per the description of the problem, this seems a regression of the bug JDK-8159068 and JDK-8081491. Hence this is reassigned to the author.
08-05-2018

Reported as regression where after using the clearSelection() method from JTable, when the mouse moves out of the current selected row, and the next row is not selectable, the previous selected row will be excluded from drawing and hence disappears. The issue is reproducible as reported with JDK 9 and onwards. Row is disappearing as the mouse leaves the selected row and the next row underneath the cursor becomes not selectable. Results: ========== 8u171: OK 9: Fail 10.0.1: Fail 11 ea b10: Fail This seems a regression in JDK 9 and onwards. To verify, run the attachd test case with respective JDK version(s). Move over the mouse of selected row and see the result. As per submitter, the code change in BasicTableUI may have cause the problem. In BasicTableUI.paint(...) there is the following check: if (rMax != (table.getRowCount() - 1) && (table.getSelectedRow() == -1)) { rMax = rMax - 1; } In situations where rMax is 1, this causes rMax to be 0 and the subsequently call of paintCells(...) excludes the cells of the row from being drawn because the inner loop with paintCell(... )is not running.
07-05-2018