8191639: NPE from BasicListUI.Actions.getNextPageIndex
Reviewed-by: serb, ssadetsky
This commit is contained in:
parent
e08ffc05d9
commit
81c1d53cdb
@ -2134,8 +2134,11 @@ public class BasicListUI extends ListUI
|
||||
Rectangle leadRect =
|
||||
(lead==-1) ? new Rectangle() : list.getCellBounds(lead, lead);
|
||||
|
||||
if (leadRect == null) {
|
||||
return index;
|
||||
}
|
||||
if (list.getLayoutOrientation() == JList.VERTICAL_WRAP &&
|
||||
list.getVisibleRowCount() <= 0) {
|
||||
list.getVisibleRowCount() <= 0) {
|
||||
if (!list.getComponentOrientation().isLeftToRight()) {
|
||||
direction = -direction;
|
||||
}
|
||||
@ -2146,14 +2149,20 @@ public class BasicListUI extends ListUI
|
||||
visRect.x = leadRect.x + leadRect.width - visRect.width;
|
||||
Point p = new Point(visRect.x - 1, leadRect.y);
|
||||
index = list.locationToIndex(p);
|
||||
if (index == -1) {
|
||||
return index;
|
||||
}
|
||||
Rectangle cellBounds = list.getCellBounds(index, index);
|
||||
if (visRect.intersects(cellBounds)) {
|
||||
if (cellBounds != null && visRect.intersects(cellBounds)) {
|
||||
p.x = cellBounds.x - 1;
|
||||
index = list.locationToIndex(p);
|
||||
if (index == -1) {
|
||||
return index;
|
||||
}
|
||||
cellBounds = list.getCellBounds(index, index);
|
||||
}
|
||||
// this is necessary for right-to-left orientation only
|
||||
if (cellBounds.y != leadRect.y) {
|
||||
if (cellBounds != null && cellBounds.y != leadRect.y) {
|
||||
p.x = cellBounds.x + cellBounds.width;
|
||||
index = list.locationToIndex(p);
|
||||
}
|
||||
@ -2163,13 +2172,19 @@ public class BasicListUI extends ListUI
|
||||
visRect.x = leadRect.x;
|
||||
Point p = new Point(visRect.x + visRect.width, leadRect.y);
|
||||
index = list.locationToIndex(p);
|
||||
if (index == -1) {
|
||||
return index;
|
||||
}
|
||||
Rectangle cellBounds = list.getCellBounds(index, index);
|
||||
if (visRect.intersects(cellBounds)) {
|
||||
if (cellBounds != null && visRect.intersects(cellBounds)) {
|
||||
p.x = cellBounds.x + cellBounds.width;
|
||||
index = list.locationToIndex(p);
|
||||
if (index == -1) {
|
||||
return index;
|
||||
}
|
||||
cellBounds = list.getCellBounds(index, index);
|
||||
}
|
||||
if (cellBounds.y != leadRect.y) {
|
||||
if (cellBounds != null && cellBounds.y != leadRect.y) {
|
||||
p.x = cellBounds.x - 1;
|
||||
index = list.locationToIndex(p);
|
||||
}
|
||||
@ -2187,17 +2202,23 @@ public class BasicListUI extends ListUI
|
||||
visRect.y = leadRect.y + leadRect.height - visRect.height;
|
||||
p.y = visRect.y;
|
||||
index = list.locationToIndex(p);
|
||||
if (index == -1) {
|
||||
return index;
|
||||
}
|
||||
Rectangle cellBounds = list.getCellBounds(index, index);
|
||||
// go one cell down if first visible cell doesn't fit
|
||||
// into adjasted visible rectangle
|
||||
if (cellBounds.y < visRect.y) {
|
||||
if (cellBounds != null && cellBounds.y < visRect.y) {
|
||||
p.y = cellBounds.y + cellBounds.height;
|
||||
index = list.locationToIndex(p);
|
||||
if (index == -1) {
|
||||
return index;
|
||||
}
|
||||
cellBounds = list.getCellBounds(index, index);
|
||||
}
|
||||
// if index isn't less then lead
|
||||
// try to go to cell previous to lead
|
||||
if (cellBounds.y >= leadRect.y) {
|
||||
if (cellBounds != null && cellBounds.y >= leadRect.y) {
|
||||
p.y = leadRect.y - 1;
|
||||
index = list.locationToIndex(p);
|
||||
}
|
||||
@ -2207,15 +2228,23 @@ public class BasicListUI extends ListUI
|
||||
// down
|
||||
// go to the last completely visible cell
|
||||
Point p = new Point(leadRect.x,
|
||||
visRect.y + visRect.height - 1);
|
||||
visRect.y + visRect.height - 1);
|
||||
index = list.locationToIndex(p);
|
||||
if (index == -1) {
|
||||
return index;
|
||||
}
|
||||
Rectangle cellBounds = list.getCellBounds(index, index);
|
||||
// go up one cell if last visible cell doesn't fit
|
||||
// into visible rectangle
|
||||
if (cellBounds.y + cellBounds.height >
|
||||
visRect.y + visRect.height) {
|
||||
if (cellBounds != null &&
|
||||
cellBounds.y + cellBounds.height >
|
||||
visRect.y + visRect.height)
|
||||
{
|
||||
p.y = cellBounds.y - 1;
|
||||
index = list.locationToIndex(p);
|
||||
if (index == -1) {
|
||||
return index;
|
||||
}
|
||||
cellBounds = list.getCellBounds(index, index);
|
||||
index = Math.max(index, lead);
|
||||
}
|
||||
@ -2226,24 +2255,33 @@ public class BasicListUI extends ListUI
|
||||
visRect.y = leadRect.y;
|
||||
p.y = visRect.y + visRect.height - 1;
|
||||
index = list.locationToIndex(p);
|
||||
if (index == -1) {
|
||||
return index;
|
||||
}
|
||||
cellBounds = list.getCellBounds(index, index);
|
||||
// go one cell up if last visible cell doesn't fit
|
||||
// into adjasted visible rectangle
|
||||
if (cellBounds.y + cellBounds.height >
|
||||
visRect.y + visRect.height) {
|
||||
if (cellBounds != null &&
|
||||
cellBounds.y + cellBounds.height >
|
||||
visRect.y + visRect.height)
|
||||
{
|
||||
p.y = cellBounds.y - 1;
|
||||
index = list.locationToIndex(p);
|
||||
if (index == -1) {
|
||||
return index;
|
||||
}
|
||||
cellBounds = list.getCellBounds(index, index);
|
||||
}
|
||||
// if index isn't greater then lead
|
||||
// try to go to cell next after lead
|
||||
if (cellBounds.y <= leadRect.y) {
|
||||
if (cellBounds != null && cellBounds.y <= leadRect.y) {
|
||||
p.y = leadRect.y + leadRect.height;
|
||||
index = list.locationToIndex(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
@ -2308,18 +2346,27 @@ public class BasicListUI extends ListUI
|
||||
cellBounds.x + cellBounds.width - visRect.width);
|
||||
int startIndex =
|
||||
list.locationToIndex(new Point(x, cellBounds.y));
|
||||
if (startIndex == -1) {
|
||||
return;
|
||||
}
|
||||
Rectangle startRect = list.getCellBounds(startIndex,
|
||||
startIndex);
|
||||
if (startRect.x < x && startRect.x < cellBounds.x) {
|
||||
if (startRect != null &&
|
||||
startRect.x < x && startRect.x < cellBounds.x) {
|
||||
startRect.x += startRect.width;
|
||||
startIndex =
|
||||
list.locationToIndex(startRect.getLocation());
|
||||
if (startIndex == -1) {
|
||||
return;
|
||||
}
|
||||
startRect = list.getCellBounds(startIndex,
|
||||
startIndex);
|
||||
}
|
||||
cellBounds = startRect;
|
||||
}
|
||||
cellBounds.width = visRect.width;
|
||||
if (cellBounds != null) {
|
||||
cellBounds.width = visRect.width;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (direction > 0) {
|
||||
@ -2327,15 +2374,20 @@ public class BasicListUI extends ListUI
|
||||
int x = cellBounds.x + visRect.width;
|
||||
int rightIndex =
|
||||
list.locationToIndex(new Point(x, cellBounds.y));
|
||||
if (rightIndex == -1) {
|
||||
return;
|
||||
}
|
||||
Rectangle rightRect = list.getCellBounds(rightIndex,
|
||||
rightIndex);
|
||||
if (rightRect.x + rightRect.width > x &&
|
||||
rightRect.x > cellBounds.x) {
|
||||
rightRect.width = 0;
|
||||
if (rightRect != null) {
|
||||
if (rightRect.x + rightRect.width > x &&
|
||||
rightRect.x > cellBounds.x) {
|
||||
rightRect.width = 0;
|
||||
}
|
||||
cellBounds.x = Math.max(0,
|
||||
rightRect.x + rightRect.width - visRect.width);
|
||||
cellBounds.width = visRect.width;
|
||||
}
|
||||
cellBounds.x = Math.max(0,
|
||||
rightRect.x + rightRect.width - visRect.width);
|
||||
cellBounds.width = visRect.width;
|
||||
}
|
||||
else {
|
||||
cellBounds.x += Math.max(0,
|
||||
@ -2357,24 +2409,35 @@ public class BasicListUI extends ListUI
|
||||
cellBounds.y + cellBounds.height - visRect.height);
|
||||
int startIndex =
|
||||
list.locationToIndex(new Point(cellBounds.x, y));
|
||||
if (startIndex == -1) {
|
||||
return;
|
||||
}
|
||||
Rectangle startRect = list.getCellBounds(startIndex,
|
||||
startIndex);
|
||||
if (startRect.y < y && startRect.y < cellBounds.y) {
|
||||
if (startRect != null &&
|
||||
startRect.y < y && startRect.y < cellBounds.y) {
|
||||
startRect.y += startRect.height;
|
||||
startIndex =
|
||||
list.locationToIndex(startRect.getLocation());
|
||||
if (startIndex == -1) {
|
||||
return;
|
||||
}
|
||||
startRect =
|
||||
list.getCellBounds(startIndex, startIndex);
|
||||
}
|
||||
cellBounds = startRect;
|
||||
cellBounds.height = visRect.height;
|
||||
if (cellBounds != null) {
|
||||
cellBounds.height = visRect.height;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// adjust height to fit into visible rectangle
|
||||
cellBounds.height = Math.min(cellBounds.height, visRect.height);
|
||||
}
|
||||
}
|
||||
list.scrollRectToVisible(cellBounds);
|
||||
if (cellBounds != null) {
|
||||
list.scrollRectToVisible(cellBounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
125
test/jdk/javax/swing/JList/BasicListTest.java
Normal file
125
test/jdk/javax/swing/JList/BasicListTest.java
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8191639
|
||||
* @headful
|
||||
* @summary Verifies no NPE is thrown wjen pageup/down is pressed in a JList
|
||||
* @run main BasicListTest
|
||||
*/
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
|
||||
class MyList extends JList {
|
||||
// I need this to be able to unselect when clicking outside list content
|
||||
@Override
|
||||
public int locationToIndex(final Point location) {
|
||||
final int n = super.locationToIndex(location);
|
||||
//return n;
|
||||
final Rectangle q = getCellBounds(n, n);
|
||||
return q != null && q.contains(location)?n:-1;
|
||||
}
|
||||
}
|
||||
|
||||
public class BasicListTest {
|
||||
private static void initComponents() {
|
||||
f = new JFrame();
|
||||
jScrollPane1 = new JScrollPane();
|
||||
list1 = new MyList();
|
||||
|
||||
f.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
|
||||
|
||||
list1.setModel(new javax.swing.AbstractListModel() {
|
||||
String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
|
||||
@Override
|
||||
public int getSize() { return strings.length; }
|
||||
@Override
|
||||
public Object getElementAt(int i) { return strings[i]; }
|
||||
});
|
||||
jScrollPane1.setViewportView(list1);
|
||||
|
||||
f.getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);
|
||||
|
||||
f.pack();
|
||||
f.setVisible(true);
|
||||
p = list1.getLocationOnScreen();
|
||||
}
|
||||
|
||||
private static void setLookAndFeel(final UIManager.LookAndFeelInfo laf) {
|
||||
try {
|
||||
UIManager.setLookAndFeel(laf.getClassName());
|
||||
} catch (ClassNotFoundException | InstantiationException |
|
||||
UnsupportedLookAndFeelException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf));
|
||||
System.out.println("Test for LookAndFeel " + laf.getClassName());
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
initComponents();
|
||||
});
|
||||
System.out.println("Test passed for LookAndFeel " + laf.getClassName());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Robot robot = new Robot();
|
||||
robot.setAutoDelay(200);
|
||||
robot.mouseMove(p.x, p.y);
|
||||
robot.waitForIdle();
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.waitForIdle();
|
||||
robot.keyPress(KeyEvent.VK_PAGE_DOWN);
|
||||
robot.keyRelease(KeyEvent.VK_PAGE_DOWN);
|
||||
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
f.dispose();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static JScrollPane jScrollPane1;
|
||||
private static MyList list1;
|
||||
private static Point p;
|
||||
private static JFrame f;
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user