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 import java.awt.Component; 25 import java.awt.Container; 26 import java.awt.GridLayout; 27 import java.awt.Point; 28 import java.awt.Rectangle; 29 import java.awt.Robot; 30 import java.awt.AWTException; 31 import java.awt.IllegalComponentStateException; 32 import java.awt.event.InputEvent; 33 import javax.swing.JButton; 34 import javax.swing.JDesktopPane; 35 import javax.swing.JFrame; 36 import javax.swing.JInternalFrame; 37 import javax.swing.JOptionPane; 38 import javax.swing.JPanel; 39 import javax.swing.JScrollPane; 40 import javax.swing.JTable; 41 import javax.swing.SwingUtilities; 42 import javax.swing.ToolTipManager; 43 import javax.swing.table.DefaultTableModel; 44 45 /** 46 * @test 47 * @key headful 48 * @bug 6219960 49 * @summary null reference in ToolTipManager 50 * @run main bug6219960 51 */ 52 public class bug6219960 { 53 54 private static final String QUESTION = "Question"; 55 56 static volatile JFrame frame; 57 static JTable table; 58 59 public static void main(String[] args) throws Exception { 60 Robot robot = new Robot(); 61 SwingUtilities.invokeAndWait(bug6219960::createAndShowGUI); 62 robot.waitForIdle(); 63 showModal("The tooltip should be showing. Press ok with mouse. And don't move it."); 64 robot.waitForIdle(); 65 showModal("Now press ok and move the mouse inside the table (don't leave it)."); 66 robot.waitForIdle(); 67 } 68 69 private static void createAndShowGUI() { 70 ToolTipManager.sharedInstance().setDismissDelay(10 * 60 * 1000); 71 frame = new JFrame(); 72 frame.setLocation(20, 20); 73 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 74 JDesktopPane desk = new JDesktopPane(); 75 JInternalFrame iframe = new JInternalFrame(); 76 iframe.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE); 77 desk.add(iframe); 78 JButton save = new JButton(); 79 save.setToolTipText("Wait for dialog to show."); 80 save.setText("Wait for the tooltip to show."); 81 JPanel panel = new JPanel(new GridLayout(1, 2)); 82 panel.add(save); 83 table = createTable(); 84 panel.add(new JScrollPane(table)); 85 iframe.setContentPane(panel); 86 frame.getContentPane().add(desk); 87 frame.setSize(800, 600); 88 iframe.setSize(640, 480); 89 iframe.validate(); 90 iframe.setVisible(true); 91 frame.validate(); 92 frame.setVisible(true); 93 try { 94 iframe.setSelected(true); 95 } catch (Exception e) { 96 throw new AssertionError(e); 97 } 98 99 try { 100 Robot robot = new Robot(); 101 Rectangle bounds = frame.getBounds(); 102 int centerX = (int) (bounds.getX() + bounds.getWidth() / 6); 103 int centerY = (int) (bounds.getY() + bounds.getHeight() / 6); 104 robot.mouseMove(centerX, centerY); 105 } catch (AWTException e) { 106 throw new RuntimeException(e); 107 } 108 } 109 110 private static void showModal(final String msg) throws Exception { 111 112 new Thread(() -> { 113 114 int timeout = 3000; 115 long endTime = System.currentTimeMillis() + timeout; 116 117 while (System.currentTimeMillis() <= endTime) { 118 if (pressOK(frame)) { 119 return; 120 } 121 } 122 throw new RuntimeException("Internal frame has not been found!"); 123 }).start(); 124 125 Thread.sleep(900); 126 127 SwingUtilities.invokeAndWait(() -> { 128 JOptionPane.showInternalMessageDialog(table, msg, 129 QUESTION, 130 JOptionPane.PLAIN_MESSAGE); 131 }); 132 } 133 134 private static JTable createTable() { 135 DefaultTableModel model = new DefaultTableModel(); 136 JTable table = new JTable(model); 137 table.setFillsViewportHeight(true); 138 return table; 139 } 140 141 private static boolean pressOK(Component comp) { 142 143 JInternalFrame internalFrame 144 = findModalInternalFrame(comp, QUESTION); 145 146 if (internalFrame == null) { 147 return false; 148 } 149 150 JButton button = (JButton) findButton(internalFrame); 151 152 if (button == null) { 153 return false; 154 } 155 156 try { 157 Robot robot = new Robot(); 158 Point location = button.getLocationOnScreen(); 159 Rectangle bounds = button.getBounds(); 160 int centerX = (int) (location.getX() + bounds.getWidth() / 2); 161 int centerY = (int) (location.getY() + bounds.getHeight() / 2); 162 robot.mouseMove(centerX, centerY); 163 robot.mousePress(InputEvent.BUTTON1_MASK); 164 robot.mouseRelease(InputEvent.BUTTON1_MASK); 165 } catch (IllegalComponentStateException ignore) { 166 return false; 167 } catch (AWTException e) { 168 throw new RuntimeException(e); 169 } 170 return true; 171 } 172 173 private static JInternalFrame findModalInternalFrame(Component comp, String title) { 174 175 if (comp instanceof JInternalFrame) { 176 JInternalFrame internalFrame = (JInternalFrame) comp; 177 if (internalFrame.getTitle().equals(title)) { 178 return (JInternalFrame) comp; 179 } 180 } 181 182 if (comp instanceof Container) { 183 Container cont = (Container) comp; 184 for (int i = 0; i < cont.getComponentCount(); i++) { 185 JInternalFrame result = findModalInternalFrame(cont.getComponent(i), title); 186 if (result != null) { 187 return result; 188 } 189 } 190 } 191 return null; 192 } 193 194 private static JButton findButton(Component comp) { 195 196 if (comp instanceof JButton) { 197 return (JButton) comp; 198 } 199 200 if (comp instanceof Container) { 201 Container cont = (Container) comp; 202 for (int i = 0; i < cont.getComponentCount(); i++) { 203 JButton result = findButton(cont.getComponent(i)); 204 if (result != null) { 205 return result; 206 } 207 } 208 } 209 return null; 210 } 211 }