Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/java/swing/SwingUtilities3.java
38923 views
/*1* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.java.swing;2627import sun.awt.EventQueueDelegate;28import sun.awt.AppContext;29import sun.awt.SunToolkit;3031import java.util.Collections;32import java.util.Map;33import java.util.WeakHashMap;34import java.util.concurrent.Callable;35import java.applet.Applet;36import java.awt.AWTEvent;37import java.awt.EventQueue;38import java.awt.Component;39import java.awt.Container;40import java.awt.Window;41import javax.swing.JComponent;42import javax.swing.RepaintManager;4344/**45* A collection of utility methods for Swing.46* <p>47* <b>WARNING:</b> While this class is public, it should not be treated as48* public API and its API may change in incompatable ways between dot dot49* releases and even patch releases. You should not rely on this class even50* existing.51*52* This is a second part of sun.swing.SwingUtilities2. It is required53* to provide services for JavaFX applets.54*55*/56public class SwingUtilities3 {57/**58* The {@code clientProperty} key for delegate {@code RepaintManager}59*/60private static final Object DELEGATE_REPAINT_MANAGER_KEY =61new StringBuilder("DelegateRepaintManagerKey");6263/**64* Registers delegate RepaintManager for {@code JComponent}.65*/66public static void setDelegateRepaintManager(JComponent component,67RepaintManager repaintManager) {68/* setting up flag in AppContext to speed up lookups in case69* there are no delegate RepaintManagers used.70*/71AppContext.getAppContext().put(DELEGATE_REPAINT_MANAGER_KEY,72Boolean.TRUE);7374component.putClientProperty(DELEGATE_REPAINT_MANAGER_KEY,75repaintManager);76}7778private static final Map<Container, Boolean> vsyncedMap =79Collections.synchronizedMap(new WeakHashMap<Container, Boolean>());8081/**82* Sets vsyncRequested state for the {@code rootContainer}. If83* {@code isRequested} is {@code true} then vsynced84* {@code BufferStrategy} is enabled for this {@code rootContainer}.85*86* Note: requesting vsynced painting does not guarantee one. The outcome87* depends on current RepaintManager's RepaintManager.PaintManager88* and on the capabilities of the graphics hardware/software and what not.89*90* @param rootContainer topmost container. Should be either {@code Window}91* or {@code Applet}92* @param isRequested the value to set vsyncRequested state to93*/94public static void setVsyncRequested(Container rootContainer,95boolean isRequested) {96assert (rootContainer instanceof Applet) || (rootContainer instanceof Window);97if (isRequested) {98vsyncedMap.put(rootContainer, Boolean.TRUE);99} else {100vsyncedMap.remove(rootContainer);101}102}103104/**105* Checks if vsync painting is requested for {@code rootContainer}106*107* @param rootContainer topmost container. Should be either Window or Applet108* @return {@code true} if vsync painting is requested for {@code rootContainer}109*/110public static boolean isVsyncRequested(Container rootContainer) {111assert (rootContainer instanceof Applet) || (rootContainer instanceof Window);112return Boolean.TRUE == vsyncedMap.get(rootContainer);113}114115/**116* Returns delegate {@code RepaintManager} for {@code component} hierarchy.117*/118public static RepaintManager getDelegateRepaintManager(Component119component) {120RepaintManager delegate = null;121if (Boolean.TRUE == SunToolkit.targetToAppContext(component)122.get(DELEGATE_REPAINT_MANAGER_KEY)) {123while (delegate == null && component != null) {124while (component != null125&& ! (component instanceof JComponent)) {126component = component.getParent();127}128if (component != null) {129delegate = (RepaintManager)130((JComponent) component)131.getClientProperty(DELEGATE_REPAINT_MANAGER_KEY);132component = component.getParent();133}134135}136}137return delegate;138}139140/*141* We use maps to avoid reflection. Hopefully it should perform better142* this way.143*/144public static void setEventQueueDelegate(145Map<String, Map<String, Object>> map) {146EventQueueDelegate.setDelegate(new EventQueueDelegateFromMap(map));147}148149private static class EventQueueDelegateFromMap150implements EventQueueDelegate.Delegate {151private final AWTEvent[] afterDispatchEventArgument;152private final Object[] afterDispatchHandleArgument;153private final Callable<Void> afterDispatchCallable;154155private final AWTEvent[] beforeDispatchEventArgument;156private final Callable<Object> beforeDispatchCallable;157158private final EventQueue[] getNextEventEventQueueArgument;159private final Callable<AWTEvent> getNextEventCallable;160161@SuppressWarnings("unchecked")162public EventQueueDelegateFromMap(Map<String, Map<String, Object>> objectMap) {163Map<String, Object> methodMap = objectMap.get("afterDispatch");164afterDispatchEventArgument = (AWTEvent[]) methodMap.get("event");165afterDispatchHandleArgument = (Object[]) methodMap.get("handle");166afterDispatchCallable = (Callable<Void>) methodMap.get("method");167168methodMap = objectMap.get("beforeDispatch");169beforeDispatchEventArgument = (AWTEvent[]) methodMap.get("event");170beforeDispatchCallable = (Callable<Object>) methodMap.get("method");171172methodMap = objectMap.get("getNextEvent");173getNextEventEventQueueArgument =174(EventQueue[]) methodMap.get("eventQueue");175getNextEventCallable = (Callable<AWTEvent>) methodMap.get("method");176}177178@Override179public void afterDispatch(AWTEvent event, Object handle) throws InterruptedException {180afterDispatchEventArgument[0] = event;181afterDispatchHandleArgument[0] = handle;182try {183afterDispatchCallable.call();184} catch (InterruptedException e) {185throw e;186} catch (RuntimeException e) {187throw e;188} catch (Exception e) {189throw new RuntimeException(e);190}191}192193@Override194public Object beforeDispatch(AWTEvent event) throws InterruptedException {195beforeDispatchEventArgument[0] = event;196try {197return beforeDispatchCallable.call();198} catch (InterruptedException e) {199throw e;200} catch (RuntimeException e) {201throw e;202} catch (Exception e) {203throw new RuntimeException(e);204}205}206207@Override208public AWTEvent getNextEvent(EventQueue eventQueue) throws InterruptedException {209getNextEventEventQueueArgument[0] = eventQueue;210try {211return getNextEventCallable.call();212} catch (InterruptedException e) {213throw e;214} catch (RuntimeException e) {215throw e;216} catch (Exception e) {217throw new RuntimeException(e);218}219}220}221}222223224