1 /* 2 * Copyright (c) 2011, 2016, 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 * @key headful 27 * @bug 7108598 8172009 28 * @summary Container.paint/KeyboardFocusManager.clearMostRecentFocusOwner methods deadlock 29 * @library ../../regtesthelpers 30 * @author Oleg Pekhovskiy 31 * @build Util 32 * @run main PaintSetEnabledDeadlock 33 */ 34 35 import java.awt.Button; 36 import java.awt.Color; 37 import java.awt.Dimension; 38 import java.awt.Frame; 39 import java.awt.Graphics; 40 import java.awt.GridLayout; 41 import java.awt.Image; 42 import java.awt.Panel; 43 import java.awt.Rectangle; 44 import java.awt.Robot; 45 import java.awt.event.MouseAdapter; 46 import java.awt.event.MouseEvent; 47 import java.awt.event.WindowAdapter; 48 import java.awt.event.WindowEvent; 49 import test.java.awt.regtesthelpers.Util; 50 51 public class PaintSetEnabledDeadlock extends Frame { 52 53 final TestPanel panel; 54 final Button button; 55 56 public static void main(String[] args) { 57 PaintSetEnabledDeadlock frame = new PaintSetEnabledDeadlock(); 58 frame.setSize(200, 200); 59 frame.setVisible(true); 60 61 Robot robot = Util.createRobot(); 62 robot.setAutoDelay(100); 63 robot.setAutoWaitForIdle(true); 64 65 for (int i = 0; i < 20; ++i) { 66 Util.clickOnComp(frame.panel, robot); 67 Util.clickOnComp(frame.button, robot); 68 } 69 70 boolean ret = frame.panel.stop(); 71 frame.dispose(); 72 73 if (!ret) { 74 throw new RuntimeException("Test failed!"); 75 } 76 System.out.println("Test passed."); 77 } 78 79 public PaintSetEnabledDeadlock() { 80 super("7108598 test"); 81 setLayout(new GridLayout(1, 2)); 82 addWindowListener(new WindowAdapter() { 83 84 @Override 85 public void windowClosing(WindowEvent e) { 86 panel.stop(); 87 System.exit(0); 88 } 89 }); 90 panel = new TestPanel(); 91 add(panel); 92 button = new Button("Enable"); 93 button.addMouseListener(new MouseAdapter() { 94 95 @Override 96 public void mousePressed(MouseEvent e) { 97 panel.setEnabled(true); 98 panel.sync(); 99 panel.repaint(); 100 } 101 }); 102 add(button); 103 } 104 } 105 106 class TestPanel extends Panel implements Runnable { 107 108 Image image = null; 109 Thread thread = null; 110 volatile boolean active = true; 111 final Object sync = new Object(); 112 Panel panel = this; 113 114 public TestPanel() { 115 addMouseListener(new MouseAdapter() { 116 117 @Override 118 public void mouseReleased(MouseEvent e) { 119 synchronized (panel) { 120 sync(); 121 panel.setEnabled(false); 122 } 123 panel.repaint(); 124 } 125 }); 126 thread = new Thread(this); 127 thread.start(); 128 } 129 130 @Override 131 public void paint(Graphics paramGraphics) { 132 synchronized (getTreeLock()) { 133 Rectangle rect = getBounds(); 134 if (image == null) { 135 image = createImage(rect.width, rect.height); 136 } 137 138 if (image != null) { 139 paramGraphics.drawImage(image, 0, 0, this); 140 } 141 } 142 } 143 144 @Override 145 public void run() { 146 while (active) { 147 try { 148 synchronized (sync) { 149 sync.wait(); 150 } 151 } catch (InterruptedException ex) { 152 } 153 if (active) { 154 draw(); 155 } 156 } 157 } 158 159 public boolean stop() { 160 active = false; 161 try { 162 sync(); 163 thread.join(1000); 164 if (thread.isAlive()) { 165 thread.interrupt(); 166 return false; 167 } 168 } catch (InterruptedException ex) { 169 return false; 170 } 171 return true; 172 } 173 174 public void draw() { 175 synchronized (getTreeLock()) { 176 if (image != null) { 177 Graphics localGraphics = image.getGraphics(); 178 Dimension size = getSize(); 179 localGraphics.setColor(isEnabled() ? Color.green : Color.red); 180 localGraphics.fillRect(0, 0, size.width, size.height); 181 super.paint(localGraphics); 182 localGraphics.dispose(); 183 getTreeLock().notifyAll(); 184 } 185 } 186 } 187 188 public void sync() { 189 synchronized (sync) { 190 sync.notify(); 191 } 192 } 193 }