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
|
||||
#
|
||||
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
|
||||
|
||||
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.security.action.GetPropertyAction;
|
||||
|
||||
import com.sun.java.swing.SwingUtilities3;
|
||||
|
||||
|
||||
/**
|
||||
* This class manages repaint requests, allowing the number
|
||||
@ -303,6 +305,11 @@ public class RepaintManager
|
||||
*/
|
||||
public synchronized void addInvalidComponent(JComponent invalidComponent)
|
||||
{
|
||||
RepaintManager delegate = getDelegate(invalidComponent);
|
||||
if (delegate != null) {
|
||||
delegate.addInvalidComponent(invalidComponent);
|
||||
return;
|
||||
}
|
||||
Component validateRoot = null;
|
||||
|
||||
/* Find the first JComponent ancestor of this component whose
|
||||
@ -373,6 +380,11 @@ public class RepaintManager
|
||||
* @see #addInvalidComponent
|
||||
*/
|
||||
public synchronized void removeInvalidComponent(JComponent component) {
|
||||
RepaintManager delegate = getDelegate(component);
|
||||
if (delegate != null) {
|
||||
delegate.removeInvalidComponent(component);
|
||||
return;
|
||||
}
|
||||
if(invalidComponents != null) {
|
||||
int index = invalidComponents.indexOf(component);
|
||||
if(index != -1) {
|
||||
@ -464,6 +476,11 @@ public class RepaintManager
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@ -588,6 +605,10 @@ public class RepaintManager
|
||||
* dirty.
|
||||
*/
|
||||
public Rectangle getDirtyRegion(JComponent aComponent) {
|
||||
RepaintManager delegate = getDelegate(aComponent);
|
||||
if (delegate != null) {
|
||||
return delegate.getDirtyRegion(aComponent);
|
||||
}
|
||||
Rectangle r = null;
|
||||
synchronized(this) {
|
||||
r = (Rectangle)dirtyComponents.get(aComponent);
|
||||
@ -603,6 +624,11 @@ public class RepaintManager
|
||||
* completely painted during the next paintDirtyRegions() call.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@ -611,6 +637,11 @@ public class RepaintManager
|
||||
* get painted during the next paintDirtyRegions() call.
|
||||
*/
|
||||
public void markCompletelyClean(JComponent aComponent) {
|
||||
RepaintManager delegate = getDelegate(aComponent);
|
||||
if (delegate != null) {
|
||||
delegate.markCompletelyClean(aComponent);
|
||||
return;
|
||||
}
|
||||
synchronized(this) {
|
||||
dirtyComponents.remove(aComponent);
|
||||
}
|
||||
@ -623,6 +654,10 @@ public class RepaintManager
|
||||
* if it return true.
|
||||
*/
|
||||
public boolean isCompletelyDirty(JComponent aComponent) {
|
||||
RepaintManager delegate = getDelegate(aComponent);
|
||||
if (delegate != null) {
|
||||
return delegate.isCompletelyDirty(aComponent);
|
||||
}
|
||||
Rectangle r;
|
||||
|
||||
r = getDirtyRegion(aComponent);
|
||||
@ -900,6 +935,10 @@ public class RepaintManager
|
||||
* repaint manager.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@ -917,6 +956,11 @@ public class RepaintManager
|
||||
*/
|
||||
public Image getVolatileOffscreenBuffer(Component c,
|
||||
int proposedWidth,int proposedHeight) {
|
||||
RepaintManager delegate = getDelegate(c);
|
||||
if (delegate != null) {
|
||||
return delegate.getVolatileOffscreenBuffer(c, proposedWidth,
|
||||
proposedHeight);
|
||||
}
|
||||
GraphicsConfiguration config = c.getGraphicsConfiguration();
|
||||
if (config == null) {
|
||||
config = GraphicsEnvironment.getLocalGraphicsEnvironment().
|
||||
@ -1550,4 +1594,11 @@ public class RepaintManager
|
||||
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…
Reference in New Issue
Block a user