6608456: need API to define RepaintManager per components hierarchy
Reviewed-by: alexp
This commit is contained in:
parent
eba63ce088
commit
f7be937495
@ -33,7 +33,7 @@ include $(BUILDDIR)/common/Defs.gmk
|
|||||||
# Files
|
# Files
|
||||||
#
|
#
|
||||||
include FILES.gmk
|
include FILES.gmk
|
||||||
AUTO_FILES_JAVA_DIRS = javax/swing sun/swing
|
AUTO_FILES_JAVA_DIRS = javax/swing sun/swing com/sun/java/swing
|
||||||
AUTO_JAVA_PRUNE = plaf
|
AUTO_JAVA_PRUNE = plaf
|
||||||
|
|
||||||
SUBDIRS = html32dtd plaf
|
SUBDIRS = html32dtd plaf
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Sun designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Sun in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sun.java.swing;
|
||||||
|
|
||||||
|
import sun.awt.AppContext;
|
||||||
|
import java.awt.Component;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.RepaintManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of utility methods for Swing.
|
||||||
|
* <p>
|
||||||
|
* <b>WARNING:</b> While this class is public, it should not be treated as
|
||||||
|
* public API and its API may change in incompatable ways between dot dot
|
||||||
|
* releases and even patch releases. You should not rely on this class even
|
||||||
|
* existing.
|
||||||
|
*
|
||||||
|
* This is a second part of sun.swing.SwingUtilities2. It is required
|
||||||
|
* to provide services for JavaFX applets.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SwingUtilities3 {
|
||||||
|
/**
|
||||||
|
* The {@code clientProperty} key for delegate {@code RepaintManager}
|
||||||
|
*/
|
||||||
|
private static final Object DELEGATE_REPAINT_MANAGER_KEY =
|
||||||
|
new StringBuilder("DelegateRepaintManagerKey");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers delegate RepaintManager for {@code JComponent}.
|
||||||
|
*/
|
||||||
|
public static void setDelegateRepaintManager(JComponent component,
|
||||||
|
RepaintManager repaintManager) {
|
||||||
|
/* setting up flag in AppContext to speed up lookups in case
|
||||||
|
* there are no delegate RepaintManagers used.
|
||||||
|
*/
|
||||||
|
AppContext.getAppContext().put(DELEGATE_REPAINT_MANAGER_KEY,
|
||||||
|
Boolean.TRUE);
|
||||||
|
|
||||||
|
component.putClientProperty(DELEGATE_REPAINT_MANAGER_KEY,
|
||||||
|
repaintManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns delegate {@code RepaintManager} for {@code component} hierarchy.
|
||||||
|
*/
|
||||||
|
public static RepaintManager getDelegateRepaintManager(Component
|
||||||
|
component) {
|
||||||
|
RepaintManager delegate = null;
|
||||||
|
if (Boolean.TRUE == AppContext.getAppContext().get(
|
||||||
|
DELEGATE_REPAINT_MANAGER_KEY)) {
|
||||||
|
while (delegate == null && component != null) {
|
||||||
|
while (component != null
|
||||||
|
&& ! (component instanceof JComponent)) {
|
||||||
|
component = component.getParent();
|
||||||
|
}
|
||||||
|
if (component != null) {
|
||||||
|
delegate = (RepaintManager)
|
||||||
|
((JComponent) component)
|
||||||
|
.getClientProperty(DELEGATE_REPAINT_MANAGER_KEY);
|
||||||
|
component = component.getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
}
|
@ -40,6 +40,8 @@ import sun.awt.SunToolkit;
|
|||||||
import sun.java2d.SunGraphicsEnvironment;
|
import sun.java2d.SunGraphicsEnvironment;
|
||||||
import sun.security.action.GetPropertyAction;
|
import sun.security.action.GetPropertyAction;
|
||||||
|
|
||||||
|
import com.sun.java.swing.SwingUtilities3;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class manages repaint requests, allowing the number
|
* This class manages repaint requests, allowing the number
|
||||||
@ -303,6 +305,11 @@ public class RepaintManager
|
|||||||
*/
|
*/
|
||||||
public synchronized void addInvalidComponent(JComponent invalidComponent)
|
public synchronized void addInvalidComponent(JComponent invalidComponent)
|
||||||
{
|
{
|
||||||
|
RepaintManager delegate = getDelegate(invalidComponent);
|
||||||
|
if (delegate != null) {
|
||||||
|
delegate.addInvalidComponent(invalidComponent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Component validateRoot = null;
|
Component validateRoot = null;
|
||||||
|
|
||||||
/* Find the first JComponent ancestor of this component whose
|
/* Find the first JComponent ancestor of this component whose
|
||||||
@ -373,6 +380,11 @@ public class RepaintManager
|
|||||||
* @see #addInvalidComponent
|
* @see #addInvalidComponent
|
||||||
*/
|
*/
|
||||||
public synchronized void removeInvalidComponent(JComponent component) {
|
public synchronized void removeInvalidComponent(JComponent component) {
|
||||||
|
RepaintManager delegate = getDelegate(component);
|
||||||
|
if (delegate != null) {
|
||||||
|
delegate.removeInvalidComponent(component);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(invalidComponents != null) {
|
if(invalidComponents != null) {
|
||||||
int index = invalidComponents.indexOf(component);
|
int index = invalidComponents.indexOf(component);
|
||||||
if(index != -1) {
|
if(index != -1) {
|
||||||
@ -464,6 +476,11 @@ public class RepaintManager
|
|||||||
*/
|
*/
|
||||||
public void addDirtyRegion(JComponent c, int x, int y, int w, int h)
|
public void addDirtyRegion(JComponent c, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
|
RepaintManager delegate = getDelegate(c);
|
||||||
|
if (delegate != null) {
|
||||||
|
delegate.addDirtyRegion(c, x, y, w, h);
|
||||||
|
return;
|
||||||
|
}
|
||||||
addDirtyRegion0(c, x, y, w, h);
|
addDirtyRegion0(c, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,6 +605,10 @@ public class RepaintManager
|
|||||||
* dirty.
|
* dirty.
|
||||||
*/
|
*/
|
||||||
public Rectangle getDirtyRegion(JComponent aComponent) {
|
public Rectangle getDirtyRegion(JComponent aComponent) {
|
||||||
|
RepaintManager delegate = getDelegate(aComponent);
|
||||||
|
if (delegate != null) {
|
||||||
|
return delegate.getDirtyRegion(aComponent);
|
||||||
|
}
|
||||||
Rectangle r = null;
|
Rectangle r = null;
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
r = (Rectangle)dirtyComponents.get(aComponent);
|
r = (Rectangle)dirtyComponents.get(aComponent);
|
||||||
@ -603,6 +624,11 @@ public class RepaintManager
|
|||||||
* completely painted during the next paintDirtyRegions() call.
|
* completely painted during the next paintDirtyRegions() call.
|
||||||
*/
|
*/
|
||||||
public void markCompletelyDirty(JComponent aComponent) {
|
public void markCompletelyDirty(JComponent aComponent) {
|
||||||
|
RepaintManager delegate = getDelegate(aComponent);
|
||||||
|
if (delegate != null) {
|
||||||
|
delegate.markCompletelyDirty(aComponent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
addDirtyRegion(aComponent,0,0,Integer.MAX_VALUE,Integer.MAX_VALUE);
|
addDirtyRegion(aComponent,0,0,Integer.MAX_VALUE,Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,6 +637,11 @@ public class RepaintManager
|
|||||||
* get painted during the next paintDirtyRegions() call.
|
* get painted during the next paintDirtyRegions() call.
|
||||||
*/
|
*/
|
||||||
public void markCompletelyClean(JComponent aComponent) {
|
public void markCompletelyClean(JComponent aComponent) {
|
||||||
|
RepaintManager delegate = getDelegate(aComponent);
|
||||||
|
if (delegate != null) {
|
||||||
|
delegate.markCompletelyClean(aComponent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
dirtyComponents.remove(aComponent);
|
dirtyComponents.remove(aComponent);
|
||||||
}
|
}
|
||||||
@ -623,6 +654,10 @@ public class RepaintManager
|
|||||||
* if it return true.
|
* if it return true.
|
||||||
*/
|
*/
|
||||||
public boolean isCompletelyDirty(JComponent aComponent) {
|
public boolean isCompletelyDirty(JComponent aComponent) {
|
||||||
|
RepaintManager delegate = getDelegate(aComponent);
|
||||||
|
if (delegate != null) {
|
||||||
|
return delegate.isCompletelyDirty(aComponent);
|
||||||
|
}
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
|
|
||||||
r = getDirtyRegion(aComponent);
|
r = getDirtyRegion(aComponent);
|
||||||
@ -900,6 +935,10 @@ public class RepaintManager
|
|||||||
* repaint manager.
|
* repaint manager.
|
||||||
*/
|
*/
|
||||||
public Image getOffscreenBuffer(Component c,int proposedWidth,int proposedHeight) {
|
public Image getOffscreenBuffer(Component c,int proposedWidth,int proposedHeight) {
|
||||||
|
RepaintManager delegate = getDelegate(c);
|
||||||
|
if (delegate != null) {
|
||||||
|
return delegate.getOffscreenBuffer(c, proposedWidth, proposedHeight);
|
||||||
|
}
|
||||||
return _getOffscreenBuffer(c, proposedWidth, proposedHeight);
|
return _getOffscreenBuffer(c, proposedWidth, proposedHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -917,6 +956,11 @@ public class RepaintManager
|
|||||||
*/
|
*/
|
||||||
public Image getVolatileOffscreenBuffer(Component c,
|
public Image getVolatileOffscreenBuffer(Component c,
|
||||||
int proposedWidth,int proposedHeight) {
|
int proposedWidth,int proposedHeight) {
|
||||||
|
RepaintManager delegate = getDelegate(c);
|
||||||
|
if (delegate != null) {
|
||||||
|
return delegate.getVolatileOffscreenBuffer(c, proposedWidth,
|
||||||
|
proposedHeight);
|
||||||
|
}
|
||||||
GraphicsConfiguration config = c.getGraphicsConfiguration();
|
GraphicsConfiguration config = c.getGraphicsConfiguration();
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
config = GraphicsEnvironment.getLocalGraphicsEnvironment().
|
config = GraphicsEnvironment.getLocalGraphicsEnvironment().
|
||||||
@ -1550,4 +1594,11 @@ public class RepaintManager
|
|||||||
prePaintDirtyRegions();
|
prePaintDirtyRegions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private RepaintManager getDelegate(Component c) {
|
||||||
|
RepaintManager delegate = SwingUtilities3.getDelegateRepaintManager(c);
|
||||||
|
if (this == delegate) {
|
||||||
|
delegate = null;
|
||||||
|
}
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
162
jdk/test/javax/swing/RepaintManager/6608456/bug6608456.java
Normal file
162
jdk/test/javax/swing/RepaintManager/6608456/bug6608456.java
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @test
|
||||||
|
*
|
||||||
|
* @bug 6608456
|
||||||
|
* @author Igor Kushnirskiy
|
||||||
|
* @summary tests if delegate RepaintManager gets invoked.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.RepaintManager;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class bug6608456 {
|
||||||
|
private static final TestFuture testFuture = new TestFuture();
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
final JComponent component = invokeAndWait(
|
||||||
|
new Callable<JComponent>() {
|
||||||
|
public JComponent call() throws Exception {
|
||||||
|
RepaintManager.setCurrentManager(new TestRepaintManager());
|
||||||
|
JFrame frame = new JFrame("test");
|
||||||
|
frame.setLayout(new FlowLayout());
|
||||||
|
JButton button = new JButton("default");
|
||||||
|
|
||||||
|
frame.add(button);
|
||||||
|
button = new JButton("delegate");
|
||||||
|
if ( ! registerDelegate(
|
||||||
|
button, new TestRepaintManager())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
frame.add(button);
|
||||||
|
frame.pack();
|
||||||
|
frame.setVisible(true);
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (component == null) {
|
||||||
|
throw new RuntimeException("failed. can not register delegate");
|
||||||
|
}
|
||||||
|
blockTillDisplayed(component);
|
||||||
|
// trigger repaint for delegate RepaintManager
|
||||||
|
invokeAndWait(
|
||||||
|
new Callable<Void>() {
|
||||||
|
public Void call() {
|
||||||
|
component.repaint();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
if (testFuture.get(10, TimeUnit.SECONDS)) {
|
||||||
|
// passed
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("failed", e);
|
||||||
|
} finally {
|
||||||
|
JFrame frame = (JFrame) SwingUtilities
|
||||||
|
.getAncestorOfClass(JFrame.class, component);
|
||||||
|
if (frame != null) {
|
||||||
|
frame.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static class TestRepaintManager extends RepaintManager {
|
||||||
|
@Override
|
||||||
|
public void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
|
||||||
|
if (RepaintManager.currentManager(c) == this) {
|
||||||
|
testFuture.defaultCalled();
|
||||||
|
} else {
|
||||||
|
testFuture.delegateCalled();
|
||||||
|
}
|
||||||
|
super.addDirtyRegion(c, x, y, w, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static class TestFuture extends FutureTask<Boolean> {
|
||||||
|
private volatile boolean defaultCalled = false;
|
||||||
|
private volatile boolean delegateCalled = false;
|
||||||
|
public TestFuture() {
|
||||||
|
super(new Callable<Boolean>() {
|
||||||
|
public Boolean call() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void defaultCalled() {
|
||||||
|
defaultCalled = true;
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
public void delegateCalled() {
|
||||||
|
delegateCalled = true;
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
private void updateState() {
|
||||||
|
if (defaultCalled && delegateCalled) {
|
||||||
|
set(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean registerDelegate(JComponent c,
|
||||||
|
RepaintManager repaintManager) {
|
||||||
|
boolean rv = false;
|
||||||
|
try {
|
||||||
|
Class<?> clazz = Class.forName("com.sun.java.swing.SwingUtilities3");
|
||||||
|
Method method = clazz.getMethod("setDelegateRepaintManager",
|
||||||
|
JComponent.class, RepaintManager.class);
|
||||||
|
method.invoke(clazz, c, repaintManager);
|
||||||
|
rv = true;
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
static <T> T invokeAndWait(Callable<T> callable) throws Exception {
|
||||||
|
FutureTask<T> future = new FutureTask<T>(callable);
|
||||||
|
SwingUtilities.invokeLater(future);
|
||||||
|
return future.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void blockTillDisplayed(Component comp) {
|
||||||
|
Point p = null;
|
||||||
|
while (p == null) {
|
||||||
|
try {
|
||||||
|
p = comp.getLocationOnScreen();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user