diff options
author | alitvinov <none@none> | 2014-08-09 01:18:25 +0400 |
---|---|---|
committer | alitvinov <none@none> | 2014-08-09 01:18:25 +0400 |
commit | cb45736d92174e8c441028be2a4662cf5c088ca0 (patch) | |
tree | 3f57da6e095d63ff1f6f5de6460d9a7eaee88dae /src/share/classes/javax | |
parent | ad399745eba46284ed067944add6a3f4bf571f35 (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.java | 57 |
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) { |