aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/javax
diff options
context:
space:
mode:
authoralitvinov <none@none>2014-08-09 01:18:25 +0400
committeralitvinov <none@none>2014-08-09 01:18:25 +0400
commitcb45736d92174e8c441028be2a4662cf5c088ca0 (patch)
tree3f57da6e095d63ff1f6f5de6460d9a7eaee88dae /src/share/classes/javax
parentad399745eba46284ed067944add6a3f4bf571f35 (diff)
8048887: SortingFocusTraversalPolicy throws IllegalArgumentException from the sort method
Reviewed-by: azvegint, alexsch Contributed-by: nakul.natu@oracle.com
Diffstat (limited to 'src/share/classes/javax')
-rw-r--r--src/share/classes/javax/swing/SortingFocusTraversalPolicy.java57
1 files changed, 56 insertions, 1 deletions
diff --git a/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java b/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java
index 53b348fe7..c1383f648 100644
--- a/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java
+++ b/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java
@@ -30,6 +30,11 @@ import java.awt.Window;
import java.util.*;
import java.awt.FocusTraversalPolicy;
import sun.util.logging.PlatformLogger;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import sun.security.action.GetPropertyAction;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
/**
* A FocusTraversalPolicy that determines traversal order by sorting the
@@ -89,6 +94,34 @@ public class SortingFocusTraversalPolicy
final private int FORWARD_TRAVERSAL = 0;
final private int BACKWARD_TRAVERSAL = 1;
+ /*
+ * When true (by default), the legacy merge-sort algo is used to sort an FTP cycle.
+ * When false, the default (tim-sort) algo is used, which may lead to an exception.
+ * See: JDK-8048887
+ */
+ private static final boolean legacySortingFTPEnabled;
+ private static final Method legacyMergeSortMethod;
+
+ static {
+ legacySortingFTPEnabled = "true".equals(AccessController.doPrivileged(
+ new GetPropertyAction("swing.legacySortingFTPEnabled", "true")));
+ legacyMergeSortMethod = legacySortingFTPEnabled ?
+ AccessController.doPrivileged(new PrivilegedAction<Method>() {
+ public Method run() {
+ try {
+ Class c = Class.forName("java.util.Arrays");
+ Method m = c.getDeclaredMethod("legacyMergeSort", new Class[]{Object[].class, Comparator.class});
+ m.setAccessible(true);
+ return m;
+ } catch (ClassNotFoundException | NoSuchMethodException e) {
+ // using default sorting algo
+ return null;
+ }
+ }
+ }) :
+ null;
+ }
+
/**
* Constructs a SortingFocusTraversalPolicy without a Comparator.
* Subclasses must set the Comparator using <code>setComparator</code>
@@ -133,8 +166,30 @@ public class SortingFocusTraversalPolicy
private void enumerateAndSortCycle(Container focusCycleRoot, List<Component> cycle) {
if (focusCycleRoot.isShowing()) {
enumerateCycle(focusCycleRoot, cycle);
- Collections.sort(cycle, comparator);
+ if (!legacySortingFTPEnabled ||
+ !legacySort(cycle, comparator))
+ {
+ Collections.sort(cycle, comparator);
+ }
+ }
+ }
+
+ private boolean legacySort(List<Component> l, Comparator<? super Component> c) {
+ if (legacyMergeSortMethod == null)
+ return false;
+
+ Object[] a = l.toArray();
+ try {
+ legacyMergeSortMethod.invoke(null, a, c);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ return false;
+ }
+ ListIterator<Component> i = l.listIterator();
+ for (Object e : a) {
+ i.next();
+ i.set((Component)e);
}
+ return true;
}
private void enumerateCycle(Container container, List<Component> cycle) {