diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java b/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java index 7da3fa313b207..38bb0eec13ea1 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java @@ -27,10 +27,7 @@ import sun.swing.SwingUtilities2; import java.awt.*; import java.awt.font.FontRenderContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import javax.swing.JPasswordField; -import static javax.swing.text.PlainView.isFPMethodOverriden; /** * Implements a View suitable for use in JPasswordField @@ -332,22 +329,6 @@ public float getPreferredSpan(int axis) { static char[] ONE = new char[1]; - private final boolean drawEchoCharacterOverridden; - - { - final Class CLS = getClass(); - final Class INT = Integer.TYPE; - final Class FP = Float.TYPE; - final Class CHAR = Character.TYPE; - - drawEchoCharacterOverridden = AccessController - .doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - Class[] intTypes = {Graphics.class, INT, INT, CHAR}; - Class[] fpTypes = {Graphics2D.class, FP, FP, CHAR}; - return isFPMethodOverriden("drawEchoCharacter", CLS, intTypes, fpTypes); - } - }); - } + private final boolean drawEchoCharacterOverridden = + getFPMethodOverridden(getClass(), "drawEchoCharacter", FPMethodArgs.GNNC); } diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java b/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java index e04c95aecd6ef..4430b4e1c893b 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java @@ -32,6 +32,8 @@ import java.util.Objects; import javax.swing.event.*; import java.lang.reflect.Module; +import java.lang.ref.SoftReference; +import java.util.HashMap; /** * Implements View interface for a simple multi-line text view @@ -818,10 +820,45 @@ private int getLineWidth(Element line) { return w; } - static boolean isFPMethodOverriden(String method, - Class cls, - Class[] intTypes, - Class[] fpTypes) + static boolean getFPMethodOverridden(Class cls, String method, + FPMethodArgs methodArgs) { + HashMap map = null; + boolean initialized = methodsOverriddenMapRef != null + && (map = methodsOverriddenMapRef.get()) != null; + + if (!initialized) { + map = new HashMap<>(); + methodsOverriddenMapRef = new SoftReference<>(map); + } + + FPMethodItem key = new FPMethodItem(cls, method); + Boolean isFPMethodOverridden = map.get(key); + if (isFPMethodOverridden == null) { + isFPMethodOverridden = checkFPMethodOverridden(cls, method, methodArgs); + map.put(key, isFPMethodOverridden); + } + return isFPMethodOverridden; + } + + private static boolean checkFPMethodOverridden(final Class className, + final String methodName, + final FPMethodArgs methodArgs) { + + return AccessController + .doPrivileged(new PrivilegedAction() { + @Override + public Boolean run() { + return isFPMethodOverridden(methodName, className, + methodArgs.getMethodArguments(false), + methodArgs.getMethodArguments(true)); + } + }); + } + + private static boolean isFPMethodOverridden(String method, + Class cls, + Class[] intTypes, + Class[] fpTypes) { Module thisModule = PlainView.class.getModule(); while (!thisModule.equals(cls.getModule())) { @@ -840,6 +877,57 @@ static boolean isFPMethodOverriden(String method, return true; } + enum FPMethodArgs { + + IGNN, + IIGNN, + GNNII, + GNNC; + + public Class[] getMethodArguments(boolean isFPType) { + Class N = (isFPType) ? Float.TYPE : Integer.TYPE; + Class G = (isFPType) ? Graphics2D.class : Graphics.class; + switch (this) { + case IGNN: + return new Class[]{Integer.TYPE, G, N, N}; + case IIGNN: + return new Class[]{Integer.TYPE, Integer.TYPE, G, N, N}; + case GNNII: + return new Class[]{G, N, N, Integer.TYPE, Integer.TYPE}; + case GNNC: + return new Class[]{G, N, N, Character.TYPE}; + default: + throw new RuntimeException("Unknown method arguments!"); + } + } + } + + private static class FPMethodItem { + + final Class className; + final String methodName; + + public FPMethodItem(Class className, String methodName) { + this.className = className; + this.methodName = methodName; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof FPMethodItem) { + FPMethodItem that = (FPMethodItem) obj; + return this.className.equals(that.className) + && this.methodName.equals(that.methodName); + } + return false; + } + + @Override + public int hashCode() { + return 31 * methodName.hashCode() + className.hashCode(); + } + } + // --- member variables ----------------------------------------------- /** @@ -878,46 +966,13 @@ static boolean isFPMethodOverriden(String method, */ int firstLineOffset; - final boolean drawLineOverridden; - final boolean drawSelectedTextOverridden; - final boolean drawUnselectedTextOverridden; - final boolean useFloatingPointAPI; - - { - final Class CLS = getClass(); - final Class INT = Integer.TYPE; - final Class FP = Float.TYPE; - - drawLineOverridden = AccessController - .doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - Class[] intTypes = {INT, Graphics.class, INT, INT}; - Class[] fpTypes = {INT, Graphics2D.class, FP, FP}; - return isFPMethodOverriden("drawLine", CLS, intTypes, fpTypes); - } - }); - - drawUnselectedTextOverridden = AccessController - .doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - Class[] intTypes = {Graphics.class, INT, INT, INT, INT}; - Class[] fpTypes = {Graphics2D.class, FP, FP, INT, INT}; - return isFPMethodOverriden("drawUnselectedText", CLS, intTypes, fpTypes); - } - }); - - drawSelectedTextOverridden = AccessController - .doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - Class[] intTypes = {Graphics.class, INT, INT, INT, INT}; - Class[] fpTypes = {Graphics2D.class, FP, FP, INT, INT}; - return isFPMethodOverriden("drawSelectedText", CLS, intTypes, fpTypes); - } - }); - - useFloatingPointAPI = drawUnselectedTextOverridden || drawSelectedTextOverridden; - } + private static SoftReference> methodsOverriddenMapRef; + final boolean drawLineOverridden = + getFPMethodOverridden(getClass(), "drawLine", FPMethodArgs.IGNN); + final boolean drawSelectedTextOverridden = + getFPMethodOverridden(getClass(), "drawSelectedText", FPMethodArgs.GNNII); + final boolean drawUnselectedTextOverridden = + getFPMethodOverridden(getClass(), "drawUnselectedText", FPMethodArgs.GNNII); + final boolean useFloatingPointAPI = + drawUnselectedTextOverridden || drawSelectedTextOverridden; } diff --git a/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java b/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java index dde3437adf490..7cb83f755c287 100644 --- a/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java @@ -28,10 +28,9 @@ import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.lang.ref.SoftReference; -import java.security.AccessController; -import java.security.PrivilegedAction; import javax.swing.event.*; -import static javax.swing.text.PlainView.isFPMethodOverriden; +import static javax.swing.text.PlainView.FPMethodArgs.*; +import static javax.swing.text.PlainView.getFPMethodOverridden; /** * View of plain text (text with only one font and color) @@ -989,46 +988,12 @@ private int findLine(int[] array, int offset, int min, int max) { SoftReference lineCache = null; } - private final boolean drawLineOverridden; - private final boolean drawSelectedTextOverridden; - private final boolean drawUnselectedTextOverridden; - private final boolean useFloatingPointAPI; - - { - final Class CLS = getClass(); - final Class INT = Integer.TYPE; - final Class FP = Float.TYPE; - - drawLineOverridden = AccessController - .doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - Class[] intTypes = {INT, INT, Graphics.class, INT, INT}; - Class[] fpTypes = {INT, INT, Graphics2D.class, FP, FP}; - return isFPMethodOverriden("drawLine", CLS, intTypes, fpTypes); - } - }); - - drawUnselectedTextOverridden = AccessController - .doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - Class[] intTypes = {Graphics.class, INT, INT, INT, INT}; - Class[] fpTypes = {Graphics2D.class, FP, FP, INT, INT}; - return isFPMethodOverriden("drawUnselectedText", CLS, intTypes, fpTypes); - } - }); - - drawSelectedTextOverridden = AccessController - .doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - Class[] intTypes = {Graphics.class, INT, INT, INT, INT}; - Class[] fpTypes = {Graphics2D.class, FP, FP, INT, INT}; - return isFPMethodOverriden("drawSelectedText", CLS, intTypes, fpTypes); - } - }); - - useFloatingPointAPI = drawUnselectedTextOverridden || drawSelectedTextOverridden; - } + private final boolean drawLineOverridden = + getFPMethodOverridden(getClass(), "drawLine", IIGNN); + private final boolean drawSelectedTextOverridden = + getFPMethodOverridden(getClass(), "drawSelectedText", GNNII); + private final boolean drawUnselectedTextOverridden = + getFPMethodOverridden(getClass(), "drawUnselectedText", GNNII); + private final boolean useFloatingPointAPI = + drawUnselectedTextOverridden || drawSelectedTextOverridden; } diff --git a/jdk/test/javax/swing/text/View/8156217/FPMethodCalledTest.java b/jdk/test/javax/swing/text/View/8156217/FPMethodCalledTest.java index ed9693bbb0c02..5ac336133b898 100644 --- a/jdk/test/javax/swing/text/View/8156217/FPMethodCalledTest.java +++ b/jdk/test/javax/swing/text/View/8156217/FPMethodCalledTest.java @@ -42,7 +42,7 @@ /** * @test - * @bug 8156217 + * @bug 8156217 8169922 * @key headful * @summary Selected text is shifted on HiDPI display * @run main FPMethodCalledTest