1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 @test 26 @bug 8048887 27 @summary Tests SortingFTP for an exception caused by the tim-sort algo. 28 @author anton.tarasov: area=awt.focus 29 @run main JDK8048887 30 */ 31 32 import javax.swing.JFrame; 33 import javax.swing.JPanel; 34 import javax.swing.SwingUtilities; 35 import java.awt.Dimension; 36 import java.awt.Color; 37 import java.awt.GridBagLayout; 38 import java.awt.GridBagConstraints; 39 import java.awt.event.WindowAdapter; 40 import java.awt.event.WindowEvent; 41 import java.util.concurrent.CountDownLatch; 42 import java.util.concurrent.TimeUnit; 43 44 public class JDK8048887 { 45 46 static volatile boolean passed = true; 47 48 public static void main(String[] args) { 49 JDK8048887 app = new JDK8048887(); 50 app.start(); 51 } 52 53 public void start() { 54 final CountDownLatch latch = new CountDownLatch(1); 55 56 SwingUtilities.invokeLater(new Runnable(){ 57 @Override 58 public void run(){ 59 // Catch the original exception which sounds like: 60 // java.lang.IllegalArgumentException: Comparison method violates its general contract! 61 62 Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 63 public void uncaughtException(Thread t, Throwable e) { 64 e.printStackTrace(); 65 if (e instanceof IllegalArgumentException) { 66 passed = false; 67 latch.countDown(); 68 } 69 } 70 }); 71 72 TestDialog d = new TestDialog(); 73 // It's expected that the dialog is focused on start. 74 // The listener is called after the FTP completes processing and the bug is reproduced or not. 75 d.addWindowFocusListener(new WindowAdapter() { 76 public void windowGainedFocus(WindowEvent e) { 77 latch.countDown(); 78 } 79 }); 80 d.setVisible(true); 81 82 83 } 84 }); 85 86 try { 87 latch.await(5, TimeUnit.SECONDS); 88 } catch (InterruptedException e) { 89 e.printStackTrace(); 90 } 91 92 if (passed) 93 System.out.println("Test passed."); 94 else 95 throw new RuntimeException("Test failed!"); 96 } 97 } 98 99 class TestDialog extends JFrame { 100 101 // The layout of the components reproduces the transitivity issue 102 // with SortingFocusTraversalPolicy relying on the tim-sort algo. 103 104 private static int[] Xs = new int[] {71, 23, 62, 4, 79, 39, 34, 9, 84, 58, 30, 34, 38, 15, 69, 10, 44, 95, 70, 54, 105 44, 62, 77, 64, 70, 83, 31, 48, 96, 54, 40, 3, 60, 58, 3, 20, 94, 54, 26, 19, 48, 47, 12, 70, 86, 43, 71, 97, 19, 106 69, 90, 22, 43, 76, 10, 60, 29, 49, 9, 9, 15, 73, 85, 80, 81, 35, 87, 43, 17, 57, 38, 44, 29, 86, 96, 15, 57, 26, 107 27, 78, 26, 87, 43, 6, 4, 16, 57, 99, 32, 86, 96, 5, 50, 69, 12, 4, 36, 84, 71, 60, 22, 46, 11, 44, 87, 3, 23, 14, 108 43, 25, 32, 44, 11, 18, 77, 2, 51, 87, 88, 53, 69, 37, 14, 10, 25, 73, 39, 33, 91, 51, 96, 9, 74, 66, 70, 42, 72, 109 7, 82, 40, 91, 33, 83, 54, 33, 50, 83, 1, 81, 32, 66, 11, 75, 56, 53, 45, 1, 69, 46, 31, 79, 58, 12, 20, 92, 49, 110 50, 90, 33, 8, 43, 93, 72, 78, 9, 56, 84, 60, 30, 39, 33, 88, 84, 56, 49, 47, 4, 90, 57, 6, 23, 96, 37, 88, 22, 79, 111 35, 80, 45, 55}; 112 113 public TestDialog() { 114 JPanel panel = new JPanel(new GridBagLayout()); 115 GridBagConstraints gbc = new GridBagConstraints(); 116 for (int i=0; i < Xs.length; i++) { 117 gbc.gridx = Xs[i]; 118 gbc.gridy = 100 - gbc.gridx; 119 panel.add(new MyComponent(), gbc); 120 } 121 getRootPane().getContentPane().add(panel); 122 pack(); 123 } 124 125 public static class MyComponent extends JPanel { 126 private final static Dimension SIZE = new Dimension(1,1); 127 128 public MyComponent() { 129 setBackground(Color.BLACK); 130 setOpaque(true); 131 } 132 133 @Override 134 public Dimension getPreferredSize() { 135 return SIZE; 136 } 137 } 138 }