6642728: Use reflection to access ScrollPane's private method from within sun.awt package

Reviewed-by: art, anthony
This commit is contained in:
Sergey Bylokhov 2011-07-15 19:24:09 +04:00
parent 8dd448e6b8
commit d2567eb057
5 changed files with 50 additions and 47 deletions

View File

@ -24,6 +24,8 @@
*/
package java.awt;
import sun.awt.AWTAccessor;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.peer.ScrollPanePeer;
@ -156,6 +158,12 @@ public class ScrollPaneAdjustable implements Adjustable, Serializable {
if (!GraphicsEnvironment.isHeadless()) {
initIDs();
}
AWTAccessor.setScrollPaneAdjustableAccessor(new AWTAccessor.ScrollPaneAdjustableAccessor() {
public void setTypedValue(final ScrollPaneAdjustable adj,
final int v, final int type) {
adj.setTypedValue(v, type);
}
});
}
/**

View File

@ -25,15 +25,12 @@
package sun.awt;
import sun.misc.Unsafe;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import sun.misc.Unsafe;
import java.awt.peer.ComponentPeer;
import java.security.AccessController;
import java.security.AccessControlContext;
/**
@ -470,6 +467,17 @@ public final class AWTAccessor {
boolean isMultipleMode(FileDialog fileDialog);
}
/*
* An accessor for the ScrollPaneAdjustable class.
*/
public interface ScrollPaneAdjustableAccessor {
/*
* Sets the value of this scrollbar to the specified value.
*/
void setTypedValue(final ScrollPaneAdjustable adj, final int v,
final int type);
}
/*
* Accessor instances are initialized in the static initializers of
* corresponding AWT classes by using setters defined below.
@ -485,6 +493,7 @@ public final class AWTAccessor {
private static EventQueueAccessor eventQueueAccessor;
private static PopupMenuAccessor popupMenuAccessor;
private static FileDialogAccessor fileDialogAccessor;
private static ScrollPaneAdjustableAccessor scrollPaneAdjustableAccessor;
/*
* Set an accessor object for the java.awt.Component class.
@ -675,4 +684,21 @@ public final class AWTAccessor {
return fileDialogAccessor;
}
/*
* Set an accessor object for the java.awt.ScrollPaneAdjustable class.
*/
public static void setScrollPaneAdjustableAccessor(ScrollPaneAdjustableAccessor adj) {
scrollPaneAdjustableAccessor = adj;
}
/*
* Retrieve the accessor object for the java.awt.ScrollPaneAdjustable
* class.
*/
public static ScrollPaneAdjustableAccessor getScrollPaneAdjustableAccessor() {
if (scrollPaneAdjustableAccessor == null) {
unsafe.ensureClassInitialized(ScrollPaneAdjustable.class);
}
return scrollPaneAdjustableAccessor;
}
}

View File

@ -29,6 +29,8 @@ import java.awt.*;
import java.awt.event.*;
import java.awt.peer.*;
import java.lang.reflect.*;
import sun.awt.AWTAccessor;
import sun.awt.SunToolkit;
class XScrollPanePeer extends XComponentPeer implements ScrollPanePeer, XScrollbarClient {
@ -41,9 +43,7 @@ class XScrollPanePeer extends XComponentPeer implements ScrollPanePeer, XScrollb
public final static int VERTICAL = 1 << 0;
public final static int HORIZONTAL = 1 << 1;
private static Method m_setValue;
static {
m_setValue = SunToolkit.getMethod(ScrollPaneAdjustable.class, "setTypedValue", new Class[] {Integer.TYPE, Integer.TYPE});
SCROLLBAR = XToolkit.getUIDefaults().getInt("ScrollBar.defaultWidth");
}
@ -319,17 +319,10 @@ class XScrollPanePeer extends XComponentPeer implements ScrollPanePeer, XScrollb
c.move(sx, sy);
}
void setAdjustableValue(ScrollPaneAdjustable adj, int value, int type) {
try {
m_setValue.invoke(adj, new Object[] {Integer.valueOf(value), Integer.valueOf(type)});
} catch (IllegalAccessException iae) {
adj.setValue(value);
} catch (IllegalArgumentException iae2) {
adj.setValue(value);
} catch (InvocationTargetException ite) {
adj.setValue(value);
ite.getCause().printStackTrace();
}
private void setAdjustableValue(final ScrollPaneAdjustable adj, final int value,
final int type) {
AWTAccessor.getScrollPaneAdjustableAccessor().setTypedValue(adj, value,
type);
}
@Override
void paintPeer(final Graphics g) {

View File

@ -27,6 +27,8 @@ package sun.awt.windows;
import java.awt.*;
import java.awt.event.AdjustmentEvent;
import java.awt.peer.ScrollPanePeer;
import sun.awt.AWTAccessor;
import sun.awt.PeerEvent;
import sun.util.logging.PlatformLogger;
@ -169,8 +171,6 @@ class WScrollPanePeer extends WPanelPeer implements ScrollPanePeer {
}
}
native void setTypedValue(ScrollPaneAdjustable adjustable, int newpos, int type);
/*
* Runnable for the ScrollEvent that performs the adjustment.
*/
@ -247,8 +247,9 @@ class WScrollPanePeer extends WPanelPeer implements ScrollPanePeer {
// Fix for 4075484 - consider type information when creating AdjustmentEvent
// We can't just call adj.setValue() because it creates AdjustmentEvent with type=TRACK
// Instead, we call private method setTypedValue of ScrollPaneAdjustable.
// Because ScrollPaneAdjustable is in another package we should call it through native code.
setTypedValue(adj, newpos, type);
AWTAccessor.getScrollPaneAdjustableAccessor().setTypedValue(adj,
newpos,
type);
// Paint the exposed area right away. To do this - find
// the heavyweight ancestor of the scroll child.

View File

@ -808,29 +808,4 @@ Java_sun_awt_windows_WScrollPanePeer_setSpans(JNIEnv *env, jobject self,
CATCH_BAD_ALLOC;
}
/*
* Class: sun_awt_windows_WScrollPanePeer
* Method: setTypedValue
* Signature: (Ljava/awt/ScrollPaneAdjustable;II)V
*/
JNIEXPORT void JNICALL
Java_sun_awt_windows_WScrollPanePeer_setTypedValue(JNIEnv *env, jobject peer, jobject adjustable, jint value, jint type)
{
// need this global ref to make the class unloadable (see 6500204)
static jclass scrollPaneAdj;
static jmethodID setTypedValueMID = 0;
if (setTypedValueMID == NULL) {
jclass clazz = env->FindClass("java/awt/ScrollPaneAdjustable");
if (safe_ExceptionOccurred(env)) {
env->ExceptionDescribe();
env->ExceptionClear();
}
setTypedValueMID = env->GetMethodID(clazz, "setTypedValue", "(II)V");
scrollPaneAdj = (jclass) env->NewGlobalRef(clazz);
env->DeleteLocalRef(clazz);
DASSERT(setTypedValueMID != NULL);
}
env->CallVoidMethod(adjustable, setTypedValueMID, value, type);
}
} /* extern "C" */