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