001 /* 002 * Created on Dec 01, 2008 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 005 * the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 010 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 011 * specific language governing permissions and limitations under the License. 012 * 013 * Copyright @2008-2010 the original author or authors. 014 */ 015 package org.fest.swing.edt; 016 017 import static org.fest.reflect.core.Reflection.staticMethod; 018 019 import javax.swing.*; 020 021 import org.fest.swing.exception.EdtViolationException; 022 023 /** 024 * <p> 025 * Fails a test when a Event Dispatch Thread rule violation is detected.<br/> 026 * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How to Use Threads</a> for more info 027 * </p> 028 * 029 * @author Alex Ruiz 030 */ 031 public class FailOnThreadViolationRepaintManager extends CheckThreadViolationRepaintManager { 032 033 /** 034 * Creates a new <code>{@link FailOnThreadViolationRepaintManager}</code> and sets it as the current repaint manager. 035 * <p> 036 * On Sun JVMs, this method will install the new repaint manager the first time only. Once installed, subsequent calls 037 * to this method will not install new repaint managers. This optimization may not work on non-Sun JVMs, since we use 038 * reflection to check if a {@code CheckThreadViolationRepaintManager} is already installed. 039 * </p> 040 * @return the created (and installed) repaint manager. 041 * @see RepaintManager#setCurrentManager(RepaintManager) 042 */ 043 public static FailOnThreadViolationRepaintManager install() { 044 Object m = currentRepaintManager(); 045 if (m instanceof FailOnThreadViolationRepaintManager) return (FailOnThreadViolationRepaintManager)m; 046 return installNew(); 047 } 048 049 private static Object currentRepaintManager() { 050 try { 051 return staticMethod("appContextGet").withReturnType(Object.class) 052 .withParameterTypes(Object.class) 053 .in(SwingUtilities.class) 054 .invoke(RepaintManager.class); 055 } catch (RuntimeException e) { 056 return null; 057 } 058 } 059 060 private static FailOnThreadViolationRepaintManager installNew() { 061 FailOnThreadViolationRepaintManager m = new FailOnThreadViolationRepaintManager(); 062 setCurrentManager(m); 063 return m; 064 } 065 066 public FailOnThreadViolationRepaintManager() {} 067 068 public FailOnThreadViolationRepaintManager(boolean completeCheck) { 069 super(completeCheck); 070 } 071 072 /** 073 * Throws a <code>{@link EdtViolationException}</code> when a EDT access violation is found. 074 * @param c the component involved in the EDT violation. 075 * @param stackTraceElements stack trace elements to be set to the thrown exception. 076 * @throws EdtViolationException when a EDT access violation is found. 077 */ 078 @Override void violationFound(JComponent c, StackTraceElement[] stackTraceElements) { 079 EdtViolationException e = new EdtViolationException("EDT violation detected"); 080 if (stackTraceElements != null) e.setStackTrace(stackTraceElements); 081 throw e; 082 } 083 }