--- a/jdk/make/mapfiles/libsplashscreen/mapfile-vers Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/make/mapfiles/libsplashscreen/mapfile-vers Thu Oct 27 14:52:01 2016 -0400
@@ -44,6 +44,7 @@
SplashSetFileJarName;
SplashSetScaleFactor;
SplashGetScaledImageName;
+ SplashGetScaledImgNameMaxPstfixLen;
local:
*;
};
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2016, Oracle and/or its affiliates. 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
@@ -31,7 +31,7 @@
\ (to execute the main class in a module)\n\
where options include:\n
-java.launcher.opt.datamodel =\ -d{0}\t use a {0}-bit data model if available\n
+java.launcher.opt.datamodel =\ -d{0}\t Deprecated, will be removed in a future release\n
java.launcher.opt.vmselect =\ {0}\t to select the "{1}" VM\n
java.launcher.opt.hotspot =\ {0}\t is a synonym for the "{1}" VM [deprecated]\n
@@ -95,6 +95,12 @@
\ load Java programming language agent, see java.lang.instrument\n\
\ -splash:<imagepath>\n\
\ show splash screen with specified image\n\
+\ HiDPI scaled images are automatically supported and used\n\
+\ if available. The unscaled image filename, e.g. image.ext,\n\
+\ should always be passed as the argument to the -splash option.\n\
+\ The most appropriate scaled image provided will be picked up\n\
+\ automatically.\n\
+\ See the SplashScreen API documentation for more information.\n\
\ @<filepath> read options from the specified file\n\
\To specify an argument for a long option, you can use --<name>=<value> or\n\
\--<name> <value>.\n\
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java Thu Oct 27 14:52:01 2016 -0400
@@ -29,11 +29,9 @@
import java.awt.*;
import java.beans.*;
-import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.Callable;
-import sun.awt.AWTAccessor;
import javax.accessibility.*;
import javax.swing.*;
@@ -73,8 +71,20 @@
}
public void propertyChange(final PropertyChangeEvent evt) {
- if (evt.getNewValue() == null) return;
- focusChanged();
+ Object newValue = evt.getNewValue();
+ if (newValue == null) return;
+ // Don't post focus on things that don't matter, i.e. alert, colorchooser,
+ // desktoppane, dialog, directorypane, filechooser, filler, fontchoose,
+ // frame, glasspane, layeredpane, optionpane, panel, rootpane, separator,
+ // tooltip, viewport, window.
+ // List taken from initializeRoles() in JavaComponentUtilities.m.
+ if (newValue instanceof Accessible) {
+ AccessibleContext nvAC = ((Accessible) newValue).getAccessibleContext();
+ AccessibleRole nvRole = nvAC.getAccessibleRole();
+ if (!ignoredRoles.contains(roleKey(nvRole))) {
+ focusChanged();
+ }
+ }
}
private native void focusChanged();
@@ -683,9 +693,15 @@
if (context == null) continue;
if (whichChildren == JAVA_AX_VISIBLE_CHILDREN) {
- if (!context.getAccessibleComponent().isVisible()) continue;
+ AccessibleComponent acomp = context.getAccessibleComponent();
+ if (acomp == null || !acomp.isVisible()) {
+ continue;
+ }
} else if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
- if (!ac.getAccessibleSelection().isAccessibleChildSelected(i)) continue;
+ AccessibleSelection sel = ac.getAccessibleSelection();
+ if (sel == null || !sel.isAccessibleChildSelected(i)) {
+ continue;
+ }
}
if (!allowIgnored) {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java Thu Oct 27 14:52:01 2016 -0400
@@ -39,7 +39,10 @@
import static javax.accessibility.AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY;
import static javax.accessibility.AccessibleContext.ACCESSIBLE_CARET_PROPERTY;
import static javax.accessibility.AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY;
+import static javax.accessibility.AccessibleContext.ACCESSIBLE_STATE_PROPERTY;
import static javax.accessibility.AccessibleContext.ACCESSIBLE_TEXT_PROPERTY;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
import sun.awt.AWTAccessor;
@@ -63,6 +66,9 @@
private static native void valueChanged(long ptr);
private static native void selectedTextChanged(long ptr);
private static native void selectionChanged(long ptr);
+ private static native void menuOpened(long ptr);
+ private static native void menuClosed(long ptr);
+ private static native void menuItemSelected(long ptr);
private Accessible accessible;
@@ -111,16 +117,45 @@
public void propertyChange(PropertyChangeEvent e) {
String name = e.getPropertyName();
if ( ptr != 0 ) {
+ Object newValue = e.getNewValue();
+ Object oldValue = e.getOldValue();
if (name.compareTo(ACCESSIBLE_CARET_PROPERTY) == 0) {
selectedTextChanged(ptr);
} else if (name.compareTo(ACCESSIBLE_TEXT_PROPERTY) == 0 ) {
valueChanged(ptr);
} else if (name.compareTo(ACCESSIBLE_SELECTION_PROPERTY) == 0 ) {
selectionChanged(ptr);
- } else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) {
- Object nv = e.getNewValue();
- if (nv instanceof AccessibleContext) {
- activeDescendant = (AccessibleContext)nv;
+ } else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) {
+ if (newValue instanceof AccessibleContext) {
+ activeDescendant = (AccessibleContext)newValue;
+ }
+ } else if (name.compareTo(ACCESSIBLE_STATE_PROPERTY) == 0) {
+ AccessibleContext thisAC = accessible.getAccessibleContext();
+ AccessibleRole thisRole = thisAC.getAccessibleRole();
+ Accessible parentAccessible = thisAC.getAccessibleParent();
+ AccessibleRole parentRole = null;
+ if (parentAccessible != null) {
+ parentRole = parentAccessible.getAccessibleContext().getAccessibleRole();
+ }
+ // At least for now don't handle combo box menu state changes.
+ // This may change when later fixing issues which currently
+ // exist for combo boxes, but for now the following is only
+ // for JPopupMenus, not for combobox menus.
+ if (parentRole != AccessibleRole.COMBO_BOX) {
+ if (thisRole == AccessibleRole.POPUP_MENU) {
+ if ( newValue != null &&
+ ((AccessibleState)newValue) == AccessibleState.VISIBLE ) {
+ menuOpened(ptr);
+ } else if ( oldValue != null &&
+ ((AccessibleState)oldValue) == AccessibleState.VISIBLE ) {
+ menuClosed(ptr);
+ }
+ } else if (thisRole == AccessibleRole.MENU_ITEM) {
+ if ( newValue != null &&
+ ((AccessibleState)newValue) == AccessibleState.FOCUSED ) {
+ menuItemSelected(ptr);
+ }
+ }
}
}
}
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java Thu Oct 27 14:52:01 2016 -0400
@@ -97,7 +97,7 @@
int absY = locationOnScreen.y + y;
responder.handleScrollEvent(x, y, absX, absY, modifierFlags, deltaX,
- deltaY);
+ deltaY, NSEvent.SCROLL_PHASE_UNSUPPORTED);
}
public void handleKeyEvent(int eventType, int modifierFlags, String characters,
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java Thu Oct 27 14:52:01 2016 -0400
@@ -44,6 +44,8 @@
private final PlatformEventNotifier eventNotifier;
private final boolean isNpapiCallback;
private int lastKeyPressCode = KeyEvent.VK_UNDEFINED;
+ private final DeltaAccumulator deltaAccumulatorX = new DeltaAccumulator();
+ private final DeltaAccumulator deltaAccumulatorY = new DeltaAccumulator();
CPlatformResponder(final PlatformEventNotifier eventNotifier,
final boolean isNpapiCallback) {
@@ -89,37 +91,37 @@
*/
void handleScrollEvent(final int x, final int y, final int absX,
final int absY, final int modifierFlags,
- final double deltaX, final double deltaY) {
+ final double deltaX, final double deltaY,
+ final int scrollPhase) {
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
final boolean isShift = (jmodifiers & InputEvent.SHIFT_DOWN_MASK) != 0;
+ int roundDeltaX = deltaAccumulatorX.getRoundedDelta(deltaX, scrollPhase);
+ int roundDeltaY = deltaAccumulatorY.getRoundedDelta(deltaY, scrollPhase);
+
// Vertical scroll.
- if (!isShift && deltaY != 0.0) {
- dispatchScrollEvent(x, y, absX, absY, jmodifiers, deltaY);
+ if (!isShift && (deltaY != 0.0 || roundDeltaY != 0)) {
+ dispatchScrollEvent(x, y, absX, absY, jmodifiers, roundDeltaY, deltaY);
}
// Horizontal scroll or shirt+vertical scroll.
final double delta = isShift && deltaY != 0.0 ? deltaY : deltaX;
- if (delta != 0.0) {
+ final int roundDelta = isShift && roundDeltaY != 0 ? roundDeltaY : roundDeltaX;
+ if (delta != 0.0 || roundDelta != 0) {
jmodifiers |= InputEvent.SHIFT_DOWN_MASK;
- dispatchScrollEvent(x, y, absX, absY, jmodifiers, delta);
+ dispatchScrollEvent(x, y, absX, absY, jmodifiers, roundDelta, delta);
}
}
private void dispatchScrollEvent(final int x, final int y, final int absX,
final int absY, final int modifiers,
- final double delta) {
+ final int roundDelta, final double delta) {
final long when = System.currentTimeMillis();
final int scrollType = MouseWheelEvent.WHEEL_UNIT_SCROLL;
final int scrollAmount = 1;
- int wheelRotation = (int) delta;
- int signum = (int) Math.signum(delta);
- if (signum * delta < 1) {
- wheelRotation = signum;
- }
// invert the wheelRotation for the peer
eventNotifier.notifyMouseWheelEvent(when, x, y, absX, absY, modifiers,
scrollType, scrollAmount,
- -wheelRotation, -delta, null);
+ -roundDelta, -delta, null);
}
/**
@@ -260,4 +262,46 @@
void handleWindowFocusEvent(boolean gained, LWWindowPeer opposite) {
eventNotifier.notifyActivation(gained, opposite);
}
+
+ static class DeltaAccumulator {
+
+ static final double MIN_THRESHOLD = 0.1;
+ static final double MAX_THRESHOLD = 0.5;
+ double accumulatedDelta;
+
+ int getRoundedDelta(double delta, int scrollPhase) {
+
+ int roundDelta = (int) Math.round(delta);
+
+ if (scrollPhase == NSEvent.SCROLL_PHASE_UNSUPPORTED) { // mouse wheel
+ if (roundDelta == 0 && delta != 0) {
+ roundDelta = delta > 0 ? 1 : -1;
+ }
+ } else { // trackpad
+ boolean begin = scrollPhase == NSEvent.SCROLL_PHASE_BEGAN;
+ boolean end = scrollPhase == NSEvent.SCROLL_MASK_PHASE_ENDED
+ || scrollPhase == NSEvent.SCROLL_MASK_PHASE_CANCELLED;
+
+ if (begin) {
+ accumulatedDelta = 0;
+ }
+
+ accumulatedDelta += delta;
+
+ double absAccumulatedDelta = Math.abs(accumulatedDelta);
+ if (absAccumulatedDelta > MAX_THRESHOLD) {
+ roundDelta = (int) Math.round(accumulatedDelta);
+ accumulatedDelta -= roundDelta;
+ }
+
+ if (end) {
+ if (roundDelta == 0 && absAccumulatedDelta > MIN_THRESHOLD) {
+ roundDelta = accumulatedDelta > 0 ? 1 : -1;
+ }
+ }
+ }
+
+ return roundDelta;
+ }
+ }
}
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformView.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformView.java Thu Oct 27 14:52:01 2016 -0400
@@ -194,7 +194,8 @@
if (event.getType() == CocoaConstants.NSScrollWheel) {
responder.handleScrollEvent(x, y, absX, absY, event.getModifierFlags(),
- event.getScrollDeltaX(), event.getScrollDeltaY());
+ event.getScrollDeltaX(), event.getScrollDeltaY(),
+ event.getScrollPhase());
} else {
responder.handleMouseEvent(event.getType(), event.getModifierFlags(), event.getButtonNumber(),
event.getClickCount(), x, y,
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java Thu Oct 27 14:52:01 2016 -0400
@@ -32,6 +32,13 @@
* JDK functionality.
*/
final class NSEvent {
+
+ static final int SCROLL_PHASE_UNSUPPORTED = 1;
+ static final int SCROLL_PHASE_BEGAN = 2;
+ static final int SCROLL_PHASE_CONTINUED = 3;
+ static final int SCROLL_MASK_PHASE_CANCELLED = 4;
+ static final int SCROLL_MASK_PHASE_ENDED = 5;
+
private int type;
private int modifierFlags;
@@ -42,6 +49,7 @@
private int y;
private double scrollDeltaY;
private double scrollDeltaX;
+ private int scrollPhase;
private int absX;
private int absY;
@@ -62,7 +70,7 @@
// Called from native
NSEvent(int type, int modifierFlags, int clickCount, int buttonNumber,
int x, int y, int absX, int absY,
- double scrollDeltaY, double scrollDeltaX) {
+ double scrollDeltaY, double scrollDeltaX, int scrollPhase) {
this.type = type;
this.modifierFlags = modifierFlags;
this.clickCount = clickCount;
@@ -73,6 +81,7 @@
this.absY = absY;
this.scrollDeltaY = scrollDeltaY;
this.scrollDeltaX = scrollDeltaX;
+ this.scrollPhase = scrollPhase;
}
int getType() {
@@ -107,6 +116,10 @@
return scrollDeltaX;
}
+ int getScrollPhase() {
+ return scrollPhase;
+ }
+
int getAbsX() {
return absX;
}
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Thu Oct 27 14:52:01 2016 -0400
@@ -383,7 +383,7 @@
}
static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
- static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDD)V");
+ static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V");
jobject jEvent = JNFNewObject(env, jctor_NSEvent,
[event type],
[event modifierFlags],
@@ -392,7 +392,8 @@
(jint)localPoint.x, (jint)localPoint.y,
(jint)absP.x, (jint)absP.y,
[event deltaY],
- [event deltaX]);
+ [event deltaX],
+ [AWTToolkit scrollStateWithEvent: event]);
CHECK_NULL(jEvent);
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m Thu Oct 27 14:52:01 2016 -0400
@@ -317,7 +317,7 @@
[self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
if (IS(self.styleBits, IS_POPUP)) {
- [self.nsWindow setCollectionBehavior:(1 << 8) /*NSWindowCollectionBehaviorFullScreenAuxiliary*/];
+ [self.nsWindow setCollectionBehavior:(1 << 8) /*NSWindowCollectionBehaviorFullScreenAuxiliary*/];
}
return self;
@@ -330,7 +330,7 @@
// returns id for the topmost window under mouse
+ (NSInteger) getTopmostWindowUnderMouseID {
NSInteger result = -1;
-
+
NSRect screenRect = [[NSScreen mainScreen] frame];
NSPoint nsMouseLocation = [NSEvent mouseLocation];
CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
@@ -433,18 +433,18 @@
// Tests wheather the corresponding Java paltform window is visible or not
+ (BOOL) isJavaPlatformWindowVisible:(NSWindow *)window {
BOOL isVisible = NO;
-
+
if ([AWTWindow isAWTWindow:window] && [window delegate] != nil) {
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
[AWTToolkit eventCountPlusPlus];
-
+
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = [awtWindow.javaPlatformWindow jObjectWithEnv:env];
if (platformWindow != NULL) {
static JNF_MEMBER_CACHE(jm_isVisible, jc_CPlatformWindow, "isVisible", "()Z");
isVisible = JNFCallBooleanMethod(env, platformWindow, jm_isVisible) == JNI_TRUE ? YES : NO;
(*env)->DeleteLocalRef(env, platformWindow);
-
+
}
}
return isVisible;
@@ -577,7 +577,9 @@
- (NSRect)windowWillUseStandardFrame:(NSWindow *)window
defaultFrame:(NSRect)newFrame {
- return [self standardFrame];
+ return NSEqualSizes(NSZeroSize, [self standardFrame].size)
+ ? newFrame
+ : [self standardFrame];
}
// Hides/shows window's childs during iconify/de-iconify operation
@@ -1085,17 +1087,17 @@
jdouble width, jdouble height)
{
JNF_COCOA_ENTER(env);
-
+
NSRect jrect = NSMakeRect(originX, originY, width, height);
-
+
NSWindow *nsWindow = OBJC(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
-
+
NSRect rect = ConvertNSScreenRect(NULL, jrect);
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
window.standardFrame = rect;
}];
-
+
JNF_COCOA_EXIT(env);
}
@@ -1366,7 +1368,7 @@
} else {
[JNFException raise:env as:kIllegalArgumentException reason:"unknown event type"];
}
-
+
JNF_COCOA_EXIT(env);
}
@@ -1476,7 +1478,7 @@
if (CGDisplayRelease(aID) == kCGErrorSuccess) {
NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:window.styleBits];
- [nsWindow setStyleMask:styleMask];
+ [nsWindow setStyleMask:styleMask];
[nsWindow setLevel: window.preFullScreenLevel];
// GraphicsDevice takes care of restoring pre full screen bounds
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.m Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.m Thu Oct 27 14:52:01 2016 -0400
@@ -45,7 +45,7 @@
self = [super init];
if (nil != self) {
- javaToMacKeyMap = [NSDictionary dictionaryWithObjectsAndKeys :
+ self.javaToMacKeyMap = [NSDictionary dictionaryWithObjectsAndKeys :
[NSNumber numberWithInt : OSX_Delete], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_BACK_SPACE],
[NSNumber numberWithInt : OSX_kVK_Tab], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_TAB],
[NSNumber numberWithInt : OSX_kVK_Return], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_ENTER],
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m Thu Oct 27 14:52:01 2016 -0400
@@ -139,9 +139,9 @@
jint clickCount;
clickCount = [event clickCount];
-
+
static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
- static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDD)V");
+ static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V");
jobject jEvent = JNFNewObject(env, jctor_NSEvent,
[event type],
[event modifierFlags],
@@ -150,7 +150,8 @@
(jint)localPoint.x, (jint)localPoint.y,
(jint)absP.x, (jint)absP.y,
[event deltaY],
- [event deltaX]);
+ [event deltaX],
+ [AWTToolkit scrollStateWithEvent: event]);
CHECK_NULL(jEvent);
static JNF_CLASS_CACHE(jc_TrayIcon, "sun/lwawt/macosx/CTrayIcon");
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m Thu Oct 27 14:52:01 2016 -0400
@@ -66,7 +66,6 @@
static JNF_MEMBER_CACHE(jf_ptr, sjc_CAccessible, "ptr", "J");
static JNF_STATIC_MEMBER_CACHE(sjm_getCAccessible, sjc_CAccessible, "getCAccessible", "(Ljavax/accessibility/Accessible;)Lsun/lwawt/macosx/CAccessible;");
-
static jobject sAccessibilityClass = NULL;
// sAttributeNamesForRoleCache holds the names of the attributes to which each java
@@ -213,6 +212,24 @@
NSAccessibilityPostNotification(self, NSAccessibilitySelectedChildrenChangedNotification);
}
+- (void)postMenuOpened
+{
+ AWT_ASSERT_APPKIT_THREAD;
+ NSAccessibilityPostNotification(self, (NSString *)kAXMenuOpenedNotification);
+}
+
+- (void)postMenuClosed
+{
+ AWT_ASSERT_APPKIT_THREAD;
+ NSAccessibilityPostNotification(self, (NSString *)kAXMenuClosedNotification);
+}
+
+- (void)postMenuItemSelected
+{
+ AWT_ASSERT_APPKIT_THREAD;
+ NSAccessibilityPostNotification(self, (NSString *)kAXMenuItemSelectedNotification);
+}
+
- (BOOL)isEqual:(id)anObject
{
if (![anObject isKindOfClass:[self class]]) return NO;
@@ -278,8 +295,7 @@
+ (jobject) getCAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env {
if (JNFIsInstanceOf(env, jaccessible, &sjc_CAccessible)) {
return jaccessible;
- }
- else if (JNFIsInstanceOf(env, jaccessible, &sjc_Accessible)) {
+ } else if (JNFIsInstanceOf(env, jaccessible, &sjc_Accessible)) {
return JNFCallStaticObjectMethod(env, sjm_getCAccessible, jaccessible);
}
return NULL;
@@ -368,6 +384,14 @@
// must init freshly -alloc'd object
[newChild initWithParent:parent withEnv:env withAccessible:jCAX withIndex:index withView:view withJavaRole:javaRole]; // must init new instance
+ // If creating a JPopupMenu (not a combobox popup list) need to fire menuOpened.
+ // This is the only way to know if the menu is opening; visible state change
+ // can't be caught because the listeners are not set up in time.
+ if ( [javaRole isEqualToString:@"popupmenu"] &&
+ ![[parent javaRole] isEqualToString:@"combobox"] ) {
+ [newChild postMenuOpened];
+ }
+
// must hard retain pointer poked into Java object
[newChild retain];
JNFSetLongField(env, jCAX, jf_ptr, ptr_to_jlong(newChild));
@@ -634,6 +658,15 @@
return moreNames;
}
}
+ // popupmenu's return values not selected children
+ if ( [javaRole isEqualToString:@"popupmenu"] &&
+ ![[[self parent] javaRole] isEqualToString:@"combobox"] ) {
+ NSMutableArray *moreNames =
+ [[NSMutableArray alloc] initWithCapacity: [names count] + 1];
+ [moreNames addObjectsFromArray: names];
+ [moreNames addObject:NSAccessibilityValueAttribute];
+ return moreNames;
+ }
return names;
} // end @synchronized
@@ -707,6 +740,7 @@
return value;
}
+
- (BOOL)accessibilityIsChildrenAttributeSettable
{
return NO;
@@ -939,6 +973,13 @@
if (fNSRole == nil) {
NSString *javaRole = [self javaRole];
fNSRole = [sRoles objectForKey:javaRole];
+ // The sRoles NSMutableDictionary maps popupmenu to Mac's popup button.
+ // JComboBox behavior currently relies on this. However this is not the
+ // proper mapping for a JPopupMenu so fix that.
+ if ( [javaRole isEqualToString:@"popupmenu"] &&
+ ![[[self parent] javaRole] isEqualToString:@"combobox"] ) {
+ fNSRole = NSAccessibilityMenuRole;
+ }
if (fNSRole == nil) {
// this component has assigned itself a custom AccessibleRole not in the sRoles array
fNSRole = javaRole;
@@ -947,6 +988,7 @@
}
return fNSRole;
}
+
- (BOOL)accessibilityIsRoleAttributeSettable
{
return NO;
@@ -1046,8 +1088,7 @@
- (NSString *)accessibilitySubroleAttribute
{
NSString *value = nil;
- if ([[self javaRole] isEqualToString:@"passwordtext"])
- {
+ if ([[self javaRole] isEqualToString:@"passwordtext"]) {
value = NSAccessibilitySecureTextFieldSubrole;
}
/*
@@ -1123,6 +1164,45 @@
JNIEnv* env = [ThreadUtilities getJNIEnv];
+ // Need to handle popupmenus differently.
+ //
+ // At least for now don't handle combo box menus.
+ // This may change when later fixing issues which currently
+ // exist for combo boxes, but for now the following is only
+ // for JPopupMenus, not for combobox menus.
+ id parent = [self parent];
+ if ( [[self javaRole] isEqualToString:@"popupmenu"] &&
+ ![[parent javaRole] isEqualToString:@"combobox"] ) {
+ NSArray *children =
+ [JavaComponentAccessibility childrenOfParent:self
+ withEnv:env
+ withChildrenCode:JAVA_AX_ALL_CHILDREN
+ allowIgnored:YES];
+ if ([children count] > 0) {
+ // handle case of AXMenuItem
+ // need to ask menu what is selected
+ NSArray *selectedChildrenOfMenu =
+ [self accessibilitySelectedChildrenAttribute];
+ JavaComponentAccessibility *selectedMenuItem =
+ [selectedChildrenOfMenu objectAtIndex:0];
+ if (selectedMenuItem != nil) {
+ jobject itemValue =
+ JNFCallStaticObjectMethod( env,
+ sjm_getAccessibleName,
+ selectedMenuItem->fAccessible,
+ selectedMenuItem->fComponent ); // AWT_THREADING Safe (AWTRunLoop)
+ if (itemValue == NULL) {
+ return nil;
+ }
+ NSString* itemString = JNFJavaToNSString(env, itemValue);
+ (*env)->DeleteLocalRef(env, itemValue);
+ return itemString;
+ } else {
+ return nil;
+ }
+ }
+ }
+
// ask Java for the component's accessibleValue. In java, the "accessibleValue" just means a numerical value
// a text value is taken care of in JavaTextAccessibility
@@ -1345,6 +1425,54 @@
/*
* Class: sun_lwawt_macosx_CAccessible
+ * Method: menuOpened
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuOpened
+(JNIEnv *env, jclass jklass, jlong element)
+{
+JNF_COCOA_ENTER(env);
+ [ThreadUtilities performOnMainThread:@selector(postMenuOpened)
+ on:(JavaComponentAccessibility *)jlong_to_ptr(element)
+ withObject:nil
+ waitUntilDone:NO];
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: sun_lwawt_macosx_CAccessible
+ * Method: menuClosed
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuClosed
+(JNIEnv *env, jclass jklass, jlong element)
+{
+JNF_COCOA_ENTER(env);
+ [ThreadUtilities performOnMainThread:@selector(postMenuClosed)
+ on:(JavaComponentAccessibility *)jlong_to_ptr(element)
+ withObject:nil
+ waitUntilDone:NO];
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: sun_lwawt_macosx_CAccessible
+ * Method: menuItemSelected
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuItemSelected
+(JNIEnv *env, jclass jklass, jlong element)
+{
+JNF_COCOA_ENTER(env);
+ [ThreadUtilities performOnMainThread:@selector(postMenuItemSelected)
+ on:(JavaComponentAccessibility *)jlong_to_ptr(element)
+ withObject:nil
+ waitUntilDone:NO];
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: sun_lwawt_macosx_CAccessible
* Method: unregisterFromCocoaAXSystem
* Signature: (I)V
*/
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.h Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.h Thu Oct 27 14:52:01 2016 -0400
@@ -41,6 +41,7 @@
@interface AWTToolkit : NSObject { }
+ (long) getEventCount;
+ (void) eventCountPlusPlus;
++ (jint) scrollStateWithEvent: (NSEvent*) event;
@end
/*
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Thu Oct 27 14:52:01 2016 -0400
@@ -43,6 +43,13 @@
#import <JavaRuntimeSupport/JavaRuntimeSupport.h>
+// SCROLL PHASE STATE
+#define SCROLL_PHASE_UNSUPPORTED 1
+#define SCROLL_PHASE_BEGAN 2
+#define SCROLL_PHASE_CONTINUED 3
+#define SCROLL_PHASE_CANCELLED 4
+#define SCROLL_PHASE_ENDED 5
+
int gNumberOfButtons;
jint* gButtonDownMasks;
@@ -72,6 +79,23 @@
eventCount++;
}
++ (jint) scrollStateWithEvent: (NSEvent*) event {
+
+ if ([event type] != NSScrollWheel) {
+ return 0;
+ }
+
+ NSEventPhase phase = [event phase];
+ NSEventPhase momentumPhase = [event momentumPhase];
+
+ if (!phase && !momentumPhase) return SCROLL_PHASE_UNSUPPORTED;
+ switch (phase) {
+ case NSEventPhaseBegan: return SCROLL_PHASE_BEGAN;
+ case NSEventPhaseCancelled: return SCROLL_PHASE_CANCELLED;
+ case NSEventPhaseEnded: return SCROLL_PHASE_ENDED;
+ default: return SCROLL_PHASE_CONTINUED;
+ }
+}
@end
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m Thu Oct 27 14:52:01 2016 -0400
@@ -193,6 +193,44 @@
return [sFontFamilyTable objectForKey:fontname];
}
+static void addFont(CTFontUIFontType uiType,
+ NSMutableArray *allFonts,
+ NSMutableDictionary* fontFamilyTable) {
+
+ CTFontRef font = CTFontCreateUIFontForLanguage(uiType, 0.0, NULL);
+ if (font == NULL) {
+ return;
+ }
+ CTFontDescriptorRef desc = CTFontCopyFontDescriptor(font);
+ if (desc == NULL) {
+ CFRelease(font);
+ return;
+ }
+ CFStringRef family = CTFontDescriptorCopyAttribute(desc, kCTFontFamilyNameAttribute);
+ if (family == NULL) {
+ CFRelease(desc);
+ CFRelease(font);
+ return;
+ }
+ CFStringRef name = CTFontDescriptorCopyAttribute(desc, kCTFontNameAttribute);
+ if (name == NULL) {
+ CFRelease(family);
+ CFRelease(desc);
+ CFRelease(font);
+ return;
+ }
+ [allFonts addObject:name];
+ [fontFamilyTable setObject:family forKey:name];
+#ifdef DEBUG
+ NSLog(@"name is : %@", (NSString*)name);
+ NSLog(@"family is : %@", (NSString*)family);
+#endif
+ CFRelease(family);
+ CFRelease(name);
+ CFRelease(desc);
+ CFRelease(font);
+}
+
static NSArray*
GetFilteredFonts()
{
@@ -227,6 +265,16 @@
}
}
+ /*
+ * JavaFX registers these fonts and so JDK needs to do so as well.
+ * If this isn't done we will have mis-matched rendering, since
+ * although these may include fonts that are enumerated normally
+ * they also demonstrably includes fonts that are not.
+ */
+ addFont(kCTFontUIFontSystem, allFonts, fontFamilyTable);
+ addFont(kCTFontUIFontEmphasizedSystem, allFonts, fontFamilyTable);
+ addFont(kCTFontUIFontUserFixedPitch, allFonts, fontFamilyTable);
+
sFilteredFonts = allFonts;
sFontFamilyTable = fontFamilyTable;
}
--- a/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. 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
@@ -47,6 +47,10 @@
#include <sizecalc.h>
#import "ThreadUtilities.h"
+NSString* findScaledImageName(NSString *fileName,
+ NSUInteger dotIndex,
+ NSString *strToAppend);
+
static NSScreen* SplashNSScreen()
{
return [[NSScreen screens] objectAtIndex: 0];
@@ -134,8 +138,8 @@
}
jboolean SplashGetScaledImageName(const char* jar, const char* file,
- float *scaleFactor, char *scaledFile,
- const size_t scaledImageLength) {
+ float *scaleFactor, char *scaledFile,
+ const size_t scaledImageLength) {
*scaleFactor = 1;
if(isSWTRunning()){
@@ -158,18 +162,14 @@
options:NSBackwardsSearch];
NSUInteger dotIndex = range.location;
NSString *fileName2x = nil;
-
- if (dotIndex == NSNotFound) {
- fileName2x = [fileName stringByAppendingString: @"@2x"];
- } else {
- fileName2x = [fileName substringToIndex: dotIndex];
- fileName2x = [fileName2x stringByAppendingString: @"@2x"];
- fileName2x = [fileName2x stringByAppendingString:
- [fileName substringFromIndex: dotIndex]];
+
+ fileName2x = findScaledImageName(fileName, dotIndex, @"@2x");
+ if(![[NSFileManager defaultManager]
+ fileExistsAtPath: fileName2x]) {
+ fileName2x = findScaledImageName(fileName, dotIndex, @"@200pct");
}
-
- if ((fileName2x != nil) && (jar || [[NSFileManager defaultManager]
- fileExistsAtPath: fileName2x])){
+ if (jar || [[NSFileManager defaultManager]
+ fileExistsAtPath: fileName2x]){
if (strlen([fileName2x UTF8String]) > scaledImageLength) {
[pool drain];
return JNI_FALSE;
@@ -458,3 +458,16 @@
sendctl(splash, SPLASHCTL_RECONFIGURE);
}
+NSString* findScaledImageName(NSString *fileName, NSUInteger dotIndex, NSString *strToAppend) {
+ NSString *fileName2x = nil;
+ if (dotIndex == NSNotFound) {
+ fileName2x = [fileName stringByAppendingString: strToAppend];
+ } else {
+ fileName2x = [fileName substringToIndex: dotIndex];
+ fileName2x = [fileName2x stringByAppendingString: strToAppend];
+ fileName2x = [fileName2x stringByAppendingString:
+ [fileName substringFromIndex: dotIndex]];
+ }
+ return fileName2x;
+}
+
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java Thu Oct 27 14:52:01 2016 -0400
@@ -1314,7 +1314,7 @@
super(locale);
this.canWriteCompressed = true;
this.canWriteProgressive = true;
- this.compressionTypes = new String[] {"LZW", "lzw"};
+ this.compressionTypes = new String[] {"LZW"};
this.compressionType = compressionTypes[0];
}
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifComboBoxUI.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifComboBoxUI.java Thu Oct 27 14:52:01 2016 -0400
@@ -298,31 +298,24 @@
public void paintIcon(Component c, Graphics g, int xo, int yo) {
int w = getIconWidth();
int h = getIconHeight();
-
- g.setColor(lightShadow);
- g.drawLine(xo, yo, xo+w-1, yo);
- g.drawLine(xo, yo+1, xo+w-3, yo+1);
- g.setColor(darkShadow);
- g.drawLine(xo+w-2, yo+1, xo+w-1, yo+1);
+ int x1 = xo + w - 1;
+ int y1 = yo;
+ int x2 = xo + w / 2;
+ int y2 = yo + h - 1;
- for ( int x = xo+1, y = yo+2, dx = w-6; y+1 < yo+h; y += 2 ) {
- g.setColor(lightShadow);
- g.drawLine(x, y, x+1, y);
- g.drawLine(x, y+1, x+1, y+1);
- if ( dx > 0 ) {
- g.setColor(fill);
- g.drawLine(x+2, y, x+1+dx, y);
- g.drawLine(x+2, y+1, x+1+dx, y+1);
- }
- g.setColor(darkShadow);
- g.drawLine(x+dx+2, y, x+dx+3, y);
- g.drawLine(x+dx+2, y+1, x+dx+3, y+1);
- x += 1;
- dx -= 2;
- }
+ g.setColor(fill);
+ g.fillPolygon(new int[]{xo, x1, x2}, new int[]{yo, y1, y2}, 3);
+ g.setColor(lightShadow);
+ g.drawLine(xo, yo, x1, y1);
+ g.drawLine(xo, yo + 1, x2, y2);
+ g.drawLine(xo, yo + 1, x1, y1 + 1);
+ g.drawLine(xo + 1, yo + 1, x2, y2 - 1);
g.setColor(darkShadow);
- g.drawLine(xo+(w/2), yo+h-1, xo+(w/2), yo+h-1);
+ g.drawLine(x1, y1 + 1, x2, y2);
+ g.drawLine(x1 - 1, y1 + 1, x2, y2 - 1);
+ g.drawLine(x1 - 1, y1 + 1, x1, y1 + 1); // corner
+ g.drawLine(x2, y2, x2, y2); // corner
}
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifIconFactory.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifIconFactory.java Thu Oct 27 14:52:01 2016 -0400
@@ -249,17 +249,11 @@
if (check) {
// draw check
g.setColor(foreground);
- g.drawLine(csize-2,1,csize-2,2);
- g.drawLine(csize-3,2,csize-3,3);
- g.drawLine(csize-4,3,csize-4,4);
- g.drawLine(csize-5,4,csize-5,6);
- g.drawLine(csize-6,5,csize-6,8);
- g.drawLine(csize-7,6,csize-7,10);
- g.drawLine(csize-8,7,csize-8,10);
- g.drawLine(csize-9,6,csize-9,9);
- g.drawLine(csize-10,5,csize-10,8);
- g.drawLine(csize-11,5,csize-11,7);
- g.drawLine(csize-12,6,csize-12,6);
+ int[] xa = {csize - 12, csize - 8, csize - 7, csize - 4,
+ csize - 2, csize - 2, csize - 8, csize - 10,
+ csize - 11};
+ int[] ya = new int[]{6, 10, 10, 4, 2, 1, 7, 5, 5};
+ g.fillPolygon(xa, ya, 9);
}
g.translate(-x, -y);
g.setColor(oldColor);
@@ -301,50 +295,18 @@
if (checkIn){
g.setColor(shadow);
- g.drawLine(x+5,y+0,x+8,y+0);
- g.drawLine(x+3,y+1,x+4,y+1);
- g.drawLine(x+9,y+1,x+9,y+1);
- g.drawLine(x+2,y+2,x+2,y+2);
- g.drawLine(x+1,y+3,x+1,y+3);
- g.drawLine(x,y+4,x,y+9);
- g.drawLine(x+1,y+10,x+1,y+10);
- g.drawLine(x+2,y+11,x+2,y+11);
+ g.drawArc(x, y, w - 1, h - 1, 45, 180);
g.setColor(highlight);
- g.drawLine(x+3,y+12,x+4,y+12);
- g.drawLine(x+5,y+13,x+8,y+13);
- g.drawLine(x+9,y+12,x+10,y+12);
- g.drawLine(x+11,y+11,x+11,y+11);
- g.drawLine(x+12,y+10,x+12,y+10);
- g.drawLine(x+13,y+9,x+13,y+4);
- g.drawLine(x+12,y+3,x+12,y+3);
- g.drawLine(x+11,y+2,x+11,y+2);
- g.drawLine(x+10,y+1,x+10,y+1);
+ g.drawArc(x, y, w - 1, h - 1, 45, -180);
g.setColor(dot);
- g.fillRect(x+4,y+5,6,4);
- g.drawLine(x+5,y+4,x+8,y+4);
- g.drawLine(x+5,y+9,x+8,y+9);
+ g.fillOval(x + 3, y + 3, 7, 7);
}
else {
g.setColor(highlight);
- g.drawLine(x+5,y+0,x+8,y+0);
- g.drawLine(x+3,y+1,x+4,y+1);
- g.drawLine(x+9,y+1,x+9,y+1);
- g.drawLine(x+2,y+2,x+2,y+2);
- g.drawLine(x+1,y+3,x+1,y+3);
- g.drawLine(x,y+4,x,y+9);
- g.drawLine(x+1,y+10,x+1,y+10);
- g.drawLine(x+2,y+11,x+2,y+11);
+ g.drawArc(x, y, w - 1, h - 1, 45, 180);
g.setColor(shadow);
- g.drawLine(x+3,y+12,x+4,y+12);
- g.drawLine(x+5,y+13,x+8,y+13);
- g.drawLine(x+9,y+12,x+10,y+12);
- g.drawLine(x+11,y+11,x+11,y+11);
- g.drawLine(x+12,y+10,x+12,y+10);
- g.drawLine(x+13,y+9,x+13,y+4);
- g.drawLine(x+12,y+3,x+12,y+3);
- g.drawLine(x+11,y+2,x+11,y+2);
- g.drawLine(x+10,y+1,x+10,y+1);
+ g.drawArc(x, y, w - 1, h - 1, 45, -180);
}
}
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifScrollBarButton.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifScrollBarButton.java Thu Oct 27 14:52:01 2016 -0400
@@ -117,95 +117,57 @@
switch (direction) {
case NORTH:
+ g.setColor(fill);
+ g.fillPolygon(new int[]{cx, 0, s - 1}, new int[]{0, s - 1, s - 1}, 3);
+ g.setColor(trail);
+ g.drawLine(cx, 0, s - 1, s - 2);
+ g.drawLine(0, s - 1, s - 1, s - 1);
+ g.drawLine(s - 1, s - 2, s - 1, s - 1); // corner
g.setColor(lead);
- g.drawLine(cx, 0, cx, 0);
- for (int x = cx - 1, y = 1, dx = 1; y <= s - 2; y += 2) {
- g.setColor(lead);
- g.drawLine(x, y, x, y);
- if (y >= (s - 2)) {
- g.drawLine(x, y + 1, x, y + 1);
- }
- g.setColor(fill);
- g.drawLine(x + 1, y, x + dx, y);
- if (y < (s - 2)) {
- g.drawLine(x, y + 1, x + dx + 1, y + 1);
- }
- g.setColor(trail);
- g.drawLine(x + dx + 1, y, x + dx + 1, y);
- if (y >= (s - 2)) {
- g.drawLine(x + 1, y + 1, x + dx + 1, y + 1);
- }
- dx += 2;
- x -= 1;
- }
+ g.drawLine(cx, 0, 0, s - 2);
+ g.drawLine(cx, 0, cx, 0); // corner
+ g.drawLine(0, s - 1, 0, s - 1); // corner
break;
case SOUTH:
+ g.setColor(fill);
+ g.fillPolygon(new int[]{0, s - 1, cx}, new int[]{1, 1, s}, 3);
g.setColor(trail);
- g.drawLine(cx, s, cx, s);
- for (int x = cx - 1, y = s - 1, dx = 1; y >= 1; y -= 2) {
- g.setColor(lead);
- g.drawLine(x, y, x, y);
- if (y <= 2) {
- g.drawLine(x, y - 1, x + dx + 1, y - 1);
- }
- g.setColor(fill);
- g.drawLine(x + 1, y, x + dx, y);
- if (y > 2) {
- g.drawLine(x, y - 1, x + dx + 1, y - 1);
- }
- g.setColor(trail);
- g.drawLine(x + dx + 1, y, x + dx + 1, y);
-
- dx += 2;
- x -= 1;
- }
+ g.drawLine(s - 1, 2, cx, s);
+ g.drawLine(s - 1, 2, s - 1, 2); // corner
+ g.setColor(lead);
+ g.drawLine(0, 2, cx, s);
+ g.drawLine(0, 1, s - 1, 1);
+ g.drawLine(0, 1, 0, 2);
+ g.setColor(trail);
+ g.drawLine(cx, s, cx, s); // corner
break;
case EAST:
+ g.setColor(fill);
+ g.fillPolygon(new int[]{1, s, 1}, new int[]{0, cy, s}, 3);
+ g.setColor(trail);
+ g.drawLine(1, s, s, cy);
+ g.drawLine(2, s, 2, s); // corner
g.setColor(lead);
+ g.drawLine(1, 0, 1, s);
+ g.drawLine(2, 0, s, cy);
+ g.drawLine(2, 0, 2, 0); // corner
g.drawLine(s, cy, s, cy);
- for (int y = cy - 1, x = s - 1, dy = 1; x >= 1; x -= 2) {
- g.setColor(lead);
- g.drawLine(x, y, x, y);
- if (x <= 2) {
- g.drawLine(x - 1, y, x - 1, y + dy + 1);
- }
- g.setColor(fill);
- g.drawLine(x, y + 1, x, y + dy);
- if (x > 2) {
- g.drawLine(x - 1, y, x - 1, y + dy + 1);
- }
- g.setColor(trail);
- g.drawLine(x, y + dy + 1, x, y + dy + 1);
-
- dy += 2;
- y -= 1;
- }
break;
case WEST:
+ g.setColor(fill);
+ g.fillPolygon(new int[]{0, s - 1, s - 1}, new int[]{cy, 0, s}, 3);
+ g.drawLine(s - 1, 0, s - 1, s);
g.setColor(trail);
- g.drawLine(0, cy, 0, cy);
- for (int y = cy - 1, x = 1, dy = 1; x <= s - 2; x += 2) {
- g.setColor(lead);
- g.drawLine(x, y, x, y);
- if (x >= (s - 2)) {
- g.drawLine(x + 1, y, x + 1, y);
- }
- g.setColor(fill);
- g.drawLine(x, y + 1, x, y + dy);
- if (x < (s - 2)) {
- g.drawLine(x + 1, y, x + 1, y + dy + 1);
- }
- g.setColor(trail);
- g.drawLine(x, y + dy + 1, x, y + dy + 1);
- if (x >= (s - 2)) {
- g.drawLine(x + 1, y + 1, x + 1, y + dy + 1);
- }
- dy += 2;
- y -= 1;
- }
+ g.drawLine(0, cy, s - 1, s);
+ g.drawLine(s - 1, 0, s - 1, s);
+ g.setColor(lead);
+ g.drawLine(0, cy, s - 2, 0);
+ g.drawLine(s - 2, 0, s - 1, 0); // corner
+ g.setColor(trail);
+ g.drawLine(0, cy, 0, cy); // corner
break;
}
}
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AlawCodec.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AlawCodec.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. 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
@@ -30,25 +30,26 @@
import java.util.Vector;
import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.spi.FormatConversionProvider;
/**
* A-law encodes linear data, and decodes a-law data to linear data.
*
* @author Kara Kytle
*/
-public final class AlawCodec extends SunCodec {
+public final class AlawCodec extends FormatConversionProvider {
/* Tables used for A-law decoding */
private static final byte[] ALAW_TABH = new byte[256];
private static final byte[] ALAW_TABL = new byte[256];
- private static final AudioFormat.Encoding[] alawEncodings = { AudioFormat.Encoding.ALAW, AudioFormat.Encoding.PCM_SIGNED };
-
- private static final short seg_end [] = {0xFF, 0x1FF, 0x3FF,
- 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
+ private static final short seg_end[] = {
+ 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
+ };
/**
* Initializes the decode tables.
@@ -73,13 +74,14 @@
}
}
+ @Override
+ public AudioFormat.Encoding[] getSourceEncodings() {
+ return new Encoding[]{Encoding.ALAW, Encoding.PCM_SIGNED};
+ }
- /**
- * Constructs a new ALAW codec object.
- */
- public AlawCodec() {
-
- super(alawEncodings, alawEncodings);
+ @Override
+ public AudioFormat.Encoding[] getTargetEncodings() {
+ return getSourceEncodings();
}
@Override
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. 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
@@ -562,8 +562,7 @@
@Override
public Encoding[] getTargetEncodings() {
- return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
- Encoding.PCM_FLOAT };
+ return getSourceEncodings();
}
@Override
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. 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
@@ -1034,6 +1034,7 @@
// $$fb part of fix for 4679187: Clip.open() throws unexpected Exceptions
Toolkit.isFullySpecifiedAudioFormat(format);
+ Toolkit.validateBuffer(format.getFrameSize(), bufferSize);
byte[] newData = new byte[bufferSize];
System.arraycopy(data, offset, newData, 0, bufferSize);
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/PCMtoPCMCodec.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/PCMtoPCMCodec.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. 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
@@ -30,32 +30,26 @@
import java.util.Vector;
import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.spi.FormatConversionProvider;
/**
* Converts among signed/unsigned and little/big endianness of sampled.
*
* @author Jan Borgersen
*/
-public final class PCMtoPCMCodec extends SunCodec {
-
- private static final AudioFormat.Encoding[] inputEncodings = {
- AudioFormat.Encoding.PCM_SIGNED,
- AudioFormat.Encoding.PCM_UNSIGNED,
- };
+public final class PCMtoPCMCodec extends FormatConversionProvider {
- private static final AudioFormat.Encoding[] outputEncodings = {
- AudioFormat.Encoding.PCM_SIGNED,
- AudioFormat.Encoding.PCM_UNSIGNED,
- };
+ @Override
+ public AudioFormat.Encoding[] getSourceEncodings() {
+ return new Encoding[]{Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED};
+ }
- /**
- * Constructs a new PCMtoPCM codec object.
- */
- public PCMtoPCMCodec() {
-
- super( inputEncodings, outputEncodings);
+ @Override
+ public AudioFormat.Encoding[] getTargetEncodings() {
+ return getSourceEncodings();
}
@Override
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftMixingClip.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftMixingClip.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, Oracle and/or its affiliates. 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
@@ -363,9 +363,7 @@
if (AudioFloatConverter.getConverter(format) == null)
throw new IllegalArgumentException("Invalid format : "
+ format.toString());
- if (bufferSize % format.getFrameSize() != 0)
- throw new IllegalArgumentException(
- "Buffer size does not represent an integral number of sample frames!");
+ Toolkit.validateBuffer(format.getFrameSize(), bufferSize);
if (data != null) {
this.data = Arrays.copyOf(data, data.length);
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SunCodec.java Thu Oct 27 14:50:23 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.media.sound;
-
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.spi.FormatConversionProvider;
-
-/**
- * A codec can encode and/or decode audio data. It provides an
- * AudioInputStream from which processed data may be read.
- * <p>
- * Its input format represents the format of the incoming
- * audio data, or the format of the data in the underlying stream.
- * <p>
- * Its output format represents the format of the processed, outgoing
- * audio data. This is the format of the data which may be read from
- * the filtered stream.
- *
- * @author Kara Kytle
- */
-abstract class SunCodec extends FormatConversionProvider {
-
- private final AudioFormat.Encoding[] inputEncodings;
- private final AudioFormat.Encoding[] outputEncodings;
-
- /**
- * Constructs a new codec object.
- */
- SunCodec(final AudioFormat.Encoding[] inputEncodings,
- final AudioFormat.Encoding[] outputEncodings) {
- this.inputEncodings = inputEncodings;
- this.outputEncodings = outputEncodings;
- }
-
- @Override
- public final AudioFormat.Encoding[] getSourceEncodings() {
- AudioFormat.Encoding[] encodings = new AudioFormat.Encoding[inputEncodings.length];
- System.arraycopy(inputEncodings, 0, encodings, 0, inputEncodings.length);
- return encodings;
- }
-
- @Override
- public final AudioFormat.Encoding[] getTargetEncodings() {
- AudioFormat.Encoding[] encodings = new AudioFormat.Encoding[outputEncodings.length];
- System.arraycopy(outputEncodings, 0, encodings, 0, outputEncodings.length);
- return encodings;
- }
-}
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/Toolkit.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/Toolkit.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. 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
@@ -149,6 +149,20 @@
return (long) (((double) frames) / format.getFrameRate() * 1000000.0d);
}
+ /**
+ * Throws an exception if the buffer size does not represent an integral
+ * number of sample frames.
+ */
+ static void validateBuffer(final int frameSize, final int bufferSize) {
+ if (bufferSize % frameSize == 0) {
+ return;
+ }
+ throw new IllegalArgumentException(String.format(
+ "Buffer size (%d) does not represent an integral number of "
+ + "sample frames (%d)", bufferSize, frameSize));
+ }
+
+
static void isFullySpecifiedAudioFormat(AudioFormat format) {
if (!format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
&& !format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED)
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/UlawCodec.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/UlawCodec.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. 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
@@ -30,26 +30,26 @@
import java.util.Vector;
import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.spi.FormatConversionProvider;
/**
* U-law encodes linear data, and decodes u-law data to linear data.
*
* @author Kara Kytle
*/
-public final class UlawCodec extends SunCodec {
+public final class UlawCodec extends FormatConversionProvider {
/* Tables used for U-law decoding */
private static final byte[] ULAW_TABH = new byte[256];
private static final byte[] ULAW_TABL = new byte[256];
- private static final AudioFormat.Encoding[] ulawEncodings = {AudioFormat.Encoding.ULAW,
- AudioFormat.Encoding.PCM_SIGNED};
-
- private static final short seg_end [] = {0xFF, 0x1FF, 0x3FF,
- 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
+ private static final short seg_end[] = {
+ 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
+ };
/**
* Initializes the decode tables.
@@ -69,11 +69,14 @@
}
}
- /**
- * Constructs a new ULAW codec object.
- */
- public UlawCodec() {
- super(ulawEncodings, ulawEncodings);
+ @Override
+ public AudioFormat.Encoding[] getSourceEncodings() {
+ return new Encoding[]{Encoding.ULAW, Encoding.PCM_SIGNED};
+ }
+
+ @Override
+ public AudioFormat.Encoding[] getTargetEncodings() {
+ return getSourceEncodings();
}
@Override
--- a/jdk/src/java.desktop/share/classes/java/awt/Component.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java Thu Oct 27 14:52:01 2016 -0400
@@ -851,8 +851,8 @@
{
comp.setGraphicsConfiguration(gc);
}
- public boolean requestFocus(Component comp, FocusEvent.Cause cause) {
- return comp.requestFocus(cause);
+ public void requestFocus(Component comp, FocusEvent.Cause cause) {
+ comp.requestFocus(cause);
}
public boolean canBeFocusOwner(Component comp) {
return comp.canBeFocusOwner();
@@ -7511,8 +7511,51 @@
requestFocusHelper(false, true);
}
- boolean requestFocus(FocusEvent.Cause cause) {
- return requestFocusHelper(false, true, cause);
+
+ /**
+ * Requests by the reason of {@code cause} that this Component get the input
+ * focus, and that this Component's top-level ancestor become the
+ * focused Window. This component must be displayable, focusable, visible
+ * and all of its ancestors (with the exception of the top-level Window)
+ * must be visible for the request to be granted. Every effort will be
+ * made to honor the request; however, in some cases it may be
+ * impossible to do so. Developers must never assume that this
+ * Component is the focus owner until this Component receives a
+ * FOCUS_GAINED event.
+ * <p>
+ * The focus request effect may also depend on the provided
+ * cause value. If this request is succeed the {@code FocusEvent}
+ * generated in the result will receive the cause value specified as the
+ * argument of method. If this request is denied because this Component's
+ * top-level Window cannot become the focused Window, the request will be
+ * remembered and will be granted when the Window is later focused by the
+ * user.
+ * <p>
+ * This method cannot be used to set the focus owner to no Component at
+ * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}
+ * instead.
+ * <p>
+ * Because the focus behavior of this method is platform-dependent,
+ * developers are strongly encouraged to use
+ * {@code requestFocusInWindow(FocusEvent.Cause)} when possible.
+ *
+ * <p>Note: Not all focus transfers result from invoking this method. As
+ * such, a component may receive focus without this or any of the other
+ * {@code requestFocus} methods of {@code Component} being invoked.
+ *
+ * @param cause the cause why the focus is requested
+ * @see FocusEvent
+ * @see FocusEvent.Cause
+ * @see #requestFocusInWindow(FocusEvent.Cause)
+ * @see java.awt.event.FocusEvent
+ * @see #addFocusListener
+ * @see #isFocusable
+ * @see #isDisplayable
+ * @see KeyboardFocusManager#clearGlobalFocusOwner
+ * @since 9
+ */
+ public void requestFocus(FocusEvent.Cause cause) {
+ requestFocusHelper(false, true, cause);
}
/**
@@ -7578,9 +7621,77 @@
return requestFocusHelper(temporary, true);
}
- boolean requestFocus(boolean temporary, FocusEvent.Cause cause) {
+ /**
+ * Requests by the reason of {@code cause} that this {@code Component} get
+ * the input focus, and that this {@code Component}'s top-level ancestor
+ * become the focused {@code Window}. This component must be
+ * displayable, focusable, visible and all of its ancestors (with
+ * the exception of the top-level Window) must be visible for the
+ * request to be granted. Every effort will be made to honor the
+ * request; however, in some cases it may be impossible to do
+ * so. Developers must never assume that this component is the
+ * focus owner until this component receives a FOCUS_GAINED
+ * event. If this request is denied because this component's
+ * top-level window cannot become the focused window, the request
+ * will be remembered and will be granted when the window is later
+ * focused by the user.
+ * <p>
+ * This method returns a boolean value. If {@code false} is returned,
+ * the request is <b>guaranteed to fail</b>. If {@code true} is
+ * returned, the request will succeed <b>unless</b> it is vetoed, or an
+ * extraordinary event, such as disposal of the component's peer, occurs
+ * before the request can be granted by the native windowing system. Again,
+ * while a return value of {@code true} indicates that the request is
+ * likely to succeed, developers must never assume that this component is
+ * the focus owner until this component receives a FOCUS_GAINED event.
+ * <p>
+ * The focus request effect may also depend on the provided
+ * cause value. If this request is succeed the {FocusEvent}
+ * generated in the result will receive the cause value specified as the
+ * argument of the method.
+ * <p>
+ * This method cannot be used to set the focus owner to no component at
+ * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner}
+ * instead.
+ * <p>
+ * Because the focus behavior of this method is platform-dependent,
+ * developers are strongly encouraged to use
+ * {@code requestFocusInWindow} when possible.
+ * <p>
+ * Every effort will be made to ensure that {@code FocusEvent}s
+ * generated as a
+ * result of this request will have the specified temporary value. However,
+ * because specifying an arbitrary temporary state may not be implementable
+ * on all native windowing systems, correct behavior for this method can be
+ * guaranteed only for lightweight {@code Component}s.
+ * This method is not intended
+ * for general use, but exists instead as a hook for lightweight component
+ * libraries, such as Swing.
+ * <p>
+ * Note: Not all focus transfers result from invoking this method. As
+ * such, a component may receive focus without this or any of the other
+ * {@code requestFocus} methods of {@code Component} being invoked.
+ *
+ * @param temporary true if the focus change is temporary,
+ * such as when the window loses the focus; for
+ * more information on temporary focus changes see the
+ *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
+ *
+ * @param cause the cause why the focus is requested
+ * @return {@code false} if the focus change request is guaranteed to
+ * fail; {@code true} if it is likely to succeed
+ * @see FocusEvent
+ * @see FocusEvent.Cause
+ * @see #addFocusListener
+ * @see #isFocusable
+ * @see #isDisplayable
+ * @see KeyboardFocusManager#clearGlobalFocusOwner
+ * @since 9
+ */
+ protected boolean requestFocus(boolean temporary, FocusEvent.Cause cause) {
return requestFocusHelper(temporary, true, cause);
}
+
/**
* Requests that this Component get the input focus, if this
* Component's top-level ancestor is already the focused
@@ -7629,7 +7740,59 @@
return requestFocusHelper(false, false);
}
- boolean requestFocusInWindow(FocusEvent.Cause cause) {
+ /**
+ * Requests by the reason of {@code cause} that this Component get the input
+ * focus, if this Component's top-level ancestor is already the focused
+ * Window. This component must be displayable, focusable, visible
+ * and all of its ancestors (with the exception of the top-level
+ * Window) must be visible for the request to be granted. Every
+ * effort will be made to honor the request; however, in some
+ * cases it may be impossible to do so. Developers must never
+ * assume that this Component is the focus owner until this
+ * Component receives a FOCUS_GAINED event.
+ * <p>
+ * This method returns a boolean value. If {@code false} is returned,
+ * the request is <b>guaranteed to fail</b>. If {@code true} is
+ * returned, the request will succeed <b>unless</b> it is vetoed, or an
+ * extraordinary event, such as disposal of the Component's peer, occurs
+ * before the request can be granted by the native windowing system. Again,
+ * while a return value of {@code true} indicates that the request is
+ * likely to succeed, developers must never assume that this Component is
+ * the focus owner until this Component receives a FOCUS_GAINED event.
+ * <p>
+ * The focus request effect may also depend on the provided
+ * cause value. If this request is succeed the {@code FocusEvent}
+ * generated in the result will receive the cause value specified as the
+ * argument of the method.
+ * <p>
+ * This method cannot be used to set the focus owner to no Component at
+ * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}
+ * instead.
+ * <p>
+ * The focus behavior of this method can be implemented uniformly across
+ * platforms, and thus developers are strongly encouraged to use this
+ * method over {@code requestFocus(FocusEvent.Cause)} when possible.
+ * Code which relies on {@code requestFocus(FocusEvent.Cause)} may exhibit
+ * different focus behavior on different platforms.
+ *
+ * <p>Note: Not all focus transfers result from invoking this method. As
+ * such, a component may receive focus without this or any of the other
+ * {@code requestFocus} methods of {@code Component} being invoked.
+ *
+ * @param cause the cause why the focus is requested
+ * @return {@code false} if the focus change request is guaranteed to
+ * fail; {@code true} if it is likely to succeed
+ * @see #requestFocus(FocusEvent.Cause)
+ * @see FocusEvent
+ * @see FocusEvent.Cause
+ * @see java.awt.event.FocusEvent
+ * @see #addFocusListener
+ * @see #isFocusable
+ * @see #isDisplayable
+ * @see KeyboardFocusManager#clearGlobalFocusOwner
+ * @since 9
+ */
+ public boolean requestFocusInWindow(FocusEvent.Cause cause) {
return requestFocusHelper(false, false, cause);
}
--- a/jdk/src/java.desktop/share/classes/java/awt/DisplayMode.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/java/awt/DisplayMode.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. 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
@@ -142,6 +142,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean equals(Object dm) {
if (dm instanceof DisplayMode) {
return equals((DisplayMode)dm);
@@ -153,9 +154,20 @@
/**
* {@inheritDoc}
*/
+ @Override
public int hashCode() {
return getWidth() + getHeight() + getBitDepth() * 7
+ getRefreshRate() * 13;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return getWidth() + "x" + getHeight() + "x" +
+ (getBitDepth() > 0 ? getBitDepth() + "bpp": "[Multi depth]")
+ + "@" + (getRefreshRate() > 0 ? getRefreshRate() + "Hz" :
+ "[Unknown refresh rate]");
+ }
}
--- a/jdk/src/java.desktop/share/classes/java/awt/Font.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/java/awt/Font.java Thu Oct 27 14:52:01 2016 -0400
@@ -154,6 +154,10 @@
* associated with a font face, each differing in size, style, transform
* and font features.
* <p>
+ * Glyphs may not always be rendered with the requested properties (e.g, font
+ * and style) due to platform limitations such as the absence of suitable
+ * platform fonts to implement a logical font.
+ * <p>
* The {@link GraphicsEnvironment#getAllFonts() getAllFonts} method
* of the {@code GraphicsEnvironment} class returns an
* array of all font faces available in the system. These font faces are
--- a/jdk/src/java.desktop/share/classes/java/awt/SplashScreen.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/java/awt/SplashScreen.java Thu Oct 27 14:52:01 2016 -0400
@@ -65,6 +65,16 @@
* <PRE>
* java -splash:filename.gif Test
* </PRE>
+ * HiDPI scaled image is also supported.
+ * Unscaled image name i.e. filename.gif should be passed in
+ * {@code manifest.mf}/{@code -splash:} option for all image types irrespective of
+ * HiDPI and Non-HiDPI.
+ * Following is the naming convention for scaled images.
+ * Screen scale 1.25: filename@125pct.gif
+ * Screen scale 1.50: filename@150pct.gif
+ * Screen scale 2: filename@200pct.gif and filename@2x.gif both are supported
+ * Screen scale 2.50: filename@250pct.gif
+ * Screen scale 3: filename@300pct.gif and filename@3x.gif both are supported
* The command line interface has higher precedence over the manifest
* setting.
* <p>
--- a/jdk/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadataNode.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadataNode.java Thu Oct 27 14:52:01 2016 -0400
@@ -122,7 +122,7 @@
}
public Node item(int index) {
- if (index < 0 || index > nodes.size()) {
+ if (index < 0 || index >= nodes.size()) {
return null;
}
return nodes.get(index);
@@ -882,7 +882,7 @@
}
private void getElementsByTagName(String name, List<Node> l) {
- if (nodeName.equals(name)) {
+ if (nodeName.equals(name) || "*".equals(name)) {
l.add(this);
}
--- a/jdk/src/java.desktop/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. 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
@@ -25,7 +25,7 @@
package javax.sound.sampled.spi;
-import java.util.Objects;
+import java.util.stream.Stream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
@@ -81,16 +81,8 @@
* {@code false}
* @throws NullPointerException if {@code sourceEncoding} is {@code null}
*/
- public boolean isSourceEncodingSupported(Encoding sourceEncoding) {
- Objects.requireNonNull(sourceEncoding);
- Encoding sourceEncodings[] = getSourceEncodings();
-
- for(int i=0; i<sourceEncodings.length; i++) {
- if( sourceEncoding.equals( sourceEncodings[i]) ) {
- return true;
- }
- }
- return false;
+ public boolean isSourceEncodingSupported(final Encoding sourceEncoding) {
+ return Stream.of(getSourceEncodings()).anyMatch(sourceEncoding::equals);
}
/**
@@ -103,16 +95,8 @@
* {@code false}
* @throws NullPointerException if {@code targetEncoding} is {@code null}
*/
- public boolean isTargetEncodingSupported(Encoding targetEncoding) {
- Objects.requireNonNull(targetEncoding);
- Encoding targetEncodings[] = getTargetEncodings();
-
- for(int i=0; i<targetEncodings.length; i++) {
- if( targetEncoding.equals( targetEncodings[i]) ) {
- return true;
- }
- }
- return false;
+ public boolean isTargetEncodingSupported(final Encoding targetEncoding) {
+ return Stream.of(getTargetEncodings()).anyMatch(targetEncoding::equals);
}
/**
@@ -137,17 +121,10 @@
* @throws NullPointerException if {@code targetEncoding} or
* {@code sourceFormat} are {@code null}
*/
- public boolean isConversionSupported(Encoding targetEncoding,
- AudioFormat sourceFormat) {
- Objects.requireNonNull(targetEncoding);
- Encoding targetEncodings[] = getTargetEncodings(sourceFormat);
-
- for(int i=0; i<targetEncodings.length; i++) {
- if( targetEncoding.equals( targetEncodings[i]) ) {
- return true;
- }
- }
- return false;
+ public boolean isConversionSupported(final Encoding targetEncoding,
+ final AudioFormat sourceFormat) {
+ return Stream.of(getTargetEncodings(sourceFormat))
+ .anyMatch(targetEncoding::equals);
}
/**
@@ -175,17 +152,11 @@
* @throws NullPointerException if {@code targetFormat} or
* {@code sourceFormat} are {@code null}
*/
- public boolean isConversionSupported(AudioFormat targetFormat,
- AudioFormat sourceFormat) {
-
- AudioFormat targetFormats[] = getTargetFormats( targetFormat.getEncoding(), sourceFormat );
-
- for(int i=0; i<targetFormats.length; i++) {
- if( targetFormat.matches( targetFormats[i] ) ) {
- return true;
- }
- }
- return false;
+ public boolean isConversionSupported(final AudioFormat targetFormat,
+ final AudioFormat sourceFormat) {
+ final Encoding targetEncoding = targetFormat.getEncoding();
+ return Stream.of(getTargetFormats(targetEncoding, sourceFormat))
+ .anyMatch(targetFormat::matches);
}
/**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/TextUI.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/TextUI.java Thu Oct 27 14:52:01 2016 -0400
@@ -46,7 +46,11 @@
* @return the coordinates as a {@code Rectangle}
* @exception BadLocationException if the given position does not
* represent a valid location in the associated document
+ *
+ * @deprecated replaced by
+ * {@link #modelToView2D(JTextComponent, int, Position.Bias)}
*/
+ @Deprecated(since = "9")
public abstract Rectangle modelToView(JTextComponent t, int pos) throws BadLocationException;
/**
@@ -59,7 +63,11 @@
* @return the coordinates as a {@code Rectangle}
* @exception BadLocationException if the given position does not
* represent a valid location in the associated document
+ *
+ * @deprecated replaced by
+ * {@link #modelToView2D(JTextComponent, int, Position.Bias)}
*/
+ @Deprecated(since = "9")
public abstract Rectangle modelToView(JTextComponent t, int pos, Position.Bias bias) throws BadLocationException;
/**
@@ -92,7 +100,11 @@
* should be in the same coordinate system as the mouse
* events.
* @return the offset from the start of the document >= 0
+ *
+ * @deprecated replaced by
+ * {@link #viewToModel2D(JTextComponent, Point2D, Position.Bias[])}
*/
+ @Deprecated(since = "9")
public abstract int viewToModel(JTextComponent t, Point pt);
/**
@@ -110,7 +122,11 @@
*
* @return the location within the model that best represents the
* given point in the view >= 0
+ *
+ * @deprecated replaced by
+ * {@link #viewToModel2D(JTextComponent, Point2D, Position.Bias[])}
*/
+ @Deprecated(since = "9")
public abstract int viewToModel(JTextComponent t, Point pt,
Position.Bias[] biasReturn);
@@ -222,7 +238,11 @@
* @return a {@code String} containing the tooltip
* @see javax.swing.text.JTextComponent#getToolTipText
* @since 1.4
+ *
+ * @deprecated replaced by
+ * {@link #getToolTipText2D(JTextComponent, Point2D)}
*/
+ @Deprecated(since = "9")
public String getToolTipText(JTextComponent t, Point pt) {
return null;
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java Thu Oct 27 14:52:01 2016 -0400
@@ -28,6 +28,8 @@
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.awt.im.InputContext;
import java.beans.*;
import java.io.*;
@@ -1047,7 +1049,12 @@
* @exception BadLocationException if the given position does not
* represent a valid location in the associated document
* @see TextUI#modelToView
+ *
+ * @deprecated replaced by
+ * {@link #modelToView2D(JTextComponent, int, Position.Bias)}
*/
+ @Deprecated(since = "9")
+ @Override
public Rectangle modelToView(JTextComponent tc, int pos) throws BadLocationException {
return modelToView(tc, pos, Position.Bias.Forward);
}
@@ -1064,8 +1071,30 @@
* @exception BadLocationException if the given position does not
* represent a valid location in the associated document
* @see TextUI#modelToView
+ *
+ * @deprecated replaced by
+ * {@link #modelToView2D(JTextComponent, int, Position.Bias)}
*/
- public Rectangle modelToView(JTextComponent tc, int pos, Position.Bias bias) throws BadLocationException {
+ @Deprecated(since = "9")
+ @Override
+ public Rectangle modelToView(JTextComponent tc, int pos, Position.Bias bias)
+ throws BadLocationException
+ {
+ return (Rectangle) modelToView(tc, pos, bias, false);
+ }
+
+ @Override
+ public Rectangle2D modelToView2D(JTextComponent tc, int pos,
+ Position.Bias bias)
+ throws BadLocationException
+ {
+ return modelToView(tc, pos, bias, true);
+ }
+
+ private Rectangle2D modelToView(JTextComponent tc, int pos,
+ Position.Bias bias, boolean useFPAPI)
+ throws BadLocationException
+ {
Document doc = editor.getDocument();
if (doc instanceof AbstractDocument) {
((AbstractDocument)doc).readLock();
@@ -1076,7 +1105,7 @@
rootView.setSize(alloc.width, alloc.height);
Shape s = rootView.modelToView(pos, alloc, bias);
if (s != null) {
- return s.getBounds();
+ return useFPAPI ? s.getBounds2D() : s.getBounds();
}
}
} finally {
@@ -1099,7 +1128,12 @@
* @return the offset from the start of the document >= 0,
* -1 if not painted
* @see TextUI#viewToModel
+ *
+ * @deprecated replaced by
+ * {@link #viewToModel2D(JTextComponent, Point2D, Position.Bias[])}
*/
+ @Deprecated(since = "9")
+ @Override
public int viewToModel(JTextComponent tc, Point pt) {
return viewToModel(tc, pt, discardBias);
}
@@ -1116,9 +1150,25 @@
* @return the offset from the start of the document >= 0,
* -1 if the component doesn't yet have a positive size.
* @see TextUI#viewToModel
+ *
+ * @deprecated replaced by
+ * {@link #viewToModel2D(JTextComponent, Point2D, Position.Bias[])}
*/
+ @Deprecated(since = "9")
+ @Override
public int viewToModel(JTextComponent tc, Point pt,
Position.Bias[] biasReturn) {
+ return viewToModel(tc, pt.x, pt.y, biasReturn);
+ }
+
+ @Override
+ public int viewToModel2D(JTextComponent tc, Point2D pt,
+ Position.Bias[] biasReturn) {
+ return viewToModel(tc, (float) pt.getX(), (float) pt.getY(), biasReturn);
+ }
+
+ private int viewToModel(JTextComponent tc, float x, float y,
+ Position.Bias[] biasReturn) {
int offs = -1;
Document doc = editor.getDocument();
if (doc instanceof AbstractDocument) {
@@ -1128,7 +1178,7 @@
Rectangle alloc = getVisibleEditorRect();
if (alloc != null) {
rootView.setSize(alloc.width, alloc.height);
- offs = rootView.viewToModel(pt.x, pt.y, alloc, biasReturn);
+ offs = rootView.viewToModel(x, y, alloc, biasReturn);
}
} finally {
if (doc instanceof AbstractDocument) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/multi/MultiTextUI.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/multi/MultiTextUI.java Thu Oct 27 14:52:01 2016 -0400
@@ -38,6 +38,8 @@
import javax.swing.JComponent;
import java.awt.Graphics;
import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import javax.accessibility.Accessible;
/**
@@ -97,7 +99,11 @@
*
* @return the value obtained from the first UI, which is
* the UI obtained from the default <code>LookAndFeel</code>
+ *
+ * @deprecated replaced by
+ * {@link #modelToView2D(JTextComponent, int, Position.Bias)}
*/
+ @Deprecated(since = "9")
public Rectangle modelToView(JTextComponent a, int b)
throws BadLocationException {
Rectangle returnValue =
@@ -113,7 +119,12 @@
*
* @return the value obtained from the first UI, which is
* the UI obtained from the default <code>LookAndFeel</code>
+ *
+ * @deprecated replaced by
+ * {@link #modelToView2D(JTextComponent, int, Position.Bias)}
*/
+ @Deprecated(since = "9")
+ @Override
public Rectangle modelToView(JTextComponent a, int b, Position.Bias c)
throws BadLocationException {
Rectangle returnValue =
@@ -124,12 +135,24 @@
return returnValue;
}
+ @Override
+ public Rectangle2D modelToView2D(JTextComponent a, int b, Position.Bias c) throws BadLocationException {
+ Rectangle2D returnValue =
+ ((TextUI) (uis.elementAt(0))).modelToView2D(a,b,c);
+ for (int i = 1; i < uis.size(); i++) {
+ ((TextUI) (uis.elementAt(i))).modelToView2D(a,b,c);
+ }
+ return returnValue;
+ }
+
/**
* Invokes the <code>viewToModel</code> method on each UI handled by this object.
*
* @return the value obtained from the first UI, which is
* the UI obtained from the default <code>LookAndFeel</code>
*/
+ @Deprecated(since = "9")
+ @Override
public int viewToModel(JTextComponent a, Point b) {
int returnValue =
((TextUI) (uis.elementAt(0))).viewToModel(a,b);
@@ -145,6 +168,8 @@
* @return the value obtained from the first UI, which is
* the UI obtained from the default <code>LookAndFeel</code>
*/
+ @Deprecated(since = "9")
+ @Override
public int viewToModel(JTextComponent a, Point b, Position.Bias[] c) {
int returnValue =
((TextUI) (uis.elementAt(0))).viewToModel(a,b,c);
@@ -154,6 +179,16 @@
return returnValue;
}
+ @Override
+ public int viewToModel2D(JTextComponent a, Point2D b, Position.Bias[] c) {
+ int returnValue =
+ ((TextUI) (uis.elementAt(0))).viewToModel2D(a,b,c);
+ for (int i = 1; i < uis.size(); i++) {
+ ((TextUI) (uis.elementAt(i))).viewToModel2D(a,b,c);
+ }
+ return returnValue;
+ }
+
/**
* Invokes the <code>getNextVisualPositionFrom</code> method on each UI handled by this object.
*
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/GlyphPainter1.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/GlyphPainter1.java Thu Oct 27 14:52:01 2016 -0400
@@ -98,26 +98,27 @@
Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds();
// determine the x coordinate to render the glyphs
- int x = alloc.x;
+ float x = alloc.x;
int p = v.getStartOffset();
int[] justificationData = getJustificationData(v);
if (p != p0) {
text = v.getText(p, p0);
- int width = Utilities.getTabbedTextWidth(v, text, metrics, x, expander, p,
- justificationData);
+ float width = Utilities.getTabbedTextWidth(v, text, metrics, x,
+ expander, p,
+ justificationData);
x += width;
SegmentCache.releaseSharedSegment(text);
}
// determine the y coordinate to render the glyphs
- int y = alloc.y + metrics.getHeight() - metrics.getDescent();
+ float y = alloc.y + metrics.getHeight() - metrics.getDescent();
// render the glyphs
text = v.getText(p0, p1);
g.setFont(metrics.getFont());
Utilities.drawTabbedText(v, text, x, y, g, expander,p0,
- justificationData);
+ justificationData, true);
SegmentCache.releaseSharedSegment(text);
}
@@ -210,9 +211,9 @@
TabExpander expander = v.getTabExpander();
Segment s = v.getText(p0, v.getEndOffset());
int[] justificationData = getJustificationData(v);
- int index = Utilities.getTabbedTextOffset(v, s, metrics, (int)x, (int)(x+len),
+ int index = Utilities.getTabbedTextOffset(v, s, metrics, x, (x+len),
expander, p0, false,
- justificationData);
+ justificationData, true);
SegmentCache.releaseSharedSegment(s);
int p1 = p0 + index;
return p1;
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/GlyphPainter2.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/GlyphPainter2.java Thu Oct 27 14:52:01 2016 -0400
@@ -145,8 +145,9 @@
// vertical at the baseline, should use slope and check if glyphs
// are being rendered vertically.
- alloc.setRect(alloc.getX() + locs[0], alloc.getY(), 1, alloc.getHeight());
- return alloc;
+ Rectangle2D rect = new Rectangle2D.Float();
+ rect.setRect(alloc.getX() + locs[0], alloc.getY(), 1, alloc.getHeight());
+ return rect;
}
/**
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java Thu Oct 27 14:52:01 2016 -0400
@@ -49,6 +49,8 @@
import java.awt.im.InputMethodRequests;
import java.awt.font.TextHitInfo;
import java.awt.font.TextAttribute;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
@@ -1370,12 +1372,38 @@
* @exception BadLocationException if the given position does not
* represent a valid location in the associated document
* @see TextUI#modelToView
+ *
+ * @deprecated replaced by
+ * {@link #modelToView2D(int)}
*/
+ @Deprecated(since = "9")
public Rectangle modelToView(int pos) throws BadLocationException {
return getUI().modelToView(this, pos);
}
/**
+ * Converts the given location in the model to a place in
+ * the view coordinate system.
+ * The component must have a positive size for
+ * this translation to be computed (i.e. layout cannot
+ * be computed until the component has been sized). The
+ * component does not have to be visible or painted.
+ *
+ * @param pos the position {@code >= 0}
+ * @return the coordinates as a rectangle, with (r.x, r.y) as the location
+ * in the coordinate system, or null if the component does
+ * not yet have a positive size.
+ * @exception BadLocationException if the given position does not
+ * represent a valid location in the associated document
+ * @see TextUI#modelToView2D
+ *
+ * @since 9
+ */
+ public Rectangle2D modelToView2D(int pos) throws BadLocationException {
+ return getUI().modelToView2D(this, pos, Position.Bias.Forward);
+ }
+
+ /**
* Converts the given place in the view coordinate system
* to the nearest representative location in the model.
* The component must have a positive size for
@@ -1388,12 +1416,36 @@
* or -1 if the component does not yet have a positive
* size.
* @see TextUI#viewToModel
+ *
+ * @deprecated replaced by
+ * {@link #viewToModel2D(Point2D)}
*/
+ @Deprecated(since = "9")
public int viewToModel(Point pt) {
return getUI().viewToModel(this, pt);
}
/**
+ * Converts the given place in the view coordinate system
+ * to the nearest representative location in the model.
+ * The component must have a positive size for
+ * this translation to be computed (i.e. layout cannot
+ * be computed until the component has been sized). The
+ * component does not have to be visible or painted.
+ *
+ * @param pt the location in the view to translate
+ * @return the offset {@code >= 0} from the start of the document,
+ * or {@code -1} if the component does not yet have a positive
+ * size.
+ * @see TextUI#viewToModel2D
+ *
+ * @since 9
+ */
+ public int viewToModel2D(Point2D pt) {
+ return getUI().viewToModel2D(this, pt, new Position.Bias[1]);
+ }
+
+ /**
* Transfers the currently selected range in the associated
* text model to the system clipboard, removing the contents
* from the model. The current selection is reset. Does nothing
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/ParagraphView.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/ParagraphView.java Thu Oct 27 14:52:01 2016 -0400
@@ -27,6 +27,7 @@
import java.util.Arrays;
import java.awt.*;
import java.awt.font.TextAttribute;
+import java.awt.geom.Rectangle2D;
import javax.swing.event.*;
import javax.swing.SizeRequirements;
@@ -888,10 +889,9 @@
int height = r.height;
int y = r.y;
Shape loc = super.modelToView(pos, a, b);
- r = loc.getBounds();
- r.height = height;
- r.y = y;
- return r;
+ Rectangle2D bounds = loc.getBounds2D();
+ bounds.setRect(bounds.getX(), y, bounds.getWidth(), height);
+ return bounds;
}
/**
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java Thu Oct 27 14:52:01 2016 -0400
@@ -26,7 +26,11 @@
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
@@ -61,15 +65,40 @@
* @param p1 the ending offset in the model >= p0
* @return the X location of the end of the range >= 0
* @exception BadLocationException if p0 or p1 are out of range
+ *
+ * @deprecated replaced by
+ * {@link #drawUnselectedText(Graphics2D, float, float, int, int)}
*/
+ @Deprecated(since = "9")
+ @Override
protected int drawUnselectedText(Graphics g, int x, int y,
int p0, int p1) throws BadLocationException {
+ return (int) drawUnselectedTextImpl(g, x, y, p0, p1, false);
+ }
+ @Override
+ protected float drawUnselectedText(Graphics2D g, float x, float y,
+ int p0, int p1)
+ throws BadLocationException
+ {
+ return drawUnselectedTextImpl(g, x, y, p0, p1, true);
+ }
+
+ private float drawUnselectedTextImpl(Graphics g, float x, float y,
+ int p0, int p1,
+ boolean useFPAPI)
+ throws BadLocationException
+ {
Container c = getContainer();
if (c instanceof JPasswordField) {
JPasswordField f = (JPasswordField) c;
- if (! f.echoCharIsSet()) {
- return super.drawUnselectedText(g, x, y, p0, p1);
+ if (!f.echoCharIsSet()) {
+ boolean useDrawUnselectedFPAPI = useFPAPI
+ && drawUnselectedTextOverridden
+ && g instanceof Graphics2D;
+ return (useDrawUnselectedFPAPI )
+ ? super.drawUnselectedText((Graphics2D) g, x, y, p0, p1)
+ : super.drawUnselectedText(g, (int) x, (int) y, p0, p1);
}
if (f.isEnabled()) {
g.setColor(f.getForeground());
@@ -79,8 +108,13 @@
}
char echoChar = f.getEchoChar();
int n = p1 - p0;
+ boolean useEchoCharFPAPI = useFPAPI
+ && drawEchoCharacterOverridden
+ && g instanceof Graphics2D;
for (int i = 0; i < n; i++) {
- x = drawEchoCharacter(g, x, y, echoChar);
+ x = (useEchoCharFPAPI)
+ ? drawEchoCharacter((Graphics2D) g, x, y, echoChar)
+ : drawEchoCharacter(g, (int) x, (int) y, echoChar);
}
}
return x;
@@ -100,20 +134,50 @@
* @param p1 the ending offset in the model >= p0
* @return the X location of the end of the range >= 0
* @exception BadLocationException if p0 or p1 are out of range
+ *
+ * @deprecated replaced by
+ * {@link #drawSelectedText(Graphics2D, float, float, int, int)}
*/
+ @Deprecated(since = "9")
+ @Override
protected int drawSelectedText(Graphics g, int x,
int y, int p0, int p1) throws BadLocationException {
+ return (int) drawSelectedTextImpl(g, x, y, p0, p1, false);
+ }
+
+ @Override
+ protected float drawSelectedText(Graphics2D g, float x, float y,
+ int p0, int p1) throws BadLocationException
+ {
+ return drawSelectedTextImpl(g, x, y, p0, p1, true);
+ }
+
+ private float drawSelectedTextImpl(Graphics g, float x, float y,
+ int p0, int p1,
+ boolean useFPAPI)
+ throws BadLocationException {
g.setColor(selected);
Container c = getContainer();
if (c instanceof JPasswordField) {
JPasswordField f = (JPasswordField) c;
- if (! f.echoCharIsSet()) {
- return super.drawSelectedText(g, x, y, p0, p1);
+ if (!f.echoCharIsSet()) {
+ boolean useDrawUnselectedFPAPI = useFPAPI
+ && drawSelectedTextOverridden
+ && g instanceof Graphics2D;
+ return (useFPAPI)
+ ? super.drawSelectedText((Graphics2D) g, x, y, p0, p1)
+ : super.drawSelectedText(g, (int) x, (int) y, p0, p1);
}
char echoChar = f.getEchoChar();
int n = p1 - p0;
+ boolean useEchoCharFPAPI = useFPAPI
+ && drawEchoCharacterOverridden
+ && g instanceof Graphics2D;
for (int i = 0; i < n; i++) {
- x = drawEchoCharacter(g, x, y, echoChar);
+ x = (useEchoCharFPAPI)
+ ? drawEchoCharacter((Graphics2D) g, x, y, echoChar)
+ : drawEchoCharacter(g, (int) x, (int) y, echoChar);
+
}
}
return x;
@@ -130,12 +194,13 @@
* @param y the starting Y coordinate >= 0
* @param c the echo character
* @return the updated X position >= 0
+ *
+ * @deprecated replaced by
+ * {@link #drawEchoCharacter(Graphics2D, float, float, char)}
*/
+ @Deprecated(since = "9")
protected int drawEchoCharacter(Graphics g, int x, int y, char c) {
- ONE[0] = c;
- SwingUtilities2.drawChars(Utilities.getJComponent(this),
- g, ONE, 0, 1, x, y);
- return x + g.getFontMetrics().charWidth(c);
+ return (int) drawEchoCharacterImpl(g, x, y, c, false);
}
/**
@@ -144,18 +209,29 @@
* object is set to the appropriate foreground color for selected
* or unselected text.
*
- * @implSpec This implementation calls
- * {@link #drawEchoCharacter(Graphics, int, int, char)
- * drawEchoCharacter((Graphics) g, (int) x, (int) y, c)}.
- *
* @param g the graphics context
* @param x the starting X coordinate {@code >= 0}
* @param y the starting Y coordinate {@code >= 0}
* @param c the echo character
* @return the updated X position {@code >= 0}
+ *
+ * @since 9
*/
protected float drawEchoCharacter(Graphics2D g, float x, float y, char c) {
- return drawEchoCharacter((Graphics) g, (int) x, (int) y, c);
+ return drawEchoCharacterImpl(g, x, y, c, true);
+ }
+
+ private float drawEchoCharacterImpl(Graphics g, float x, float y,
+ char c, boolean useFPAPI) {
+ ONE[0] = c;
+ SwingUtilities2.drawChars(Utilities.getJComponent(this),
+ g, ONE, 0, 1, x, y);
+ if (useFPAPI) {
+ return x + g.getFontMetrics().charWidth(c);
+ } else {
+ FontRenderContext frc = g.getFontMetrics().getFontRenderContext();
+ return x + (float) g.getFont().getStringBounds(ONE, 0, 1, frc).getWidth();
+ }
}
/**
@@ -253,4 +329,23 @@
}
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<Boolean>() {
+ @Override
+ public Boolean run() {
+ Class<?>[] intTypes = {Graphics.class, INT, INT, CHAR};
+ Class<?>[] fpTypes = {Graphics2D.class, FP, FP, CHAR};
+ return isFPMethodOverriden("drawEchoCharacter", CLS, intTypes, fpTypes);
+ }
+ });
+ }
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java Thu Oct 27 14:52:01 2016 -0400
@@ -24,11 +24,14 @@
*/
package javax.swing.text;
-import java.util.Vector;
-import java.util.Properties;
import java.awt.*;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.Rectangle2D;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Objects;
import javax.swing.event.*;
+import java.lang.reflect.Module;
/**
* Implements View interface for a simple multi-line text view
@@ -61,17 +64,6 @@
}
/**
- * Returns the tab size set for the document, defaulting to 8.
- *
- * @implSpec This implementation calls {@link #getTabSize() getTabSize()}.
- *
- * @return the tab size
- */
- protected float getFractionalTabSize() {
- return getTabSize();
- }
-
- /**
* Renders a line of text, suppressing whitespace at the end
* and expanding any tabs. This is implemented to make calls
* to the methods <code>drawUnselectedText</code> and
@@ -84,8 +76,16 @@
* @param y the starting Y position >= 0
* @see #drawUnselectedText
* @see #drawSelectedText
+ *
+ * @deprecated replaced by
+ * {@link #drawLine(int, Graphics2D, float, float)}
*/
+ @Deprecated(since = "9")
protected void drawLine(int lineIndex, Graphics g, int x, int y) {
+ drawLineImpl(lineIndex, g, x, y);
+ }
+
+ private void drawLineImpl(int lineIndex, Graphics g, float x, float y) {
Element line = getElement().getElement(lineIndex);
Element elem;
@@ -112,22 +112,23 @@
* {@code drawSelectedText} so that the way selected and
* unselected text are rendered can be customized.
*
- * @implSpec This implementation calls
- * {@link #drawLine(int, Graphics, int, int)
- * drawLine(lineIndex, (Graphics)g, (int) x, (int) y)}.
- *
* @param lineIndex the line to draw {@code >= 0}
* @param g the {@code Graphics} context
* @param x the starting X position {@code >= 0}
* @param y the starting Y position {@code >= 0}
* @see #drawUnselectedText
* @see #drawSelectedText
+ *
+ * @since 9
*/
protected void drawLine(int lineIndex, Graphics2D g, float x, float y) {
- drawLine(lineIndex, (Graphics)g, (int) x, (int) y);
+ drawLineImpl(lineIndex, g, x, y);
}
- private int drawElement(int lineIndex, Element elem, Graphics g, int x, int y) throws BadLocationException {
+ private float drawElement(int lineIndex, Element elem, Graphics g,
+ float x, float y)
+ throws BadLocationException
+ {
int p0 = elem.getStartOffset();
int p1 = elem.getEndOffset();
p1 = Math.min(getDocument().getLength(), p1);
@@ -144,23 +145,23 @@
} else {
if (sel0 == sel1 || selected == unselected) {
// no selection, or it is invisible
- x = drawUnselectedText(g, x, y, p0, p1);
+ x = callDrawUnselectedText(g, x, y, p0, p1);
} else if ((p0 >= sel0 && p0 <= sel1) && (p1 >= sel0 && p1 <= sel1)) {
- x = drawSelectedText(g, x, y, p0, p1);
+ x = callDrawSelectedText(g, x, y, p0, p1);
} else if (sel0 >= p0 && sel0 <= p1) {
if (sel1 >= p0 && sel1 <= p1) {
- x = drawUnselectedText(g, x, y, p0, sel0);
- x = drawSelectedText(g, x, y, sel0, sel1);
- x = drawUnselectedText(g, x, y, sel1, p1);
+ x = callDrawUnselectedText(g, x, y, p0, sel0);
+ x = callDrawSelectedText(g, x, y, sel0, sel1);
+ x = callDrawUnselectedText(g, x, y, sel1, p1);
} else {
- x = drawUnselectedText(g, x, y, p0, sel0);
- x = drawSelectedText(g, x, y, sel0, p1);
+ x = callDrawUnselectedText(g, x, y, p0, sel0);
+ x = callDrawSelectedText(g, x, y, sel0, p1);
}
} else if (sel1 >= p0 && sel1 <= p1) {
- x = drawSelectedText(g, x, y, p0, sel1);
- x = drawUnselectedText(g, x, y, sel1, p1);
+ x = callDrawSelectedText(g, x, y, p0, sel1);
+ x = callDrawUnselectedText(g, x, y, sel1, p1);
} else {
- x = drawUnselectedText(g, x, y, p0, p1);
+ x = callDrawUnselectedText(g, x, y, p0, p1);
}
}
@@ -178,14 +179,36 @@
* @param p1 the ending position in the model >= 0
* @return the X location of the end of the range >= 0
* @exception BadLocationException if the range is invalid
+ *
+ * @deprecated replaced by
+ * {@link #drawUnselectedText(Graphics2D, float, float, int, int)}
*/
+ @Deprecated(since = "9")
protected int drawUnselectedText(Graphics g, int x, int y,
int p0, int p1) throws BadLocationException {
+ return (int) drawUnselectedTextImpl(g, x, y, p0, p1, false);
+ }
+
+ private float callDrawUnselectedText(Graphics g, float x, float y,
+ int p0, int p1)
+ throws BadLocationException
+ {
+ return drawUnselectedTextOverridden && (g instanceof Graphics2D)
+ ? drawUnselectedText((Graphics2D) g, x, y, p0, p1)
+ : drawUnselectedText(g, (int) x, (int) y, p0, p1);
+ }
+
+ private float drawUnselectedTextImpl(Graphics g, float x, float y,
+ int p0, int p1,
+ boolean useFPAPI)
+ throws BadLocationException
+ {
g.setColor(unselected);
Document doc = getDocument();
Segment s = SegmentCache.getSharedSegment();
doc.getText(p0, p1 - p0, s);
- int ret = Utilities.drawTabbedText(this, s, x, y, g, this, p0);
+ float ret = Utilities.drawTabbedText(this, s, x, y, g, this, p0, null,
+ useFPAPI);
SegmentCache.releaseSharedSegment(s);
return ret;
}
@@ -194,10 +217,6 @@
* Renders the given range in the model as normal unselected
* text. Uses the foreground or disabled color to render the text.
*
- * @implSpec This implementation calls
- * {@link #drawUnselectedText(Graphics, int, int, int, int)
- * drawUnselectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
- *
* @param g the graphics context
* @param x the starting X coordinate {@code >= 0}
* @param y the starting Y coordinate {@code >= 0}
@@ -205,10 +224,12 @@
* @param p1 the ending position in the model {@code >= 0}
* @return the X location of the end of the range {@code >= 0}
* @exception BadLocationException if the range is invalid
+ *
+ * @since 9
*/
protected float drawUnselectedText(Graphics2D g, float x, float y,
int p0, int p1) throws BadLocationException {
- return drawUnselectedText((Graphics)g, (int) x, (int) y, p0, p1);
+ return drawUnselectedTextImpl(g, x, y, p0, p1, true);
}
/**
@@ -224,14 +245,38 @@
* @param p1 the ending position in the model >= 0
* @return the location of the end of the range
* @exception BadLocationException if the range is invalid
+ *
+ * @deprecated replaced by
+ * {@link #drawSelectedText(Graphics2D, float, float, int, int)}
*/
+ @Deprecated(since = "9")
protected int drawSelectedText(Graphics g, int x,
- int y, int p0, int p1) throws BadLocationException {
+ int y, int p0, int p1)
+ throws BadLocationException
+ {
+ return (int) drawSelectedTextImpl(g, x, y, p0, p1, false);
+ }
+
+ float callDrawSelectedText(Graphics g, float x, float y,
+ int p0, int p1)
+ throws BadLocationException
+ {
+ return drawSelectedTextOverridden && g instanceof Graphics2D
+ ? drawSelectedText((Graphics2D) g, x, y, p0, p1)
+ : drawSelectedText(g, (int) x, (int) y, p0, p1);
+ }
+
+ private float drawSelectedTextImpl(Graphics g, float x, float y,
+ int p0, int p1,
+ boolean useFPAPI)
+ throws BadLocationException
+ {
g.setColor(selected);
Document doc = getDocument();
Segment s = SegmentCache.getSharedSegment();
doc.getText(p0, p1 - p0, s);
- int ret = Utilities.drawTabbedText(this, s, x, y, g, this, p0);
+ float ret = Utilities.drawTabbedText(this, s, x, y, g, this, p0, null,
+ useFPAPI);
SegmentCache.releaseSharedSegment(s);
return ret;
}
@@ -242,10 +287,6 @@
* the hosting component. It assumes the highlighter will render
* the selected background.
*
- * @implSpec This implementation calls
- * {@link #drawSelectedText(Graphics, int, int, int, int)
- * drawSelectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
- *
* @param g the graphics context
* @param x the starting X coordinate {@code >= 0}
* @param y the starting Y coordinate {@code >= 0}
@@ -253,11 +294,12 @@
* @param p1 the ending position in the model {@code >= 0}
* @return the location of the end of the range
* @exception BadLocationException if the range is invalid
+ *
+ * @since 9
*/
-
protected float drawSelectedText(Graphics2D g, float x,
float y, int p0, int p1) throws BadLocationException {
- return drawSelectedText((Graphics)g, (int) x, (int) y, p0, p1);
+ return drawSelectedTextImpl(g, x, y, p0, p1, true);
}
/**
@@ -287,7 +329,13 @@
// The font changed, we need to recalculate the
// longest line.
calculateLongestLine();
- tabSize = getTabSize() * metrics.charWidth('m');
+ if (useFloatingPointAPI) {
+ FontRenderContext frc = metrics.getFontRenderContext();
+ float tabWidth = (float) font.getStringBounds("m", frc).getWidth();
+ tabSize = getTabSize() * tabWidth;
+ } else {
+ tabSize = getTabSize() * metrics.charWidth('m');
+ }
}
}
@@ -388,7 +436,11 @@
originalA, host, this);
}
}
- drawLine(line, g, x, y);
+ if (drawLineOverridden && (g instanceof Graphics2D)) {
+ drawLine(line, (Graphics2D) g, (float) x, (float) y);
+ } else {
+ drawLine(line, g, x, y);
+ }
y += fontHeight;
if (line == 0) {
// This should never really happen, in so far as if
@@ -435,6 +487,13 @@
int p0 = line.getStartOffset();
Segment s = SegmentCache.getSharedSegment();
doc.getText(p0, pos - p0, s);
+
+ if (useFloatingPointAPI) {
+ float xOffs = Utilities.getTabbedTextWidth(s, metrics, (float) tabBase, this, p0);
+ SegmentCache.releaseSharedSegment(s);
+ return new Rectangle2D.Float(lineArea.x + xOffs, lineArea.y, 1, metrics.getHeight());
+ }
+
int xOffs = Utilities.getTabbedTextWidth(s, metrics, tabBase, this,p0);
SegmentCache.releaseSharedSegment(s);
@@ -456,14 +515,13 @@
* given point in the view >= 0
* @see View#viewToModel
*/
- public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) {
+ public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
// PENDING(prinz) properly calculate bias
bias[0] = Position.Bias.Forward;
Rectangle alloc = a.getBounds();
Document doc = getDocument();
- int x = (int) fx;
- int y = (int) fy;
+
if (y < alloc.y) {
// above the area covered by this icon, so the position
// is assumed to be the start of the coverage for this view.
@@ -481,7 +539,7 @@
Element map = doc.getDefaultRootElement();
int fontHeight = metrics.getHeight();
int lineIndex = (fontHeight > 0 ?
- Math.abs((y - alloc.y) / fontHeight) :
+ (int)Math.abs((y - alloc.y) / fontHeight) :
map.getElementCount() - 1);
if (lineIndex >= map.getElementCount()) {
return getEndOffset() - 1;
@@ -507,7 +565,7 @@
doc.getText(p0, p1 - p0, s);
tabBase = alloc.x;
int offs = p0 + Utilities.getTabbedTextOffset(s, metrics,
- tabBase, x, this, p0);
+ tabBase, x, this, p0, true);
SegmentCache.releaseSharedSegment(s);
return offs;
} catch (BadLocationException e) {
@@ -586,7 +644,7 @@
if (tabSize == 0) {
return x;
}
- int ntabs = (((int) x) - tabBase) / tabSize;
+ float ntabs = (x - tabBase) / tabSize;
return tabBase + ((ntabs + 1) * tabSize);
}
@@ -758,6 +816,28 @@
return w;
}
+ static boolean isFPMethodOverriden(String method,
+ Class<?> cls,
+ Class<?>[] intTypes,
+ Class<?>[] fpTypes)
+ {
+ Module thisModule = PlainView.class.getModule();
+ while (!thisModule.equals(cls.getModule())) {
+ try {
+ cls.getDeclaredMethod(method, fpTypes);
+ return true;
+ } catch (Exception e1) {
+ try {
+ cls.getDeclaredMethod(method, intTypes);
+ return false;
+ } catch (Exception e2) {
+ cls = cls.getSuperclass();
+ }
+ }
+ }
+ return true;
+ }
+
// --- member variables -----------------------------------------------
/**
@@ -780,7 +860,7 @@
Font font;
Segment lineBuffer;
- int tabSize;
+ float tabSize;
int tabBase;
int sel0;
@@ -796,4 +876,46 @@
*/
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<Boolean>() {
+ @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<Boolean>() {
+ @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<Boolean>() {
+ @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;
+ }
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/Utilities.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/Utilities.java Thu Oct 27 14:52:01 2016 -0400
@@ -24,24 +24,23 @@
*/
package javax.swing.text;
-import java.lang.reflect.Method;
-
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.FontMetrics;
import java.awt.Shape;
-import java.awt.Toolkit;
import java.awt.Graphics2D;
-import java.awt.font.FontRenderContext;
-import java.awt.font.TextLayout;
import java.awt.font.TextAttribute;
+import java.awt.geom.Rectangle2D;
import java.text.*;
import javax.swing.JComponent;
import javax.swing.SwingConstants;
import javax.swing.text.ParagraphView.Row;
import sun.swing.SwingUtilities2;
+import static sun.swing.SwingUtilities2.drawChars;
+import static sun.swing.SwingUtilities2.getFontCharWidth;
+import static sun.swing.SwingUtilities2.getFontCharsWidth;
/**
* A collection of methods to deal with various text
@@ -78,7 +77,11 @@
* tabs will be expanded as a space character.
* @param startOffset starting offset of the text in the document >= 0
* @return the X location at the end of the rendered text
+ *
+ * @deprecated replaced by
+ * {@link #drawTabbedText(Segment, float, float, Graphics2D, TabExpander, int)}
*/
+ @Deprecated(since = "9")
public static final int drawTabbedText(Segment s, int x, int y, Graphics g,
TabExpander e, int startOffset) {
return drawTabbedText(null, s, x, y, g, e, startOffset);
@@ -96,6 +99,8 @@
* tabs will be expanded as a space character.
* @param startOffset starting offset of the text in the document {@code >= 0}
* @return the X location at the end of the rendered text
+ *
+ * @since 9
*/
public static final float drawTabbedText(Segment s, float x, float y,
Graphics2D g,
@@ -138,9 +143,19 @@
Segment s, int x, int y, Graphics g,
TabExpander e, int startOffset,
int [] justificationData) {
+ return (int) drawTabbedText(view, s, x, y, g, e, startOffset,
+ justificationData, false);
+ }
+
+ static final float drawTabbedText(View view,
+ Segment s, float x, float y, Graphics g,
+ TabExpander e, int startOffset,
+ int [] justificationData,
+ boolean useFPAPI)
+ {
JComponent component = getJComponent(view);
FontMetrics metrics = SwingUtilities2.getFontMetrics(component, g);
- int nextX = x;
+ float nextX = x;
char[] txt = s.array;
int txtOffset = s.offset;
int flushLen = 0;
@@ -174,19 +189,19 @@
&& i <= endJustifiableContent
)) {
if (flushLen > 0) {
- nextX = SwingUtilities2.drawChars(component, g, txt,
- flushIndex, flushLen, x, y);
+ nextX = drawChars(component, g, txt, flushIndex, flushLen, x, y);
flushLen = 0;
}
flushIndex = i + 1;
if (txt[i] == '\t') {
if (e != null) {
- nextX = (int) e.nextTabStop((float) nextX, startOffset + i - txtOffset);
+ nextX = e.nextTabStop(nextX, startOffset + i - txtOffset);
} else {
- nextX += metrics.charWidth(' ');
+ nextX += getFontCharWidth(' ', metrics, useFPAPI);
}
} else if (txt[i] == ' ') {
- nextX += metrics.charWidth(' ') + spaceAddon;
+ float spaceWidth = getFontCharWidth(' ', metrics, useFPAPI);
+ nextX += spaceWidth + spaceAddon;
if (i <= spaceAddonLeftoverEnd) {
nextX++;
}
@@ -194,8 +209,8 @@
x = nextX;
} else if ((txt[i] == '\n') || (txt[i] == '\r')) {
if (flushLen > 0) {
- nextX = SwingUtilities2.drawChars(component, g, txt,
- flushIndex, flushLen, x, y);
+ nextX = drawChars(component, g, txt, flushIndex, flushLen,
+ x, y, useFPAPI);
flushLen = 0;
}
flushIndex = i + 1;
@@ -205,8 +220,7 @@
}
}
if (flushLen > 0) {
- nextX = SwingUtilities2.drawChars(component, g,txt, flushIndex,
- flushLen, x, y);
+ nextX = drawChars(component, g,txt, flushIndex, flushLen, x, y, useFPAPI);
}
return nextX;
}
@@ -223,7 +237,11 @@
* tabs will be expanded as a space character.
* @param startOffset starting offset of the text in the document >= 0
* @return the width of the text
+ *
+ * @deprecated replaced by
+ * {@link #getTabbedTextWidth(Segment, FontMetrics, float, TabExpander, int)}
*/
+ @Deprecated(since = "9")
public static final int getTabbedTextWidth(Segment s, FontMetrics metrics, int x,
TabExpander e, int startOffset) {
return getTabbedTextWidth(null, s, metrics, x, e, startOffset, null);
@@ -240,11 +258,13 @@
* tabs will be expanded as a space character.
* @param startOffset starting offset of the text in the document {@code >= 0}
* @return the width of the text
+ *
+ * @since 9
*/
public static final float getTabbedTextWidth(Segment s, FontMetrics metrics,
float x, TabExpander e,
int startOffset) {
- return getTabbedTextWidth(s, metrics, (int) x, e, startOffset);
+ return getTabbedTextWidth(null, s, metrics, x, e, startOffset, null);
}
// In addition to the previous method it can extend spaces for
@@ -254,10 +274,32 @@
// one:
// @param justificationData justificationData for the row.
// if null not justification is needed
- static final int getTabbedTextWidth(View view, Segment s, FontMetrics metrics, int x,
+ static final int getTabbedTextWidth(View view, Segment s,
+ FontMetrics metrics, int x,
+ TabExpander e, int startOffset,
+ int[] justificationData)
+ {
+ return (int) getTabbedTextWidth(view, s, metrics, x, e, startOffset,
+ justificationData, false);
+
+ }
+
+ static final float getTabbedTextWidth(View view, Segment s,
+ FontMetrics metrics, float x,
TabExpander e, int startOffset,
- int[] justificationData) {
- int nextX = x;
+ int[] justificationData)
+ {
+ return getTabbedTextWidth(view, s, metrics, x, e, startOffset,
+ justificationData, true);
+
+ }
+
+ static final float getTabbedTextWidth(View view, Segment s,
+ FontMetrics metrics, float x,
+ TabExpander e, int startOffset,
+ int[] justificationData,
+ boolean useFPAPI) {
+ float nextX = x;
char[] txt = s.array;
int txtOffset = s.offset;
int n = s.offset + s.count;
@@ -294,13 +336,13 @@
charCount = 0;
if (txt[i] == '\t') {
if (e != null) {
- nextX = (int) e.nextTabStop((float) nextX,
- startOffset + i - txtOffset);
+ nextX = e.nextTabStop(nextX, startOffset + i - txtOffset);
} else {
- nextX += metrics.charWidth(' ');
+ nextX += getFontCharWidth(' ', metrics, useFPAPI);
}
} else if (txt[i] == ' ') {
- nextX += metrics.charWidth(' ') + spaceAddon;
+ float spaceWidth = getFontCharWidth(' ', metrics, useFPAPI);
+ nextX += spaceWidth + spaceAddon;
if (i <= spaceAddonLeftoverEnd) {
nextX++;
}
@@ -308,13 +350,15 @@
} else if(txt[i] == '\n') {
// Ignore newlines, they take up space and we shouldn't be
// counting them.
- nextX += metrics.charsWidth(txt, i - charCount, charCount);
+ nextX += getFontCharsWidth(txt, i - charCount, charCount,
+ metrics, useFPAPI);
charCount = 0;
} else {
charCount++;
}
}
- nextX += metrics.charsWidth(txt, n - charCount, charCount);
+ nextX += getFontCharsWidth(txt, n - charCount, charCount,
+ metrics, useFPAPI);
return nextX - x;
}
@@ -334,7 +378,12 @@
* tabs will be expanded as a space character.
* @param startOffset starting offset of the text in the document >= 0
* @return the offset into the text >= 0
+ *
+ * @deprecated replaced by
+ * {@link #getTabbedTextOffset(Segment, FontMetrics, float, float,
+ * TabExpander, int, boolean)}
*/
+ @Deprecated(since = "9")
public static final int getTabbedTextOffset(Segment s, FontMetrics metrics,
int x0, int x, TabExpander e,
int startOffset) {
@@ -346,7 +395,7 @@
int startOffset,
int[] justificationData) {
return getTabbedTextOffset(view, s, metrics, x0, x, e, startOffset, true,
- justificationData);
+ justificationData, false);
}
/**
@@ -365,13 +414,19 @@
* @param startOffset starting offset of the text in the document >= 0
* @param round whether or not to round
* @return the offset into the text >= 0
+ *
+ * @deprecated replaced by
+ * {@link #getTabbedTextOffset(Segment, FontMetrics, float, float,
+ * TabExpander, int, boolean)}
*/
+ @Deprecated(since = "9")
public static final int getTabbedTextOffset(Segment s,
FontMetrics metrics,
int x0, int x, TabExpander e,
int startOffset,
boolean round) {
- return getTabbedTextOffset(null, s, metrics, x0, x, e, startOffset, round, null);
+ return getTabbedTextOffset(null, s, metrics, x0, x, e, startOffset,
+ round, null, false);
}
/**
@@ -390,6 +445,8 @@
* @param startOffset starting offset of the text in the document {@code >= 0}
* @param round whether or not to round
* @return the offset into the text {@code >= 0}
+ *
+ * @since 9
*/
public static final int getTabbedTextOffset(Segment s,
FontMetrics metrics,
@@ -398,8 +455,8 @@
int startOffset,
boolean round)
{
- return getTabbedTextOffset(null, s, metrics, (int) x0, (int) x, e,
- startOffset, round, null);
+ return getTabbedTextOffset(null, s, metrics, x0, x, e,
+ startOffset, round, null, true);
}
// In addition to the previous method it can extend spaces for
@@ -412,15 +469,16 @@
static final int getTabbedTextOffset(View view,
Segment s,
FontMetrics metrics,
- int x0, int x, TabExpander e,
+ float x0, float x, TabExpander e,
int startOffset,
boolean round,
- int[] justificationData) {
+ int[] justificationData,
+ boolean useFPAPI) {
if (x0 >= x) {
// x before x0, return.
return 0;
}
- int nextX = x0;
+ float nextX = x0;
// s may be a shared segment, so it is copied prior to calling
// the tab expander
char[] txt = s.array;
@@ -456,19 +514,19 @@
)){
if (txt[i] == '\t') {
if (e != null) {
- nextX = (int) e.nextTabStop((float) nextX,
- startOffset + i - txtOffset);
+ nextX = e.nextTabStop(nextX, startOffset + i - txtOffset);
} else {
- nextX += metrics.charWidth(' ');
+ nextX += getFontCharWidth(' ', metrics, useFPAPI);
}
} else if (txt[i] == ' ') {
- nextX += metrics.charWidth(' ') + spaceAddon;
+ nextX += getFontCharWidth(' ', metrics, useFPAPI);
+ nextX += spaceAddon;
if (i <= spaceAddonLeftoverEnd) {
nextX++;
}
}
} else {
- nextX += metrics.charWidth(txt[i]);
+ nextX += getFontCharWidth(txt[i], metrics, useFPAPI);
}
if (x < nextX) {
// found the hit position... return the appropriate side
@@ -480,12 +538,15 @@
if (round) {
offset = i + 1 - txtOffset;
- int width = metrics.charsWidth(txt, txtOffset, offset);
- int span = x - x0;
+ float width = getFontCharsWidth(txt, txtOffset, offset,
+ metrics, useFPAPI);
+ float span = x - x0;
if (span < width) {
while (offset > 0) {
- int nextWidth = offset > 1 ? metrics.charsWidth(txt, txtOffset, offset - 1) : 0;
+ float charsWidth = getFontCharsWidth(txt, txtOffset,
+ offset - 1, metrics, useFPAPI);
+ float nextWidth = offset > 1 ? charsWidth : 0;
if (span >= nextWidth) {
if (span - nextWidth < width - span) {
@@ -502,7 +563,9 @@
} else {
offset = i - txtOffset;
- while (offset > 0 && metrics.charsWidth(txt, txtOffset, offset) > (x - x0)) {
+ while (offset > 0 && getFontCharsWidth(txt, txtOffset, offset,
+ metrics, useFPAPI)
+ > (x - x0)) {
offset--;
}
}
@@ -528,15 +591,26 @@
* tabs will be expanded as a space character.
* @param startOffset starting offset in the document of the text
* @return the offset into the given text
+ *
+ * @deprecated replaced by
+ * {@link #getBreakLocation(Segment, FontMetrics, float, float,
+ * TabExpander, int)}
*/
+ @Deprecated(since = "9")
public static final int getBreakLocation(Segment s, FontMetrics metrics,
int x0, int x, TabExpander e,
int startOffset) {
+ return getBreakLocation(s, metrics, x0, x, e, startOffset, false);
+ }
+
+ static final int getBreakLocation(Segment s, FontMetrics metrics,
+ float x0, float x, TabExpander e,
+ int startOffset, boolean useFPIAPI) {
char[] txt = s.array;
int txtOffset = s.offset;
int txtCount = s.count;
- int index = Utilities.getTabbedTextOffset(s, metrics, x0, x,
- e, startOffset, false);
+ int index = getTabbedTextOffset(null, s, metrics, x0, x, e, startOffset,
+ false, null, useFPIAPI);
if (index >= txtCount - 1) {
return txtCount;
@@ -577,11 +651,13 @@
* tabs will be expanded as a space character.
* @param startOffset starting offset in the document of the text
* @return the offset into the given text
+ *
+ * @since 9
*/
public static final int getBreakLocation(Segment s, FontMetrics metrics,
float x0, float x, TabExpander e,
int startOffset) {
- return getBreakLocation(s, metrics, (int) x0, (int) x, e, startOffset);
+ return getBreakLocation(s, metrics, x0, x, e, startOffset, false);
}
/**
@@ -627,16 +703,16 @@
* @exception BadLocationException if the offset is out of range
*/
public static final int getRowEnd(JTextComponent c, int offs) throws BadLocationException {
- Rectangle r = c.modelToView(offs);
+ Rectangle2D r = c.modelToView2D(offs);
if (r == null) {
return -1;
}
int n = c.getDocument().getLength();
int lastOffs = offs;
- int y = r.y;
- while ((r != null) && (y == r.y)) {
+ double y = r.getY();
+ while ((r != null) && (y == r.getY())) {
// Skip invisible elements
- if (r.height !=0) {
+ if (r.getHeight() !=0) {
offs = lastOffs;
}
lastOffs += 1;
@@ -657,27 +733,44 @@
* @return the position >= 0 if the request can be computed, otherwise
* a value of -1 will be returned.
* @exception BadLocationException if the offset is out of range
+ *
+ * @deprecated replaced by
+ * {@link #getPositionAbove(JTextComponent, int, float)}
*/
- public static final int getPositionAbove(JTextComponent c, int offs, int x) throws BadLocationException {
+ @Deprecated(since = "9")
+ public static final int getPositionAbove(JTextComponent c, int offs, int x)
+ throws BadLocationException
+ {
+ return getPositionAbove(c, offs, x, false);
+ }
+
+ static final int getPositionAbove(JTextComponent c, int offs, float x,
+ boolean useFPAPI) throws BadLocationException
+ {
int lastOffs = getRowStart(c, offs) - 1;
if (lastOffs < 0) {
return -1;
}
- int bestSpan = Integer.MAX_VALUE;
- int y = 0;
- Rectangle r = null;
+ double bestSpan = Integer.MAX_VALUE;
+ double y = 0;
+ Rectangle2D r = null;
if (lastOffs >= 0) {
- r = c.modelToView(lastOffs);
- y = r.y;
+ r = useFPAPI ? c.modelToView2D(lastOffs) : c.modelToView(lastOffs);
+ y = r.getY();
}
- while ((r != null) && (y == r.y)) {
- int span = Math.abs(r.x - x);
+ while ((r != null) && (y == r.getY())) {
+ double span = Math.abs(r.getX() - x);
if (span < bestSpan) {
offs = lastOffs;
bestSpan = span;
}
lastOffs -= 1;
- r = (lastOffs >= 0) ? c.modelToView(lastOffs) : null;
+
+ if ((lastOffs >= 0)) {
+ r = useFPAPI ? c.modelToView2D(lastOffs) : c.modelToView(lastOffs);
+ } else {
+ r = null;
+ }
}
return offs;
}
@@ -694,10 +787,12 @@
* @return the position {@code >= 0} if the request can be computed, otherwise
* a value of -1 will be returned.
* @exception BadLocationException if the offset is out of range
+ *
+ * @since 9
*/
public static final int getPositionAbove(JTextComponent c, int offs, float x)
throws BadLocationException {
- return getPositionAbove(c, offs, (int) x);
+ return getPositionAbove(c, offs, x, true);
}
/**
@@ -712,28 +807,45 @@
* @return the position >= 0 if the request can be computed, otherwise
* a value of -1 will be returned.
* @exception BadLocationException if the offset is out of range
+ *
+ * @deprecated replaced by
+ * {@link #getPositionBelow(JTextComponent, int, float)}
*/
- public static final int getPositionBelow(JTextComponent c, int offs, int x) throws BadLocationException {
+ @Deprecated(since = "9")
+ public static final int getPositionBelow(JTextComponent c, int offs, int x)
+ throws BadLocationException
+ {
+ return getPositionBelow(c, offs, x, false);
+ }
+
+ static final int getPositionBelow(JTextComponent c, int offs, float x,
+ boolean useFPAPI) throws BadLocationException
+ {
int lastOffs = getRowEnd(c, offs) + 1;
if (lastOffs <= 0) {
return -1;
}
- int bestSpan = Integer.MAX_VALUE;
+ double bestSpan = Integer.MAX_VALUE;
int n = c.getDocument().getLength();
- int y = 0;
- Rectangle r = null;
+ double y = 0;
+ Rectangle2D r = null;
if (lastOffs <= n) {
- r = c.modelToView(lastOffs);
- y = r.y;
+ r = useFPAPI ? c.modelToView2D(lastOffs) : c.modelToView(lastOffs);
+ y = r.getY();
}
- while ((r != null) && (y == r.y)) {
- int span = Math.abs(x - r.x);
+ while ((r != null) && (y == r.getY())) {
+ double span = Math.abs(x - r.getX());
if (span < bestSpan) {
offs = lastOffs;
bestSpan = span;
}
lastOffs += 1;
- r = (lastOffs <= n) ? c.modelToView(lastOffs) : null;
+
+ if (lastOffs <= n) {
+ r = useFPAPI ? c.modelToView2D(lastOffs) : c.modelToView(lastOffs);
+ } else {
+ r = null;
+ }
}
return offs;
}
@@ -750,10 +862,12 @@
* @return the position {@code >= 0} if the request can be computed, otherwise
* a value of -1 will be returned.
* @exception BadLocationException if the offset is out of range
+ *
+ * @since 9
*/
public static final int getPositionBelow(JTextComponent c, int offs, float x)
throws BadLocationException {
- return getPositionBelow(c, offs, (int) x);
+ return getPositionBelow(c, offs, x, true);
}
/**
@@ -1029,7 +1143,23 @@
*/
static int drawComposedText(View view, AttributeSet attr, Graphics g,
int x, int y, int p0, int p1)
- throws BadLocationException {
+ throws BadLocationException
+ {
+ return (int) drawComposedText(view, attr, g, x, y, p0, p1, false);
+ }
+
+ static float drawComposedText(View view, AttributeSet attr, Graphics g,
+ float x, float y, int p0, int p1)
+ throws BadLocationException
+ {
+ return drawComposedText(view, attr, g, x, y, p0, p1, true);
+ }
+
+ static float drawComposedText(View view, AttributeSet attr, Graphics g,
+ float x, float y, int p0, int p1,
+ boolean useFPAPI)
+ throws BadLocationException
+ {
Graphics2D g2d = (Graphics2D)g;
AttributedString as = (AttributedString)attr.getAttribute(
StyleConstants.ComposedTextAttribute);
@@ -1039,8 +1169,7 @@
return x;
AttributedCharacterIterator aci = as.getIterator(null, p0, p1);
- return x + (int)SwingUtilities2.drawString(
- getJComponent(view), g2d,aci,x,y);
+ return x + SwingUtilities2.drawString(getJComponent(view), g2d, aci, x, y);
}
/**
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java Thu Oct 27 14:52:01 2016 -0400
@@ -25,8 +25,12 @@
package javax.swing.text;
import java.awt.*;
+import java.awt.font.FontRenderContext;
import java.lang.ref.SoftReference;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import javax.swing.event.*;
+import static javax.swing.text.PlainView.isFPMethodOverriden;
/**
* View of plain text (text with only one font and color)
@@ -87,17 +91,6 @@
}
/**
- * Returns the tab size set for the document, defaulting to 8.
- *
- * @implSpec This implementation calls {@link #getTabSize() getTabSize()}.
- *
- * @return the tab size
- */
- protected float getFractionalTabSize() {
- return getTabSize();
- }
-
- /**
* Renders a line of text, suppressing whitespace at the end
* and expanding any tabs. This is implemented to make calls
* to the methods <code>drawUnselectedText</code> and
@@ -111,8 +104,17 @@
* @param y the starting Y position >= 0
* @see #drawUnselectedText
* @see #drawSelectedText
+ *
+ * @deprecated replaced by
+ * {@link #drawLine(int, int, Graphics2D, float, float)}
*/
+ @Deprecated(since = "9")
protected void drawLine(int p0, int p1, Graphics g, int x, int y) {
+ drawLineImpl(p0, p1, g, x, y, false);
+ }
+
+ private void drawLineImpl(int p0, int p1, Graphics g, float x, float y,
+ boolean useFPAPI) {
Element lineMap = getElement();
Element line = lineMap.getElement(lineMap.getElementIndex(p0));
Element elem;
@@ -143,10 +145,6 @@
* <code>drawSelectedText</code> so that the way selected and
* unselected text are rendered can be customized.
*
- * @implSpec This implementation calls
- * {@link #drawLine(int, int, Graphics, int, int)
- * drawLine(p0, p1, (Graphics) g, (int) x, (int) y)}.
- *
* @param p0 the starting document location to use >= 0
* @param p1 the ending document location to use >= p1
* @param g the graphics context
@@ -154,12 +152,17 @@
* @param y the starting Y position >= 0
* @see #drawUnselectedText
* @see #drawSelectedText
+ *
+ * @since 9
*/
protected void drawLine(int p0, int p1, Graphics2D g, float x, float y) {
- drawLine(p0, p1, (Graphics) g, (int) x, (int) y);
+ drawLineImpl(p0, p1, g, x, y, true);
}
- private int drawText(Element elem, int p0, int p1, Graphics g, int x, int y) throws BadLocationException {
+ private float drawText(Element elem, int p0, int p1, Graphics g,
+ float x, float y)
+ throws BadLocationException
+ {
p1 = Math.min(getDocument().getLength(), p1);
AttributeSet attr = elem.getAttributes();
@@ -171,23 +174,23 @@
} else {
if (sel0 == sel1 || selected == unselected) {
// no selection, or it is invisible
- x = drawUnselectedText(g, x, y, p0, p1);
+ x = callDrawUnselectedText(g, x, y, p0, p1);
} else if ((p0 >= sel0 && p0 <= sel1) && (p1 >= sel0 && p1 <= sel1)) {
- x = drawSelectedText(g, x, y, p0, p1);
+ x = callDrawSelectedText(g, x, y, p0, p1);
} else if (sel0 >= p0 && sel0 <= p1) {
if (sel1 >= p0 && sel1 <= p1) {
- x = drawUnselectedText(g, x, y, p0, sel0);
- x = drawSelectedText(g, x, y, sel0, sel1);
- x = drawUnselectedText(g, x, y, sel1, p1);
+ x = callDrawUnselectedText(g, x, y, p0, sel0);
+ x = callDrawSelectedText(g, x, y, sel0, sel1);
+ x = callDrawUnselectedText(g, x, y, sel1, p1);
} else {
- x = drawUnselectedText(g, x, y, p0, sel0);
- x = drawSelectedText(g, x, y, sel0, p1);
+ x = callDrawUnselectedText(g, x, y, p0, sel0);
+ x = callDrawSelectedText(g, x, y, sel0, p1);
}
} else if (sel1 >= p0 && sel1 <= p1) {
- x = drawSelectedText(g, x, y, p0, sel1);
- x = drawUnselectedText(g, x, y, sel1, p1);
+ x = callDrawSelectedText(g, x, y, p0, sel1);
+ x = callDrawUnselectedText(g, x, y, sel1, p1);
} else {
- x = drawUnselectedText(g, x, y, p0, p1);
+ x = callDrawUnselectedText(g, x, y, p0, p1);
}
}
@@ -205,14 +208,36 @@
* @param p1 the ending position in the model >= p0
* @return the X location of the end of the range >= 0
* @exception BadLocationException if the range is invalid
+ *
+ * @deprecated replaced by
+ * {@link #drawUnselectedText(Graphics2D, float, float, int, int)}
*/
+ @Deprecated(since = "9")
protected int drawUnselectedText(Graphics g, int x, int y,
- int p0, int p1) throws BadLocationException {
+ int p0, int p1) throws BadLocationException
+ {
+ return (int) drawUnselectedTextImpl(g, x, y, p0, p1, false);
+ }
+
+ private float callDrawUnselectedText(Graphics g, float x, float y,
+ int p0, int p1)
+ throws BadLocationException
+ {
+ return drawUnselectedTextOverridden && g instanceof Graphics2D
+ ? drawUnselectedText((Graphics2D) g, x, y, p0, p1)
+ : drawUnselectedText(g, (int) x, (int) y, p0, p1);
+ }
+
+ private float drawUnselectedTextImpl(Graphics g, float x, float y,
+ int p0, int p1, boolean useFPAPI)
+ throws BadLocationException
+ {
g.setColor(unselected);
Document doc = getDocument();
Segment segment = SegmentCache.getSharedSegment();
doc.getText(p0, p1 - p0, segment);
- int ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0);
+ float ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0,
+ null, useFPAPI);
SegmentCache.releaseSharedSegment(segment);
return ret;
}
@@ -221,10 +246,6 @@
* Renders the given range in the model as normal unselected
* text.
*
- * @implSpec This implementation calls
- * {@link #drawUnselectedText(Graphics, int, int, int, int)
- * drawUnselectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
- *
* @param g the graphics context
* @param x the starting X coordinate >= 0
* @param y the starting Y coordinate >= 0
@@ -232,10 +253,12 @@
* @param p1 the ending position in the model >= p0
* @return the X location of the end of the range >= 0
* @exception BadLocationException if the range is invalid
+ *
+ * @since 9
*/
protected float drawUnselectedText(Graphics2D g, float x, float y,
int p0, int p1) throws BadLocationException {
- return drawUnselectedText((Graphics) g, (int) x, (int) y, p0, p1);
+ return drawUnselectedTextImpl(g, x, y, p0, p1, true);
}
/**
* Renders the given range in the model as selected text. This
@@ -250,14 +273,37 @@
* @param p1 the ending position in the model >= p0
* @return the location of the end of the range.
* @exception BadLocationException if the range is invalid
+ *
+ * @deprecated replaced by
+ * {@link #drawSelectedText(Graphics2D, float, float, int, int)}
*/
- protected int drawSelectedText(Graphics g, int x,
- int y, int p0, int p1) throws BadLocationException {
+ @Deprecated(since = "9")
+ protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1)
+ throws BadLocationException
+ {
+ return (int) drawSelectedTextImpl(g, x, y, p0, p1, false);
+ }
+
+ private float callDrawSelectedText(Graphics g, float x, float y,
+ int p0, int p1)
+ throws BadLocationException
+ {
+ return drawSelectedTextOverridden && g instanceof Graphics2D
+ ? drawSelectedText((Graphics2D) g, x, y, p0, p1)
+ : drawSelectedText(g, (int) x, (int) y, p0, p1);
+ }
+
+ private float drawSelectedTextImpl(Graphics g, float x, float y,
+ int p0, int p1,
+ boolean useFPAPI)
+ throws BadLocationException
+ {
g.setColor(selected);
Document doc = getDocument();
Segment segment = SegmentCache.getSharedSegment();
doc.getText(p0, p1 - p0, segment);
- int ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0);
+ float ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0,
+ null, useFPAPI);
SegmentCache.releaseSharedSegment(segment);
return ret;
}
@@ -268,10 +314,6 @@
* the hosting component. It assumes the highlighter will render
* the selected background.
*
- * @implSpec This implementation calls
- * {@link #drawSelectedText(Graphics, int, int, int, int)
- * drawSelectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
- *
* @param g the graphics context
* @param x the starting X coordinate >= 0
* @param y the starting Y coordinate >= 0
@@ -279,10 +321,12 @@
* @param p1 the ending position in the model >= p0
* @return the location of the end of the range.
* @exception BadLocationException if the range is invalid
+ *
+ * @since 9
*/
protected float drawSelectedText(Graphics2D g, float x, float y,
int p0, int p1) throws BadLocationException {
- return drawSelectedText((Graphics) g, (int) x, (int) y, p0, p1);
+ return drawSelectedTextImpl(g, x, y, p0, p1, true);
}
/**
* Gives access to a buffer that can be used to fetch
@@ -395,7 +439,13 @@
Component host = getContainer();
Font f = host.getFont();
metrics = host.getFontMetrics(f);
- tabSize = getTabSize() * metrics.charWidth('m');
+ if (useFloatingPointAPI) {
+ FontRenderContext frc = metrics.getFontRenderContext();
+ float tabWidth = (float) f.getStringBounds("m", frc).getWidth();
+ tabSize = getTabSize() * tabWidth;
+ } else {
+ tabSize = getTabSize() * metrics.charWidth('m');
+ }
}
// --- TabExpander methods ------------------------------------------
@@ -413,7 +463,7 @@
public float nextTabStop(float x, int tabOffset) {
if (tabSize == 0)
return x;
- int ntabs = ((int) x - tabBase) / tabSize;
+ float ntabs = (x - tabBase) / tabSize;
return tabBase + ((ntabs + 1) * tabSize);
}
@@ -591,7 +641,7 @@
Segment lineBuffer;
boolean widthChanging;
int tabBase;
- int tabSize;
+ float tabSize;
boolean wordWrap;
int sel0;
@@ -668,6 +718,7 @@
int end = getEndOffset();
int p0 = start;
int[] lineEnds = getLineEnds();
+ boolean useDrawLineFP = drawLineOverridden && g instanceof Graphics2D;
for (int i = 0; i < lineCount; i++) {
int p1 = (lineEnds == null) ? end :
start + lineEnds[i];
@@ -677,8 +728,11 @@
: p1;
dh.paintLayeredHighlights(g, p0, hOffset, a, host, this);
}
- drawLine(p0, p1, g, x, y);
-
+ if (useDrawLineFP) {
+ drawLine(p0, p1, (Graphics2D) g, (float) x, (float) y);
+ } else {
+ drawLine(p0, p1, g, x, y);
+ }
p0 = p1;
y += metrics.getHeight();
}
@@ -929,4 +983,47 @@
int lineCount;
SoftReference<int[]> 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<Boolean>() {
+ @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<Boolean>() {
+ @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<Boolean>() {
+ @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;
+ }
}
--- a/jdk/src/java.desktop/share/classes/module-info.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/module-info.java Thu Oct 27 14:52:01 2016 -0400
@@ -88,6 +88,9 @@
exports sun.awt to
jdk.accessibility;
+ exports com.sun.awt to
+ jdk.desktop;
+
uses java.awt.im.spi.InputMethodDescriptor;
uses javax.accessibility.AccessibilityProvider;
uses javax.imageio.spi.ImageInputStreamSpi;
--- a/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java Thu Oct 27 14:52:01 2016 -0400
@@ -107,7 +107,7 @@
/*
* Requests focus to the component.
*/
- boolean requestFocus(Component comp, Cause cause);
+ void requestFocus(Component comp, Cause cause);
/*
* Determines if the component can gain focus.
*/
@@ -1392,4 +1392,4 @@
AWTAccessor.dropTargetContextAccessor = accessor;
}
-}
\ No newline at end of file
+}
--- a/jdk/src/java.desktop/share/classes/sun/awt/IconInfo.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/sun/awt/IconInfo.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. 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
@@ -103,7 +103,7 @@
}
this.scaledWidth = width;
this.scaledHeight = height;
- this.rawLength = getScaledRawLength();
+ this.rawLength = getScaledRawLength(width, height);
}
/*
@@ -112,14 +112,14 @@
public void setScaledSize(int width, int height) {
this.scaledWidth = width;
this.scaledHeight = height;
- this.rawLength = getScaledRawLength();
+ this.rawLength = getScaledRawLength(width, height);
}
/*
* returns scaled raw length.
*/
- private int getScaledRawLength() {
- int scaledWidthAndHeight[] = getScaledWidthAndHeight(width, height);
+ private int getScaledRawLength(int w, int h) {
+ int scaledWidthAndHeight[] = getScaledWidthAndHeight(w, h);
return scaledWidthAndHeight[0] * scaledWidthAndHeight[1] + 2;
}
--- a/jdk/src/java.desktop/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java Thu Oct 27 14:52:01 2016 -0400
@@ -142,8 +142,8 @@
}
// WARNING: Don't call it on the Toolkit thread.
- public static boolean requestFocusFor(Component target, FocusEvent.Cause cause) {
- return AWTAccessor.getComponentAccessor().requestFocus(target, cause);
+ public static void requestFocusFor(Component target, FocusEvent.Cause cause) {
+ AWTAccessor.getComponentAccessor().requestFocus(target, cause);
}
// WARNING: Don't call it on the Toolkit thread.
--- a/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java Thu Oct 27 14:52:01 2016 -0400
@@ -1512,9 +1512,9 @@
*/
protected abstract boolean syncNativeQueue(final long timeout);
- private boolean eventDispatched = false;
- private boolean queueEmpty = false;
- private final Object waitLock = "Wait Lock";
+ private boolean eventDispatched;
+ private boolean queueEmpty;
+ private final Object waitLock = new Object();
private boolean isEQEmpty() {
EventQueue queue = getSystemEventQueueImpl();
@@ -1531,10 +1531,11 @@
@SuppressWarnings("serial")
protected final boolean waitForIdle(final long timeout) {
flushPendingEvents();
- boolean queueWasEmpty = isEQEmpty();
- queueEmpty = false;
- eventDispatched = false;
- synchronized(waitLock) {
+ final boolean queueWasEmpty;
+ synchronized (waitLock) {
+ queueWasEmpty = isEQEmpty();
+ queueEmpty = false;
+ eventDispatched = false;
postEvent(AppContext.getAppContext(),
new PeerEvent(getSystemEventQueueImpl(), null, PeerEvent.LOW_PRIORITY_EVENT) {
@Override
--- a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Thu Oct 27 14:52:01 2016 -0400
@@ -1902,11 +1902,7 @@
clipRegion = devClip;
} else if (usrClip instanceof Rectangle2D) {
clipState = CLIP_RECTANGULAR;
- if (usrClip instanceof Rectangle) {
- clipRegion = devClip.getIntersection((Rectangle)usrClip);
- } else {
- clipRegion = devClip.getIntersection(usrClip.getBounds());
- }
+ clipRegion = devClip.getIntersection((Rectangle2D) usrClip);
} else {
PathIterator cpi = usrClip.getPathIterator(null);
int box[] = new int[4];
--- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/Region.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/Region.java Thu Oct 27 14:52:01 2016 -0400
@@ -28,10 +28,13 @@
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
import java.awt.geom.RectangularShape;
import sun.java2d.loops.TransformHelper;
+import static java.lang.Double.isNaN;
+
/**
* This class encapsulates a definition of a two dimensional region which
* consists of a number of Y ranges each containing multiple X bands.
@@ -118,6 +121,34 @@
}
/**
+ * Returns the closest {@code int} to the argument, with ties rounding to
+ * negative infinity.
+ * <p>
+ * Special cases:
+ * <ul><li>If the argument is NaN, the result is 0.
+ * <li>If the argument is negative infinity or any value less than or
+ * equal to the value of {@code Integer.MIN_VALUE}, the result is
+ * equal to the value of {@code Integer.MIN_VALUE}.
+ * <li>If the argument is positive infinity or any value greater than or
+ * equal to the value of {@code Integer.MAX_VALUE}, the result is
+ * equal to the value of {@code Integer.MAX_VALUE}.</ul>
+ *
+ * @param coordinate a floating-point value to be rounded to an integer
+ * @return the value of the argument rounded to the nearest
+ * {@code int} value.
+ */
+ public static int clipRound(final double coordinate) {
+ final double newv = coordinate - 0.5;
+ if (newv < Integer.MIN_VALUE) {
+ return Integer.MIN_VALUE;
+ }
+ if (newv > Integer.MAX_VALUE) {
+ return Integer.MAX_VALUE;
+ }
+ return (int) Math.ceil(newv);
+ }
+
+ /**
* Multiply the scale factor {@code sv} and the value {@code v} with
* appropriate clipping to the bounds of Integer resolution. If the answer
* would be greater than {@code Integer.MAX_VALUE} then {@code
@@ -559,6 +590,33 @@
/**
* Returns a Region object that represents the intersection of
+ * this object with the specified Rectangle2D. The return value
+ * may be this same object if no clipping occurs.
+ */
+ public Region getIntersection(final Rectangle2D r) {
+ if (r instanceof Rectangle) {
+ return getIntersection((Rectangle) r);
+ }
+ return getIntersectionXYXY(r.getMinX(), r.getMinY(), r.getMaxX(),
+ r.getMaxY());
+ }
+
+ /**
+ * Returns a Region object that represents the intersection of
+ * this object with the specified rectangular area. The return
+ * value may be this same object if no clipping occurs.
+ */
+ public Region getIntersectionXYXY(double lox, double loy, double hix,
+ double hiy) {
+ if (isNaN(lox) || isNaN(loy) || isNaN(hix) || isNaN(hiy)) {
+ return EMPTY_REGION;
+ }
+ return getIntersectionXYXY(clipRound(lox), clipRound(loy),
+ clipRound(hix), clipRound(hiy));
+ }
+
+ /**
+ * Returns a Region object that represents the intersection of
* this object with the specified rectangular area. The return
* value may be this same object if no clipping occurs.
*/
--- a/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java Thu Oct 27 14:52:01 2016 -0400
@@ -30,6 +30,7 @@
import static java.awt.RenderingHints.*;
import java.awt.event.*;
import java.awt.font.*;
+import java.awt.geom.Rectangle2D;
import java.awt.geom.AffineTransform;
import static java.awt.geom.AffineTransform.TYPE_FLIP;
import static java.awt.geom.AffineTransform.TYPE_TRANSLATION;
@@ -723,10 +724,31 @@
int length,
int x,
int y) {
+ return (int) drawChars(c, g, data, offset, length, x, y, false);
+ }
+
+ public static float drawChars(JComponent c, Graphics g,
+ char[] data,
+ int offset,
+ int length,
+ float x,
+ float y) {
+ return drawChars(c, g, data, offset, length, x, y, true);
+ }
+
+ public static float drawChars(JComponent c, Graphics g,
+ char[] data,
+ int offset,
+ int length,
+ float x,
+ float y,
+ boolean useFPAPI) {
if ( length <= 0 ) { //no need to paint empty strings
return x;
}
- int nextX = x + getFontMetrics(c, g).charsWidth(data, offset, length);
+ float nextX = x + getFontCharsWidth(data, offset, length,
+ getFontMetrics(c, g),
+ useFPAPI);
if (isPrinting(g)) {
Graphics2D g2d = getGraphics2D(g);
if (g2d != null) {
@@ -766,8 +788,14 @@
Object aaHint = (c == null)
? null
: c.getClientProperty(KEY_TEXT_ANTIALIASING);
- if (aaHint != null && (g instanceof Graphics2D)) {
- Graphics2D g2 = (Graphics2D)g;
+
+ if (!(g instanceof Graphics2D)) {
+ g.drawChars(data, offset, length, (int) x, (int) y);
+ return nextX;
+ }
+
+ Graphics2D g2 = (Graphics2D) g;
+ if (aaHint != null) {
Object oldContrast = null;
Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);
@@ -788,7 +816,7 @@
}
}
- g.drawChars(data, offset, length, x, y);
+ g2.drawString(new String(data, offset, length), x, y);
if (oldAAValue != null) {
g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);
@@ -798,19 +826,59 @@
}
}
else {
- g.drawChars(data, offset, length, x, y);
+ g2.drawString(new String(data, offset, length), x, y);
}
return nextX;
}
+ public static float getFontCharWidth(char c, FontMetrics fm,
+ boolean useFPAPI)
+ {
+ return getFontCharsWidth(new char[]{c}, 0, 1, fm, useFPAPI);
+ }
+
+ public static float getFontCharsWidth(char[] data, int offset, int len,
+ FontMetrics fm,
+ boolean useFPAPI)
+ {
+ return len == 0 ? 0 : getFontStringWidth(new String(data, offset, len),
+ fm, useFPAPI);
+ }
+
+ public static float getFontStringWidth(String data, FontMetrics fm,
+ boolean useFPAPI)
+ {
+ if (useFPAPI) {
+ Rectangle2D bounds = fm.getFont()
+ .getStringBounds(data, fm.getFontRenderContext());
+ return (float) bounds.getWidth();
+ } else {
+ return fm.stringWidth(data);
+ }
+ }
+
/*
* see documentation for drawChars
* returns the advance
*/
public static float drawString(JComponent c, Graphics g,
AttributedCharacterIterator iterator,
- int x,
- int y) {
+ int x, int y)
+ {
+ return drawStringImpl(c, g, iterator, x, y);
+ }
+
+ public static float drawString(JComponent c, Graphics g,
+ AttributedCharacterIterator iterator,
+ float x, float y)
+ {
+ return drawStringImpl(c, g, iterator, x, y);
+ }
+
+ private static float drawStringImpl(JComponent c, Graphics g,
+ AttributedCharacterIterator iterator,
+ float x, float y)
+ {
float retVal;
boolean isPrinting = isPrinting(g);
@@ -825,8 +893,8 @@
Graphics2D g2d = getGraphics2D(g);
if (g2d == null) {
- g.drawString(iterator,x,y); //for the cases where advance
- //matters it should not happen
+ g.drawString(iterator, (int)x, (int)y); //for the cases where advance
+ //matters it should not happen
retVal = x;
} else {
--- a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c Thu Oct 27 14:52:01 2016 -0400
@@ -25,7 +25,12 @@
#include "splashscreen_impl.h"
#include "splashscreen_gfx_impl.h"
-
+#define BUFF_SIZE 1024
+#ifdef _MSC_VER
+# ifndef snprintf
+# define snprintf _snprintf
+# endif
+#endif
int splashIsVisible = 0;
Splash *
@@ -392,5 +397,101 @@
SPLASHEXPORT int
SplashGetScaledImgNameMaxPstfixLen(const char *fileName){
- return strlen(fileName) + strlen(".java-scale-200") + 1;
+ return strlen(fileName) + strlen("@100pct") + 1;
}
+
+jboolean GetScaledImageName(const char *fileName, char *scaleImageName,
+ float *scaleFactor, const size_t scaledImageLength) {
+ if (*scaleFactor > 1.0) {
+ FILE *fp = NULL;
+ char scaledImgPct[BUFF_SIZE];
+ char scaledImgX[BUFF_SIZE];
+ char *scaledImageXName = NULL;
+ char *scaledImagePctName = malloc(scaledImageLength);
+ char *dupFileName = strdup(fileName);
+ char *fileExtension = strrchr(dupFileName, '.');
+ size_t lengthPct = 0;
+ size_t lengthX = 0;
+ int retValPct = 0;
+ int retValX = 0;
+ jboolean isPctScaledImage = (*scaleFactor * 100) != ((int) (*scaleFactor)) *100;
+ snprintf(scaledImgPct, BUFF_SIZE, "%s%d%s", "@",
+ (int) (*scaleFactor * 100), "pct");
+ if (!isPctScaledImage) {
+ scaledImageXName = malloc(scaledImageLength);
+ snprintf(scaledImgX, BUFF_SIZE, "%s%d%s", "@", (int) (*scaleFactor), "x");
+ }
+ /*File is missing extension */
+ if (fileExtension == NULL) {
+ lengthPct = strlen(dupFileName) +
+ strlen(scaledImgPct) + 1;
+ if (!isPctScaledImage) {
+ lengthX = strlen(dupFileName) +
+ strlen(scaledImgX) + 1;
+ }
+ if (lengthPct > scaledImageLength || lengthX > scaledImageLength) {
+ cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
+ return JNI_FALSE;
+ }
+ retValPct = snprintf(scaledImagePctName, lengthPct, "%s%s", dupFileName,
+ scaledImgPct);
+ if (!isPctScaledImage) {
+ retValX = snprintf(scaledImageXName, lengthX, "%s%s", dupFileName,
+ scaledImgX);
+ }
+ if ((retValPct < 0 || (retValPct > lengthPct - 1)) ||
+ (retValX < 0 || (retValX > lengthX - 1))) {
+ cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
+ return JNI_FALSE;
+ }
+ } else {
+ int length_Without_Ext = fileExtension - dupFileName;
+ lengthPct = length_Without_Ext + strlen(scaledImgPct) +
+ strlen(fileExtension) + 1;
+ if (!isPctScaledImage) {
+ lengthX = length_Without_Ext + strlen(scaledImgX) +
+ strlen(fileExtension) + 1;
+ }
+ if (lengthPct > scaledImageLength || lengthX > scaledImageLength) {
+ cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
+ return JNI_FALSE;
+ }
+ retValPct = snprintf(scaledImagePctName, lengthPct, "%.*s%s%s",
+ length_Without_Ext, dupFileName, scaledImgPct, fileExtension);
+ if (!isPctScaledImage) {
+ retValX = snprintf(scaledImageXName, lengthX, "%.*s%s%s",
+ length_Without_Ext, dupFileName, scaledImgX, fileExtension);
+ }
+ if ((retValPct < 0 || (retValPct > lengthPct - 1)) ||
+ (retValX < 0 || (retValX > lengthX - 1))) {
+ cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
+ return JNI_FALSE;
+ }
+ }
+ free(dupFileName);
+ if (!(fp = fopen(scaledImagePctName, "r"))) {
+ if (!isPctScaledImage && (fp = fopen(scaledImageXName, "r"))) {
+ fclose(fp);
+ strcpy(scaleImageName, scaledImageXName);
+ free(scaledImageXName);
+ free(scaledImagePctName);
+ return JNI_TRUE;
+ }
+ cleanUp(NULL, scaledImageXName, scaledImagePctName, scaleFactor);
+ return JNI_FALSE;
+ }
+ fclose(fp);
+ strcpy(scaleImageName, scaledImagePctName);
+ free(scaledImageXName);
+ free(scaledImagePctName);
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
+
+void cleanUp(char *fName, char *xName, char *pctName, float *scaleFactor) {
+ *scaleFactor = 1;
+ free(fName);
+ free(xName);
+ free(pctName);
+}
--- a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h Thu Oct 27 14:52:01 2016 -0400
@@ -150,7 +150,9 @@
void SplashCleanup(Splash * splash);
void SplashSetScaleFactor(float scaleFactor);
int SplashGetScaledImgNameMaxPstfixLen(const char *fileName);
-
+void cleanUp(char *fName, char *xName, char *pctName, float *scaleFactor);
+jboolean GetScaledImageName(const char *fileName, char *scaledImgName,
+ float *scaleFactor, const size_t scaledImageLength);
typedef struct SplashStream {
int (*read)(void* pStream, void* pData, int nBytes);
int (*peek)(void* pStream);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java Thu Oct 27 14:52:01 2016 -0400
@@ -301,7 +301,10 @@
}
private void resetWMSetInsets() {
- wm_set_insets = null;
+ if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
+ currentInsets = new Insets(0, 0, 0, 0);
+ wm_set_insets = null;
+ }
}
public void handlePropertyNotify(XEvent xev) {
@@ -352,7 +355,7 @@
// and the initially guessed insets were wrong
handleCorrectInsets(in);
}
- } else if (!dimensions.isClientSizeSet()) {
+ } else if (!insets_corrected || !dimensions.isClientSizeSet()) {
insets_corrected = true;
// initial insets were guessed correctly. Re-request
// frame bounds because they may be changed by WM if the
@@ -908,7 +911,6 @@
public void setResizable(boolean resizable) {
int fs = winAttr.functions;
if (!isResizable() && resizable) {
- currentInsets = new Insets(0, 0, 0, 0);
resetWMSetInsets();
if (!isEmbedded()) {
setReparented(false);
@@ -922,7 +924,6 @@
winAttr.functions = fs;
XWM.setShellResizable(this);
} else if (isResizable() && !resizable) {
- currentInsets = new Insets(0, 0, 0, 0);
resetWMSetInsets();
if (!isEmbedded()) {
setReparented(false);
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/Xrandr.h Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/Xrandr.h Thu Oct 27 14:52:01 2016 -0400
@@ -118,6 +118,19 @@
RRMode *modes;
} XRROutputInfo;
+typedef struct {
+ Time timestamp;
+ int x, y;
+ unsigned int width, height;
+ RRMode mode;
+ Rotation rotation;
+ int noutput;
+ RROutput *outputs;
+ Rotation rotations;
+ int npossible;
+ RROutput *possible;
+} XRRCrtcInfo;
+
XRRScreenResources *XRRGetScreenResources (Display *dpy, Window window);
void XRRFreeScreenResources (XRRScreenResources *resources);
@@ -126,6 +139,11 @@
RROutput output);
void XRRFreeOutputInfo (XRROutputInfo *outputInfo);
+XRRCrtcInfo *XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources,
+ RRCrtc crtc);
+void XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo);
+
+
/* internal representation is private to the library */
typedef struct _XRRScreenConfiguration XRRScreenConfiguration;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Thu Oct 27 14:52:01 2016 -0400
@@ -1667,6 +1667,11 @@
typedef void (*XRRFreeOutputInfoType)(XRROutputInfo *outputInfo);
+typedef XRRCrtcInfo* (*XRRGetCrtcInfoType)(Display *dpy,
+ XRRScreenResources *resources, RRCrtc crtc);
+
+typedef void (*XRRFreeCrtcInfoType)(XRRCrtcInfo *crtcInfo);
+
static XRRQueryVersionType awt_XRRQueryVersion;
static XRRGetScreenInfoType awt_XRRGetScreenInfo;
static XRRFreeScreenConfigInfoType awt_XRRFreeScreenConfigInfo;
@@ -1680,6 +1685,8 @@
static XRRFreeScreenResourcesType awt_XRRFreeScreenResources;
static XRRGetOutputInfoType awt_XRRGetOutputInfo;
static XRRFreeOutputInfoType awt_XRRFreeOutputInfo;
+static XRRGetCrtcInfoType awt_XRRGetCrtcInfo;
+static XRRFreeCrtcInfoType awt_XRRFreeCrtcInfo;
#define LOAD_XRANDR_FUNC(f) \
do { \
@@ -1755,6 +1762,8 @@
LOAD_XRANDR_FUNC(XRRFreeScreenResources);
LOAD_XRANDR_FUNC(XRRGetOutputInfo);
LOAD_XRANDR_FUNC(XRRFreeOutputInfo);
+ LOAD_XRANDR_FUNC(XRRGetCrtcInfo);
+ LOAD_XRANDR_FUNC(XRRFreeCrtcInfo);
return JNI_TRUE;
}
@@ -1895,7 +1904,49 @@
AWT_LOCK();
- if (screen < ScreenCount(awt_display)) {
+ if (usingXinerama && XScreenCount(awt_display) > 0) {
+ XRRScreenResources *res = awt_XRRGetScreenResources(awt_display,
+ RootWindow(awt_display, 0));
+ if (res) {
+ if (res->noutput > screen) {
+ XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display,
+ res, res->outputs[screen]);
+ if (output_info) {
+ if (output_info->crtc) {
+ XRRCrtcInfo *crtc_info =
+ awt_XRRGetCrtcInfo (awt_display, res,
+ output_info->crtc);
+ if (crtc_info) {
+ if (crtc_info->mode) {
+ int i;
+ for (i = 0; i < res->nmode; i++) {
+ XRRModeInfo *mode = &res->modes[i];
+ if (mode->id == crtc_info->mode) {
+ float rate = 0;
+ if (mode->hTotal && mode->vTotal) {
+ rate = ((float)mode->dotClock /
+ ((float)mode->hTotal *
+ (float)mode->vTotal));
+ }
+ displayMode = X11GD_CreateDisplayMode(
+ env,
+ mode->width,
+ mode->height,
+ BIT_DEPTH_MULTI,
+ (int)(rate +.2));
+ break;
+ }
+ }
+ }
+ awt_XRRFreeCrtcInfo(crtc_info);
+ }
+ }
+ awt_XRRFreeOutputInfo(output_info);
+ }
+ }
+ awt_XRRFreeScreenResources(res);
+ }
+ } else {
config = awt_XRRGetScreenInfo(awt_display,
RootWindow(awt_display, screen));
@@ -1954,7 +2005,7 @@
res, res->outputs[screen]);
if (output_info) {
int i;
- for (i = 0; i < res->nmode; i++) {
+ for (i = 0; i < output_info->nmode; i++) {
RRMode m = output_info->modes[i];
int j;
XRRModeInfo *mode;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c Thu Oct 27 14:52:01 2016 -0400
@@ -35,9 +35,6 @@
#include <jni_util.h>
#include "awt.h"
-#define GTHREAD_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gthread-2.0", "0")
-#define GTHREAD_LIB JNI_LIB_NAME("gthread-2.0")
-
#define GTK_TYPE_BORDER ((*fp_gtk_border_get_type)())
#define G_TYPE_FUNDAMENTAL_SHIFT (2)
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h Thu Oct 27 14:52:01 2016 -0400
@@ -351,9 +351,6 @@
guint ellipsize : 3;
};
-
-typedef struct _GThreadFunctions GThreadFunctions;
-
/**
* Returns :
* NULL if the GLib library is compatible with the given version, or a string
@@ -449,17 +446,6 @@
static void (*fp_g_list_free) (GList *list);
static void (*fp_g_list_free_full) (GList *list, GDestroyNotify free_func);
-/**
- * This function is available for GLIB > 2.20, so it MUST be
- * called within GLIB_CHECK_VERSION(2, 20, 0) check.
- */
-static gboolean (*fp_g_thread_get_initialized)(void);
-
-static void (*fp_g_thread_init)(GThreadFunctions *vtable);
-static void (*fp_gdk_threads_init)(void);
-static void (*fp_gdk_threads_enter)(void);
-static void (*fp_gdk_threads_leave)(void);
-
static gboolean (*fp_gtk_show_uri)(GdkScreen *screen, const gchar *uri,
guint32 timestamp, GError **error);
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c Thu Oct 27 14:52:01 2016 -0400
@@ -35,6 +35,7 @@
#include "awt.h"
static void *gtk3_libhandle = NULL;
+static void *gthread_libhandle = NULL;
static jmp_buf j;
@@ -87,6 +88,15 @@
return result;
}
+static void* dl_symbol_gthread(const char* name)
+{
+ void* result = dlsym(gthread_libhandle, name);
+ if (!result)
+ longjmp(j, NO_SYMBOL_EXCEPTION);
+
+ return result;
+}
+
gboolean gtk3_check(const char* lib_name, gboolean load)
{
if (gtk3_libhandle != NULL) {
@@ -261,6 +271,13 @@
return FALSE;
}
+ gthread_libhandle = dlopen(GTHREAD_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
+ if (gthread_libhandle == NULL) {
+ gthread_libhandle = dlopen(GTHREAD_LIB, RTLD_LAZY | RTLD_LOCAL);
+ if (gthread_libhandle == NULL)
+ return FALSE;
+ }
+
if (setjmp(j) == 0)
{
fp_gtk_check_version = dl_symbol("gtk_check_version");
@@ -530,8 +547,8 @@
fp_g_path_get_dirname = dl_symbol("g_path_get_dirname");
- fp_gdk_threads_enter = ∅
- fp_gdk_threads_leave = ∅
+ fp_gdk_threads_enter = dl_symbol("gdk_threads_enter");
+ fp_gdk_threads_leave = dl_symbol("gdk_threads_leave");
/**
* Functions for sun_awt_X11_GtkFileDialogPeer.c
@@ -556,6 +573,9 @@
dlclose(gtk3_libhandle);
gtk3_libhandle = NULL;
+ dlclose(gthread_libhandle);
+ gthread_libhandle = NULL;
+
return NULL;
}
@@ -651,6 +671,7 @@
dlerror();
dlclose(gtk3_libhandle);
+ dlclose(gthread_libhandle);
if ((gtk3_error = dlerror()) != NULL)
{
return FALSE;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h Thu Oct 27 14:52:01 2016 -0400
@@ -33,6 +33,9 @@
#define TRUE (!FALSE)
#endif
+#define GTHREAD_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gthread-2.0", "0")
+#define GTHREAD_LIB JNI_LIB_NAME("gthread-2.0")
+
#define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip)
#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) \
(_G_TYPE_CIC ((instance), (g_type), c_type))
@@ -555,6 +558,13 @@
gboolean gtk_load(JNIEnv *env, GtkVersion version, gboolean verbose);
gboolean gtk_check_version(GtkVersion version);
+typedef struct _GThreadFunctions GThreadFunctions;
+static gboolean (*fp_g_thread_get_initialized)(void);
+static void (*fp_g_thread_init)(GThreadFunctions *vtable);
+static void (*fp_gdk_threads_init)(void);
+static void (*fp_gdk_threads_enter)(void);
+static void (*fp_gdk_threads_leave)(void);
+
extern GtkApi* gtk;
#endif /* !_GTK_INTERFACE_H */
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XWindow.c Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XWindow.c Thu Oct 27 14:52:01 2016 -0400
@@ -818,6 +818,32 @@
}
return awt_UseXKB;
}
+
+/*
+ * Map a keycode to the corresponding keysym.
+ * This replaces the deprecated X11 function XKeycodeToKeysym
+ */
+KeySym
+keycodeToKeysym(Display *display, KeyCode keycode, int index) {
+ static int min_kc = -1;
+ static int max_kc;
+ if (min_kc == -1) {
+ (void) XDisplayKeycodes(display, &min_kc, &max_kc);
+ }
+ if (keycode < min_kc || keycode > max_kc || index < 0) {
+ return NoSymbol;
+ }
+ int num_syms;
+ KeySym *key_syms = XGetKeyboardMapping(display, keycode, 1, &num_syms);
+ if (index >= num_syms) {
+ XFree(key_syms);
+ return NoSymbol;
+ }
+ KeySym ks = key_syms[index];
+ XFree(key_syms);
+ return ks;
+}
+
static Boolean
isKPevent(XEvent *event)
{
@@ -833,14 +859,14 @@
*/
Boolean bsun = isXsunServer( event );
Boolean bxkb = isXKBenabled( event->xkey.display );
- return IsKeypadKey( XKeycodeToKeysym(event->xkey.display, event->xkey.keycode,(bsun && !bxkb ? 2 : 1) ) );
+ return IsKeypadKey( keycodeToKeysym(event->xkey.display, event->xkey.keycode,(bsun && !bxkb ? 2 : 1) ) );
}
static void
dumpKeysymArray(XEvent *event) {
- printf(" 0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 0));
- printf(" 0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 1));
- printf(" 0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 2));
- printf(" 0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 3));
+ printf(" 0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 0));
+ printf(" 0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 1));
+ printf(" 0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 2));
+ printf(" 0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 3));
}
/*
* In a next redesign, get rid of this code altogether.
@@ -855,20 +881,20 @@
}
if( isXsunServer( event ) && !awt_UseXKB) {
if( (event->xkey.state & ShiftMask) ) { // shift modifier is on
- *keysym = XKeycodeToKeysym(event->xkey.display,
+ *keysym = keycodeToKeysym(event->xkey.display,
event->xkey.keycode, 3);
}else {
- *keysym = XKeycodeToKeysym(event->xkey.display,
+ *keysym = keycodeToKeysym(event->xkey.display,
event->xkey.keycode, 2);
}
} else {
if( (event->xkey.state & ShiftMask) || // shift modifier is on
((event->xkey.state & LockMask) && // lock modifier is on
(awt_ModLockIsShiftLock)) ) { // it is interpreted as ShiftLock
- *keysym = XKeycodeToKeysym(event->xkey.display,
+ *keysym = keycodeToKeysym(event->xkey.display,
event->xkey.keycode, 0);
}else{
- *keysym = XKeycodeToKeysym(event->xkey.display,
+ *keysym = keycodeToKeysym(event->xkey.display,
event->xkey.keycode, 1);
}
}
@@ -903,7 +929,7 @@
Perhaps using the index (modn in awt_MToolkit.c:setup_modifier_map)
would be more correct.
*/
- *keysym = XKeycodeToKeysym(event->xkey.display,
+ *keysym = keycodeToKeysym(event->xkey.display,
event->xkey.keycode, 2);
if (originalKeysym != *keysym) {
DTRACE_PRINTLN3("%s originalKeysym=0x%x, keysym=0x%x",
@@ -999,7 +1025,6 @@
}
}
-
/* This function is called as the keyChar parameter of a call to
* awt_post_java_key_event. It depends on being called after adjustKeySym.
*
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c Thu Oct 27 14:52:01 2016 -0400
@@ -49,6 +49,9 @@
#include <X11/XKBlib.h>
+// From XWindow.c
+extern KeySym keycodeToKeysym(Display *display, KeyCode keycode, int index);
+
#if defined(DEBUG)
static jmethodID lockIsHeldMID = NULL;
@@ -1286,7 +1289,7 @@
// report arbitrarily false.
return JNI_FALSE;
} else {
- long ks2 = XKeycodeToKeysym((Display*)jlong_to_ptr(display), kc7, 2);
+ long ks2 = keycodeToKeysym((Display*)jlong_to_ptr(display), kc7, 2);
if( ks2 == XK_KP_7 ) {
//XXX If some Xorg server would put XK_KP_7 in keysymarray[2] as well,
//XXX for yet unknown to me reason, the sniffer would lie.
@@ -1915,12 +1918,13 @@
XQueryKeymap( (Display *) jlong_to_ptr(display), (char *) jlong_to_ptr(vector));
}
+// XKeycodeToKeysym is deprecated but for compatibility we keep the API.
JNIEXPORT jlong JNICALL
Java_sun_awt_X11_XlibWrapper_XKeycodeToKeysym(JNIEnv *env, jclass clazz,
jlong display, jint keycode,
jint index) {
AWT_CHECK_HAVE_LOCK_RETURN(0);
- return XKeycodeToKeysym((Display*) jlong_to_ptr(display), (unsigned int)keycode, (int)index);
+ return keycodeToKeysym((Display*)jlong_to_ptr(display), (unsigned int)keycode, (int)index);
}
JNIEXPORT jint JNICALL
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c Thu Oct 27 14:52:01 2016 -0400
@@ -97,10 +97,7 @@
void callback(DbusmenuMenuitem* mi, guint ts, jobject data) {
JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2);
- (*env)->CallStaticVoidMethod(env, jTaskbarCls, jTaskbarCallback, data,
- fp_dbusmenu_menuitem_property_get_int(mi, "toggle-state")
- ? JNI_FALSE
- : JNI_TRUE);
+ (*env)->CallStaticVoidMethod(env, jTaskbarCls, jTaskbarCallback, data);
}
/*
@@ -243,10 +240,9 @@
if (!menu) {
menu = fp_dbusmenu_menuitem_new();
+ fp_unity_launcher_entry_set_quicklist(entry, menu);
}
- fp_unity_launcher_entry_set_quicklist(entry, menu);
-
GList* list = fp_dbusmenu_menuitem_take_children(menu);
gtk->g_list_free_full(list, gtk->g_object_unref);
--- a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c Thu Oct 27 14:52:01 2016 -0400
@@ -753,6 +753,9 @@
XMapRaised(splash->display, splash->window);
SplashUpdateShape(splash);
SplashRedrawWindow(splash);
+ //map the splash co-ordinates as per system scale
+ splash->x /= splash->scaleFactor;
+ splash->y /= splash->scaleFactor;
SplashEventLoop(splash);
}
SplashUnlock(splash);
@@ -807,50 +810,6 @@
return JNI_FALSE;
#endif
*scaleFactor = getNativeScaleFactor(NULL);
- if (*scaleFactor == 2.0) {
- size_t length = 0;
- char *stringToAppend = ".java-scale2x";
- char *dupFileName = strdup(fileName);
- char *fileExtension = strrchr(dupFileName, '.');
- if (fileExtension == NULL) {
- length = strlen(dupFileName) + strlen(stringToAppend) + 1;
- if (length > scaledImageNameLength) {
- *scaleFactor = 1;
- free(dupFileName);
- return JNI_FALSE;
- }
- int retVal = snprintf(scaledImgName, length, "%s%s",
- dupFileName, stringToAppend);
- if (retVal < 0 || (retVal != length - 1)) {
- free(dupFileName);
- *scaleFactor = 1;
- return JNI_FALSE;
- }
- } else {
- int length_without_ext = fileExtension - dupFileName;
- length = length_without_ext +
- strlen(stringToAppend) + strlen(fileExtension) + 1;
- if (length > scaledImageNameLength) {
- *scaleFactor = 1;
- free(dupFileName);
- return JNI_FALSE;
- }
- int retVal = snprintf(scaledImgName, length, "%.*s%s%s",
- length_without_ext, dupFileName, stringToAppend, fileExtension);
- if (retVal < 0 || retVal != length - 1) {
- free(dupFileName);
- *scaleFactor = 1;
- return JNI_FALSE;
- }
- }
- free(dupFileName);
- FILE *fp;
- if (!(fp = fopen(scaledImgName, "r"))) {
- *scaleFactor = 1;
- return JNI_FALSE;
- }
- fclose(fp);
- return JNI_TRUE;
- }
- return JNI_FALSE;
+ return GetScaledImageName(fileName, scaledImgName, scaleFactor, scaledImageNameLength);
}
+
--- a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c Thu Oct 27 14:52:01 2016 -0400
@@ -535,6 +535,9 @@
splash->hWnd = SplashCreateWindow(splash);
if (splash->hWnd) {
SplashRedrawWindow(splash);
+ //map the splash co-ordinates as per system scale
+ splash->x /= splash->scaleFactor;
+ splash->y /= splash->scaleFactor;
SplashUnlock(splash);
SplashMessagePump();
SplashLock(splash);
@@ -582,55 +585,7 @@
*scaleFactor = 1.0;
GetScreenDpi(getPrimaryMonitor(), &dpiScaleX, &dpiScaleY);
*scaleFactor = dpiScaleX > 0 ? dpiScaleX / 96 : *scaleFactor;
- if (*scaleFactor > 1.0) {
- char strDpi[BUFF_SIZE];
- char *dupFileName = strdup(fileName);
- char *fileExtension = strrchr(dupFileName, '.');
- char *nameToAppend = ".scale-";
- size_t length = 0;
- int retVal = 0;
- _snprintf(strDpi, BUFF_SIZE, "%d", (int)dpiScaleX);
- /*File is missing extension */
- if (fileExtension == NULL) {
- length = strlen(dupFileName) + strlen(nameToAppend) +
- strlen(strDpi) + 1;
- if (length > scaledImageLength) {
- *scaleFactor = 1;
- free(dupFileName);
- return JNI_FALSE;
- }
- retVal = _snprintf(scaleImageName, length, "%s%s%s", dupFileName,
- nameToAppend, strDpi);
- if (retVal < 0 || (retVal != length - 1)) {
- *scaleFactor = 1;
- free(dupFileName);
- return JNI_FALSE;
- }
- }
- else {
- size_t length_Without_Ext = fileExtension - dupFileName;
- length = length_Without_Ext + strlen(nameToAppend) + strlen(strDpi) +
- strlen(fileExtension) + 1;
- if (length > scaledImageLength) {
- *scaleFactor = 1;
- free(dupFileName);
- return JNI_FALSE;
- }
- retVal = _snprintf(scaleImageName, length, "%.*s%s%s%s",
- length_Without_Ext, dupFileName, nameToAppend, strDpi, fileExtension);
- if (retVal < 0 || (retVal != length - 1)) {
- *scaleFactor = 1;
- free(dupFileName);
- return JNI_FALSE;
- }
- }
- free(dupFileName);
- if (!(fp = fopen(scaleImageName, "r"))) {
- *scaleFactor = 1;
- return JNI_FALSE;
- }
- fclose(fp);
- return JNI_TRUE;
- }
- return JNI_FALSE;
+ return GetScaledImageName(fileName, scaleImageName,
+ scaleFactor, scaledImageLength);
}
+
--- a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java Thu Oct 27 14:52:01 2016 -0400
@@ -41,13 +41,13 @@
import javax.accessibility.*;
import com.sun.java.accessibility.util.*;
+import java.awt.geom.Rectangle2D;
import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
/*
* Note: This class has to be public. It's loaded from the VM like this:
@@ -1754,7 +1754,7 @@
if (child instanceof JTextComponent) {
JTextComponent text = (JTextComponent) child;
try {
- r = text.modelToView(text.getCaretPosition());
+ r = text.modelToView2D(text.getCaretPosition()).getBounds();
if (r != null) {
Point p = text.getLocationOnScreen();
r.translate(p.x, p.y);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.desktop/share/classes/jdk/awt/AWTUtils.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.awt;
+
+import java.awt.Component;
+import java.awt.Shape;
+
+import com.sun.awt.AWTUtilities;
+
+/**
+ * A class to allow access to JDK-specific utility methods.
+ * Methods in this class are always deprecated since a caller
+ * should be aware they may be removed and replaced in the future.
+ * Access using reflection is highly recommended.
+ * @since 9
+ */
+public final class AWTUtils {
+
+ /**
+ * No-one should be creating instances of this class.
+ */
+ private AWTUtils() {
+ }
+
+ /**
+ * Sets a 'mixing-cutout' shape for the given component.
+ *
+ * By default a lightweight component is treated as an opaque rectangle for
+ * the purposes of the Heavyweight/Lightweight Components Mixing feature.
+ * This method enables developers to set an arbitrary shape to be cut out
+ * from heavyweight components positioned underneath the lightweight
+ * component in the z-order.
+ * <p>
+ * The {@code shape} argument may have the following values:
+ * <ul>
+ * <li>{@code null} - reverts the default cutout shape (the rectangle equal
+ * to the component's {@code getBounds()})
+ * <li><i>empty-shape</i> - does not cut out anything from heavyweight
+ * components. This makes the given lightweight component effectively
+ * transparent. Note that descendants of the lightweight component still
+ * affect the shapes of heavyweight components. An example of an
+ * <i>empty-shape</i> is {@code new Rectangle()}.
+ * <li><i>non-empty-shape</i> - the given shape will be cut out from
+ * heavyweight components.
+ * </ul>
+ * <p>
+ * The most common example when the 'mixing-cutout' shape is needed is a
+ * glass pane component. The {@link JRootPane#setGlassPane()} method
+ * automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape
+ * for the given glass pane component. If a developer needs some other
+ * 'mixing-cutout' shape for the glass pane (which is rare), this must be
+ * changed manually after installing the glass pane to the root pane.
+ * <p>
+ * Note that the 'mixing-cutout' shape neither affects painting, nor the
+ * mouse events handling for the given component. It is used exclusively
+ * for the purposes of the Heavyweight/Lightweight Components Mixing
+ * feature.
+ *
+ * @param component the component that needs non-default
+ * 'mixing-cutout' shape
+ * @param shape the new 'mixing-cutout' shape
+ * @throws NullPointerException if the component argument is {@code null}
+ * @deprecated This API may be removed or replaced.
+ */
+ @Deprecated
+ @SuppressWarnings("deprecation")
+ public static void setComponentMixingCutoutShape(Component component,
+ Shape shape) {
+
+ AWTUtilities.setComponentMixingCutoutShape(component, shape);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.desktop/share/classes/module-info.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Provides non-SE desktop APIs.
+ */
+
+module jdk.desktop {
+ requires public java.desktop;
+
+ exports jdk.awt;
+}
--- a/jdk/src/jdk.jsobject/share/classes/netscape/javascript/JSObject.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/src/jdk.jsobject/share/classes/netscape/javascript/JSObject.java Thu Oct 27 14:52:01 2016 -0400
@@ -156,6 +156,7 @@
*/
@Deprecated(since = "9")
+ @SuppressWarnings("exports")
public static JSObject getWindow(Applet applet) throws JSException {
return ProviderLoader.callGetWindow(applet);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/RequestFocusByCause/RequestFocusByCauseTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ @test
+ @bug 8154434
+ @summary Open the request focus methods of the java.awt.Component which accept
+ FocusEvent.Cause
+ @run main RequestFocusByCauseTest
+*/
+
+import java.awt.*;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
+public class RequestFocusByCauseTest {
+ static boolean success;
+
+ public static void main(String[] args) throws Exception {
+ testRequestFocusCause();
+ testRequestFocusTemporaryCause();
+ testRequestFocusInWindowCause();
+ System.out.println("ok");
+ }
+
+ private static void testRequestFocusCause() throws AWTException {
+ Frame frame = new Frame();
+ Component c = new Button();
+ frame.add(new Button());
+ frame.add(c);
+ c.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ success = e.getCause() == FocusEvent.Cause.UNEXPECTED;
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {}
+ });
+ Robot robot = new Robot();
+
+ try {
+ frame.setVisible(true);
+ robot.waitForIdle();
+ robot.delay(200);
+ success = false;
+
+ c.requestFocus(FocusEvent.Cause.UNEXPECTED);
+ robot.waitForIdle();
+ robot.delay(200);
+ if(!success) {
+ throw new RuntimeException("request failed");
+ }
+ } finally {
+ frame.dispose();
+ }
+ }
+
+ private static void testRequestFocusTemporaryCause() throws AWTException {
+ Frame frame = new Frame();
+ frame.add(new Button() {
+ @Override
+ protected boolean requestFocus(boolean temporary,
+ FocusEvent.Cause cause) {
+ success = cause == FocusEvent.Cause.ROLLBACK;
+ return super.requestFocus(temporary, cause);
+ }
+ });
+ Component c = new Button() {
+ @Override
+ public void requestFocus() {
+ super.requestFocus();
+ setFocusable(false);
+ }
+ };
+ frame.add(c);
+ Robot robot = new Robot();
+
+ try {
+ frame.setVisible(true);
+ robot.waitForIdle();
+ robot.delay(200);
+
+ success = false;
+ c.requestFocus();
+ robot.waitForIdle();
+ robot.delay(200);
+
+
+ if(!success) {
+ throw new RuntimeException("rollback request is not triggered");
+ }
+ } finally {
+ frame.dispose();
+ }
+ }
+
+ private static void testRequestFocusInWindowCause() throws AWTException {
+ Frame frame = new Frame();
+ Component c = new Button();
+ frame.add(new Button());
+ frame.add(c);
+ c.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ success = e.getCause() == FocusEvent.Cause.UNEXPECTED;
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ }
+ });
+ Robot robot = new Robot();
+
+ try {
+ frame.setVisible(true);
+ robot.waitForIdle();
+ robot.delay(200);
+ success = false;
+
+ c.requestFocusInWindow(FocusEvent.Cause.UNEXPECTED);
+ robot.waitForIdle();
+ robot.delay(200);
+ if (!success) {
+ throw new RuntimeException("request in window failed");
+ }
+ } finally {
+ frame.dispose();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/SetIconImagesCrashTest/SetIconImagesCrashTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key headful
+ * @bug 8166980
+ * @summary Test to check Window.setIconImages() does not result in crash when
+ * a frame is shown
+ * @run main/othervm SetIconImagesCrashTest
+ * @run main/othervm -Dsun.java2d.uiScale=2 SetIconImagesCrashTest
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Window;
+import java.awt.Frame;
+import java.util.List;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import javax.swing.SwingUtilities;
+
+public class SetIconImagesCrashTest {
+
+ public static void main(String[] args) throws Exception {
+
+ List<BufferedImage> imageList = new ArrayList<BufferedImage>();
+ imageList.add(new BufferedImage(200, 200,
+ BufferedImage.TYPE_BYTE_BINARY));
+
+ for (int i = 0; i < 10; i++) {
+ Frame f = new Frame();
+ test(f, imageList);
+ }
+ }
+
+ public static void test(final Window window,
+ final List<BufferedImage> imageList) throws Exception {
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ for (BufferedImage image : imageList) {
+ Graphics graphics = image.getGraphics();
+ graphics.setColor(Color.RED);
+ graphics.fillRect(
+ 0, 0, image.getWidth(), image.getHeight());
+ graphics.dispose();
+ }
+
+ window.setIconImages(imageList);
+ window.setSize(200, 200);
+ window.setVisible(true);
+ }
+ });
+
+ while (!window.isVisible()) {
+ Thread.sleep((long) (20));
+ }
+
+ Thread.sleep((long) (50));
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ window.setVisible(false);
+ window.dispose();
+ }
+ });
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/FullScreen/CurrentDisplayModeTest/CurrentDisplayModeTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8022810
+ * @summary Device.getDisplayMode() doesn't report refresh rate on Linux in case
+ * of dual screen
+ * @run main CurrentDisplayModeTest
+ */
+
+import java.awt.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class CurrentDisplayModeTest {
+ public static void main(String[] args) {
+ GraphicsDevice[] screenDevices = GraphicsEnvironment.
+ getLocalGraphicsEnvironment().getScreenDevices();
+ for (GraphicsDevice screenDevice : screenDevices) {
+ DisplayMode currentMode = screenDevice.getDisplayMode();
+ System.out.println("current mode " + currentMode);
+ Set<DisplayMode> set = new HashSet<>(
+ Arrays.asList(screenDevice.getDisplayModes()));
+ if (!set.contains(currentMode)) {
+ throw new RuntimeException("Mode " + currentMode +
+ " is not found in the modes list " + set);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics/IncorrectFractionalClip/IncorrectFractionalClip.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.Area;
+import java.awt.image.BufferedImage;
+import java.io.File;
+
+import javax.imageio.ImageIO;
+
+import static java.awt.RenderingHints.KEY_STROKE_CONTROL;
+import static java.awt.RenderingHints.VALUE_STROKE_PURE;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8167310
+ * @summary The clip should be correct if the scale is fractional
+ */
+public final class IncorrectFractionalClip {
+
+ private static final int SIZE = 128;
+
+ public static final Color RED = new Color(255, 0, 0, 100);
+
+ public static final Color GREEN = new Color(0, 255, 0, 100);
+
+ public static final Color WHITE = new Color(0, 0, 0, 0);
+
+ public static final BasicStroke STROKE = new BasicStroke(2.01f);
+
+ private static final double[] SCALES = {
+ 0.1, 0.25, 0.4, 0.5, 0.6, 1, 1.4, 1.5, 1.6, 2.0, 2.4, 2.5, 2.6, 4
+ };
+
+ static BufferedImage bi;
+
+ static BufferedImage gold;
+
+ static BufferedImage redI;
+
+ static BufferedImage greenI;
+
+ public static void main(final String[] args) throws Exception {
+ bi = new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB);
+ gold = new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB);
+ redI = createImage(RED);
+ greenI = createImage(GREEN);
+
+ System.out.println("Will test fillRect");
+ test(0, true);
+ test(0, false);
+ System.out.println("Will test DrawImage");
+ test(1, true);
+ test(1, false);
+ System.out.println("Will test drawLine");
+ test(2, true);
+ test(2, false);
+ }
+
+ /**
+ * This method draws/fills a number of rectangle, images and lines. Each
+ * time the clip is set as one vertical/horizontal line. The resulted image
+ * should not have any overlapping of different colors. The clip is set via
+ * rectangle(test) and via shape(gold). Both images should be identical.
+ */
+ private static void test(final int testId, final boolean horiz)
+ throws Exception {
+ for (final double scale : SCALES) {
+ // Initialize the test and gold images
+ drawToImage(testId, horiz, scale, bi, /* Rectangle */ false);
+ drawToImage(testId, horiz, scale, gold, /* Shape */ true);
+ validate(bi, gold, testId);
+ }
+ }
+
+ private static void drawToImage(int testId, boolean horiz, double scale,
+ BufferedImage image, boolean shape) {
+ Graphics2D g = image.createGraphics();
+ g.setComposite(AlphaComposite.Src);
+ g.setColor(WHITE);
+ g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
+ g.setComposite(AlphaComposite.SrcOver);
+ g.setRenderingHint(KEY_STROKE_CONTROL, VALUE_STROKE_PURE);
+
+ // set the scale in one direction
+ if (horiz) {
+ g.scale(scale, 1);
+ } else {
+ g.scale(1, scale);
+ }
+ // cover all units in the user space to touch all pixels in the
+ // image after transform
+ final int destSize = (int) Math.ceil(SIZE / scale);
+ final int destW;
+ final int destH;
+ if (horiz) {
+ destW = destSize;
+ destH = SIZE;
+ } else {
+ destW = SIZE;
+ destH = destSize;
+ }
+ for (int step = 0; step < destSize; ++step) {
+ if (horiz) {
+ if (!shape) {
+ g.setClip(step, 0, 1, SIZE);
+ } else{
+ g.setClip(new Area(new Rectangle(step, 0, 1, SIZE)));
+ }
+ } else {
+ if (!shape) {
+ g.setClip(0, step, SIZE, 1);
+ }else{
+ g.setClip(new Area(new Rectangle(0, step, SIZE, 1)));
+ }
+ }
+ switch (testId) {
+ case 0:
+ g.setColor(step % 2 == 0 ? RED : GREEN);
+ g.fillRect(0, 0, destW, destH);
+ break;
+ case 1:
+ g.drawImage(step % 2 == 0 ? redI : greenI, 0, 0,
+ destW, destH, null);
+ break;
+ case 2:
+ g.setColor(step % 2 == 0 ? RED : GREEN);
+ g.setStroke(STROKE);
+ if (horiz) {
+ g.drawLine(step, 0, step, SIZE);
+ } else {
+ g.drawLine(0, step, SIZE, step);
+ }
+ break;
+ default:
+ throw new RuntimeException();
+ }
+ }
+ g.dispose();
+ }
+
+ private static void validate(final BufferedImage bi, BufferedImage gold,
+ final int testID) throws Exception {
+ for (int x = 0; x < SIZE; ++x) {
+ for (int y = 0; y < SIZE; ++y) {
+ int rgb = bi.getRGB(x, y);
+ int goldRGB = gold.getRGB(x, y);
+ if ((rgb != GREEN.getRGB() && rgb != RED.getRGB())
+ || rgb != goldRGB) {
+ ImageIO.write(bi, "png", new File("image.png"));
+ ImageIO.write(gold, "png", new File("gold.png"));
+ throw new RuntimeException("Test failed.");
+ }
+ }
+ }
+ }
+
+ private static BufferedImage createImage(final Color color) {
+ BufferedImage bi = new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB);
+ Graphics2D g = bi.createGraphics();
+ g.setComposite(AlphaComposite.Src);
+ g.setColor(color);
+ g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
+ g.dispose();
+ return bi;
+ }
+}
--- a/jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. 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
@@ -23,7 +23,7 @@
/*
test
- @bug 6380743
+ @bug 6380743 8158380
@summary Submenu should be shown by mnemonic key press.
@author anton.tarasov@...: area=awt.focus
@run applet SubMenuShowTest.html
@@ -55,6 +55,8 @@
public void init() {
robot = Util.createRobot();
+ robot.setAutoDelay(200);
+ robot.setAutoWaitForIdle(true);
// Create instructions for the user here, as well as set up
// the environment -- set the layout manager, add buttons,
@@ -85,35 +87,24 @@
});
frame.setVisible(true);
- Util.waitForIdle(robot);
boolean isMacOSX = (OSInfo.getOSType() == OSInfo.OSType.MACOSX);
if (isMacOSX) {
robot.keyPress(KeyEvent.VK_CONTROL);
- robot.delay(20);
}
robot.keyPress(KeyEvent.VK_ALT);
- robot.delay(20);
robot.keyPress(KeyEvent.VK_F);
- robot.delay(20);
robot.keyRelease(KeyEvent.VK_F);
- robot.delay(20);
robot.keyRelease(KeyEvent.VK_ALT);
+
if (isMacOSX) {
robot.keyRelease(KeyEvent.VK_CONTROL);
- robot.delay(20);
}
- Util.waitForIdle(robot);
robot.keyPress(KeyEvent.VK_M);
- robot.delay(20);
robot.keyRelease(KeyEvent.VK_M);
- Util.waitForIdle(robot);
-
robot.keyPress(KeyEvent.VK_SPACE);
- robot.delay(20);
robot.keyRelease(KeyEvent.VK_SPACE);
- Util.waitForIdle(robot);
if (!Util.waitForCondition(activated, 2000)) {
throw new TestFailedException("a submenu wasn't activated by mnemonic key press");
--- a/jdk/test/java/awt/List/ActionEventTest/ActionEventTest.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/test/java/awt/List/ActionEventTest/ActionEventTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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
@@ -24,7 +24,7 @@
/*
* @test
* @key headful
- * @bug 6191390
+ * @bug 6191390 8158380
* @summary Verify that ActionEvent is received with correct modifiers set.
* @run main ActionEventTest
*/
@@ -45,6 +45,8 @@
public ActionEventTest() {
try {
robot = new Robot();
+ robot.setAutoDelay(100);
+ robot.setAutoWaitForIdle(true);
} catch(AWTException e) {
throw new RuntimeException(e.getMessage());
}
@@ -56,7 +58,6 @@
setLayout(new FlowLayout());
pack();
setVisible(true);
- robot.waitForIdle();
}
void performTest() {
@@ -86,11 +87,9 @@
// Press Enter on list item, to generate action event.
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
- robot.waitForIdle();
robot.keyRelease(KeyEvent.VK_ALT);
robot.keyRelease(KeyEvent.VK_SHIFT);
robot.keyRelease(KeyEvent.VK_CONTROL);
- robot.waitForIdle();
}
public static void main(String args[]) {
--- a/jdk/test/java/awt/Modal/InvisibleParentTest/InvisibleParentTest.html Thu Oct 27 14:50:23 2016 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-<!--
- Copyright (c) 2013, 2015, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-
-<html>
-<!--
- @test
- @bug 6401700 6412803
- @requires (os.family != "windows")
- @summary Tests that modal dialog is shown on the screen and
-iconified/restored correctly if its parent window is invisible
- @author artem.ananiev: area=awt.modal
- @run applet/manual=yesno InvisibleParentTest.html
- -->
-<head>
-<title> InvisibleParentTest </title>
-</head>
-<body>
-
-<h1>InvisibleParentTest<br>Bug ID: 6401700, 6412803</h1>
-
-<p> See the dialog box (usually in upper left corner) for instructions</p>
-
-<APPLET CODE="InvisibleParentTest.class" WIDTH=200 HEIGHT=200></APPLET>
-</body>
-</html>
--- a/jdk/test/java/awt/Modal/InvisibleParentTest/InvisibleParentTest.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/test/java/awt/Modal/InvisibleParentTest/InvisibleParentTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. 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
@@ -22,214 +22,187 @@
*/
/*
- test
- @bug 6401700 6412803
- @summary Tests that modal dialog is shown on the screen and
-iconified/restored correctly if some of its blocked windows are invisible
- @author artem.ananiev: area=awt.modal
- @run applet/manual=yesno InvisibleParentTest.html
-*/
-
-import java.applet.Applet;
-import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.Component;
+ * @test
+ * @key headful
+ * @bug 6401700 6412803 8058950
+ * @summary Tests that modal dialog is shown on the screen and
+ * iconified/restored correctly if some of its blocked windows are invisible
+ * @requires (os.family == "linux" | os.family == "solaris")
+ * @run main/manual InvisibleParentTest
+ */
import java.awt.Dialog;
import java.awt.Frame;
-import java.awt.TextArea;
-import java.awt.Window;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+public class InvisibleParentTest {
-public class InvisibleParentTest extends Applet
-{
- public void init()
- {
- setLayout(new BorderLayout());
+ public static void main(String args[]) throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ TestUI test = new TestUI(latch);
+
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ test.createUI();
+ } catch (Exception ex) {
+ throw new RuntimeException("Exception while creating test UI");
+ }
+ }
+ });
+
+ boolean status = latch.await(5, TimeUnit.MINUTES);
- String[] instructions =
- {
- "If your system is Windows, press PASS button.",
- "When the test starts two windows should appear: frame G1 and",
- " dialog D1. Another one frame F1 should be minimized.",
- " If the dialog is not shown (minimizied), press FAIL button.",
- "Then minimize frame G1 and restore F1. If the dialog D1 is not",
- " restored together with F1, press FAIL, else PASS"
- };
- Sysout.createDialogWithInstructions( instructions );
+ if (!status) {
+ System.out.println("Test timed out.");
+ }
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ test.disposeUI();
+ } catch (Exception ex) {
+ throw new RuntimeException("Exception while disposing test UI");
+ }
+ }
+ });
+
+ if (test.testResult == false) {
+ throw new RuntimeException("Test Failed.");
+ }
+ }
+}
+
+class TestUI {
+
+ private static JFrame mainFrame;
+ private static JPanel mainControlPanel;
+
+ private static JTextArea instructionTextArea;
+
+ private static JPanel resultButtonPanel;
+ private static JButton passButton;
+ private static JButton failButton;
+
+ private static GridBagLayout layout;
+ private final CountDownLatch latch;
+ public boolean testResult = false;
+
+ public TestUI(CountDownLatch latch) throws Exception {
+ this.latch = latch;
}
- public void start ()
- {
- Button b;
+ public final void createUI() throws Exception {
+
+ mainFrame = new JFrame("InvisibleParentTest");
+ mainFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
+
+ layout = new GridBagLayout();
+ mainControlPanel = new JPanel(layout);
+ resultButtonPanel = new JPanel(layout);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ // Create Test instructions
+ String instructions
+ = "When the test starts two windows should appear: frame G1 and\n"
+ + " dialog D1. Another one frame F1 should be minimized.\n"
+ + " If the dialog is not shown (minimizied), press FAIL button.\n"
+ + "Then minimize frame G1 and restore F1. If the dialog D1 is not\n"
+ + " restored together with F1, press FAIL, else PASS";
- setSize (200,200);
- setVisible(true);
- validate();
+ instructionTextArea = new JTextArea();
+ instructionTextArea.setText(instructions);
+ instructionTextArea.setEditable(false);
+ instructionTextArea.setBorder(BorderFactory.
+ createTitledBorder("Test Instructions"));
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainControlPanel.add(instructionTextArea, gbc);
+
+ // Create resultButtonPanel with Pass, Fail buttons
+ passButton = new JButton("Pass");
+ passButton.setActionCommand("Pass");
+ passButton.addActionListener((ActionEvent e) -> {
+ System.out.println("Pass Button pressed!");
+ testResult = true;
+ latch.countDown();
- Component c = this;
- while ((c != null) && !(c instanceof Window))
- {
- c = c.getParent();
- }
- if (c != null)
- {
- ((Window)c).setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
- }
+ });
+
+ failButton = new JButton("Fail");
+ failButton.setActionCommand("Fail");
+ failButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ System.out.println("Fail Button pressed!");
+ testResult = false;
+ latch.countDown();
+ }
+ });
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ resultButtonPanel.add(passButton, gbc);
+ gbc.gridx = 1;
+ gbc.gridy = 0;
+ resultButtonPanel.add(failButton, gbc);
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ mainControlPanel.add(resultButtonPanel, gbc);
+
+ mainFrame.add(mainControlPanel);
+
+ mainFrame.pack();
+ mainFrame.setVisible(true);
+
+ // Create AWT frames and modal dialog
+ createAWTComponents();
+ }
+
+ public void disposeUI() {
+ mainFrame.setVisible(false);
+ mainFrame.dispose();
+ }
+
+ private void createAWTComponents() {
Frame f1 = new Frame("F1");
f1.setBounds(100, 300, 100, 100);
f1.setVisible(true);
+
+ try {
+ Thread.sleep(500);
+ } catch (Exception ex) {
+ }
+
f1.setExtendedState(Frame.ICONIFIED);
Frame g1 = new Frame("G1");
g1.setBounds(150, 350, 100, 100);
g1.setVisible(true);
- final Dialog d1 = new Dialog((Frame)null, "D1", Dialog.ModalityType.APPLICATION_MODAL);
+ final Dialog d1 = new Dialog((Frame) null, "D1", Dialog.ModalityType.APPLICATION_MODAL);
d1.setBounds(200, 400, 100, 100);
- new Thread(new Runnable()
- {
- public void run()
- {
+ new Thread(new Runnable() {
+ public void run() {
d1.setVisible(true);
}
}).start();
}
}
-/****************************************************
- Standard Test Machinery
- DO NOT modify anything below -- it's a standard
- chunk of code whose purpose is to make user
- interaction uniform, and thereby make it simpler
- to read and understand someone else's test.
- ****************************************************/
-
-/**
- This is part of the standard test machinery.
- It creates a dialog (with the instructions), and is the interface
- for sending text messages to the user.
- To print the instructions, send an array of strings to Sysout.createDialog
- WithInstructions method. Put one line of instructions per array entry.
- To display a message for the tester to see, simply call Sysout.println
- with the string to be displayed.
- This mimics System.out.println but works within the test harness as well
- as standalone.
- */
-
-class Sysout
-{
- private static TestDialog dialog;
-
- public static void createDialogWithInstructions( String[] instructions )
- {
- dialog = new TestDialog( new Frame(), "Instructions" );
- dialog.printInstructions( instructions );
- dialog.setVisible(true);
- println( "Any messages for the tester will display here." );
- }
-
- public static void createDialog( )
- {
- dialog = new TestDialog( new Frame(), "Instructions" );
- String[] defInstr = { "Instructions will appear here. ", "" } ;
- dialog.printInstructions( defInstr );
- dialog.setVisible(true);
- println( "Any messages for the tester will display here." );
- }
-
-
- public static void printInstructions( String[] instructions )
- {
- dialog.printInstructions( instructions );
- }
-
-
- public static void println( String messageIn )
- {
- dialog.displayMessage( messageIn );
- }
-
-}// Sysout class
-
-/**
- This is part of the standard test machinery. It provides a place for the
- test instructions to be displayed, and a place for interactive messages
- to the user to be displayed.
- To have the test instructions displayed, see Sysout.
- To have a message to the user be displayed, see Sysout.
- Do not call anything in this dialog directly.
- */
-class TestDialog extends Dialog
-{
-
- TextArea instructionsText;
- TextArea messageText;
- int maxStringLength = 80;
-
- //DO NOT call this directly, go through Sysout
- public TestDialog( Frame frame, String name )
- {
- super( frame, name );
- setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
- int scrollBoth = TextArea.SCROLLBARS_BOTH;
- instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
- add( "North", instructionsText );
-
- messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
- add("Center", messageText);
-
- pack();
-
- setVisible(true);
- }// TestDialog()
-
- //DO NOT call this directly, go through Sysout
- public void printInstructions( String[] instructions )
- {
- //Clear out any current instructions
- instructionsText.setText( "" );
-
- //Go down array of instruction strings
-
- String printStr, remainingStr;
- for( int i=0; i < instructions.length; i++ )
- {
- //chop up each into pieces maxSringLength long
- remainingStr = instructions[ i ];
- while( remainingStr.length() > 0 )
- {
- //if longer than max then chop off first max chars to print
- if( remainingStr.length() >= maxStringLength )
- {
- //Try to chop on a word boundary
- int posOfSpace = remainingStr.
- lastIndexOf( ' ', maxStringLength - 1 );
-
- if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
-
- printStr = remainingStr.substring( 0, posOfSpace + 1 );
- remainingStr = remainingStr.substring( posOfSpace + 1 );
- }
- //else just print
- else
- {
- printStr = remainingStr;
- remainingStr = "";
- }
-
- instructionsText.append( printStr + "\n" );
-
- }// while
-
- }// for
-
- }//printInstructions()
-
- //DO NOT call this directly, go through Sysout
- public void displayMessage( String messageIn )
- {
- messageText.append( messageIn + "\n" );
- System.out.println(messageIn);
- }
-
-}// TestDialog class
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Robot/WaitForIdleSyncroizedOnString/WaitForIdleSyncroizedOnString.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Robot;
+import java.util.concurrent.CountDownLatch;
+
+import javax.swing.SwingUtilities;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8166673
+ */
+public final class WaitForIdleSyncroizedOnString {
+
+ private static final String WAIT_LOCK = "Wait Lock";
+
+ private static volatile boolean passed = true;
+
+ public static void main(final String[] args) throws Exception {
+ CountDownLatch go = new CountDownLatch(1);
+ Robot r = new Robot();
+ SwingUtilities.invokeLater(() -> System.out.println("some work"));
+ Thread t = new Thread(() -> {
+ synchronized (WAIT_LOCK) {
+ go.countDown();
+ try {
+ Thread.sleep(30000);
+ passed = false;
+ } catch (InterruptedException e) {
+ System.out.println("e = " + e);
+ }
+ }
+ });
+ t.start();
+ go.await();
+ r.waitForIdle();
+ t.interrupt();
+ if (!passed) {
+ throw new RuntimeException("Test failed");
+ }
+ }
+}
--- a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -43,7 +43,7 @@
/**
* @test
* @key headful
- * @bug 8043869 8075244 8078082 8145173
+ * @bug 8043869 8075244 8078082 8145173 8151787
* @summary Tests the HiDPI splash screen support for windows and MAC
* @modules java.desktop/sun.java2d
* @run main MultiResolutionSplashTest GENERATE_IMAGES
@@ -56,27 +56,20 @@
private static final int IMAGE_WIDTH = 300;
private static final int IMAGE_HEIGHT = 200;
+ private static boolean isMac;
- private static final ImageInfo[] macTests = {
+ static {
+ isMac = System.getProperty("os.name").contains("OS X");
+ }
+ private static final ImageInfo[] tests = {
new ImageInfo("splash1.png", "splash1@2x.png", Color.BLUE, Color.GREEN),
new ImageInfo("splash2", "splash2@2x", Color.WHITE, Color.BLACK),
new ImageInfo("splash3.", "splash3@2x.", Color.YELLOW, Color.RED)
};
- private static final ImageInfo[] windowsTests = {
- new ImageInfo("splash1.png", "splash1.scale-120.png", Color.BLUE, Color.GREEN),
- new ImageInfo("splash2", "splash2.scale-120", Color.WHITE, Color.BLACK),
- new ImageInfo("splash3.", "splash3.scale-120.", Color.YELLOW, Color.RED)
- };
- private static ImageInfo[] tests;
public static void main(String[] args) throws Exception {
String test = args[0];
- tests = windowsTests;
- String osName = System.getProperty("os.name");
- if (osName.contains("OS X")) {
- tests = macTests;
- }
switch (test) {
case "GENERATE_IMAGES":
generateImages();
@@ -104,12 +97,10 @@
Rectangle splashBounds = splashScreen.getBounds();
int screenX = (int) splashBounds.getCenterX();
int screenY = (int) splashBounds.getCenterY();
-
if (splashBounds.width != IMAGE_WIDTH) {
throw new RuntimeException(
"SplashScreen#getBounds has wrong width");
}
-
if (splashBounds.height != IMAGE_HEIGHT) {
throw new RuntimeException(
"SplashScreen#getBounds has wrong height");
@@ -117,7 +108,6 @@
Robot robot = new Robot();
Color splashScreenColor = robot.getPixelColor(screenX, screenY);
-
float scaleFactor = getScaleFactor();
Color testColor = (1 < scaleFactor) ? test.color2x : test.color1x;
@@ -129,7 +119,6 @@
static void testFocus() throws Exception {
- System.out.println("Focus Test!");
Robot robot = new Robot();
robot.setAutoDelay(50);
@@ -150,18 +139,18 @@
frame.dispose();
- if(!textField.getText().equals("ab")){
+ if (!textField.getText().equals("ab")) {
throw new RuntimeException("Focus is lost!");
}
}
- static boolean compare(Color c1, Color c2){
+ static boolean compare(Color c1, Color c2) {
return compare(c1.getRed(), c2.getRed())
&& compare(c1.getGreen(), c2.getGreen())
&& compare(c1.getBlue(), c2.getBlue());
}
- static boolean compare(int n, int m){
+ static boolean compare(int n, int m) {
return Math.abs(n - m) <= 50;
}
@@ -177,10 +166,7 @@
public void paint(Graphics g) {
float scaleFactor = 1;
if (g instanceof SunGraphics2D) {
- scaleFactor = (float)GraphicsEnvironment.
- getLocalGraphicsEnvironment().
- getDefaultScreenDevice().getDefaultConfiguration().
- getDefaultTransform().getScaleX();
+ scaleFactor = getScreenScaleFactor();
}
scaleFactors[0] = scaleFactor;
dialog.setVisible(false);
@@ -197,23 +183,30 @@
static void generateImages() throws Exception {
for (ImageInfo test : tests) {
generateImage(test.name1x, test.color1x, 1);
- generateImage(test.name2x, test.color2x, 2);
+ generateImage(test.name2x, test.color2x, getScreenScaleFactor());
}
}
- static void generateImage(String name, Color color, int scale) throws Exception {
+ static void generateImage(String name, Color color, float scale) throws Exception {
File file = new File(name);
if (file.exists()) {
return;
}
- BufferedImage image = new BufferedImage(scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT,
- BufferedImage.TYPE_INT_RGB);
+ BufferedImage image = new BufferedImage((int) (scale * IMAGE_WIDTH),
+ (int) (scale * IMAGE_HEIGHT), BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(color);
- g.fillRect(0, 0, scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT);
+ g.fillRect(0, 0, (int) (scale * IMAGE_WIDTH), (int) (scale * IMAGE_HEIGHT));
ImageIO.write(image, "png", file);
}
+ static float getScreenScaleFactor() {
+ return (float) GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration().
+ getDefaultTransform().getScaleX();
+ }
+
static class ImageInfo {
final String name1x;
@@ -223,9 +216,32 @@
public ImageInfo(String name1x, String name2x, Color color1x, Color color2x) {
this.name1x = name1x;
- this.name2x = name2x;
+ if (!isMac) {
+ float scale = getScreenScaleFactor();
+ StringBuffer buff = new StringBuffer();
+ if (scale - (int) scale > 0) {
+ buff.append("@").append((int) (scale * 100)).append("pct");
+ } else {
+ buff.append("@").append((int) scale).append("x");
+ }
+ StringBuffer buffer = new StringBuffer();
+ String[] splitStr = name1x.split("\\.");
+ if (splitStr.length == 2) {
+ this.name2x = buffer.append(splitStr[0]).append(buff)
+ .append(".").append(splitStr[1]).toString();
+ } else {
+ if (name1x.indexOf(".") > 0) {
+ this.name2x = buffer.append(splitStr[0]).append(buff).append(".").toString();
+ } else {
+ this.name2x = buffer.append(splitStr[0]).append(buff).toString();
+ }
+ }
+ } else {
+ this.name2x = name2x;
+ }
this.color1x = color1x;
this.color2x = color2x;
}
}
}
+
--- a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -44,7 +44,7 @@
import javax.imageio.ImageIO;
/**
- * @test @bug 8145174
+ * @test @bug 8145174 8151787
* @summary HiDPI splash screen support on Linux
* @modules java.desktop/sun.java2d
* @run main UnixMultiResolutionSplashTest
@@ -55,9 +55,9 @@
private static final int IMAGE_HEIGHT = 200;
private static int inx = 0;
private static final ImageInfo[] tests = {
- new ImageInfo("splash1.png", "splash1.java-scale2x.png", Color.BLUE, Color.GREEN),
- new ImageInfo("splash2", "splash2.java-scale2x", Color.WHITE, Color.BLACK),
- new ImageInfo("splash3.", "splash3.java-scale2x.", Color.YELLOW, Color.RED)
+ new ImageInfo("splash1.png", "splash1@200pct.png", Color.BLUE, Color.GREEN),
+ new ImageInfo("splash2", "splash2@2x", Color.WHITE, Color.BLACK),
+ new ImageInfo("splash3.", "splash3@200pct.", Color.YELLOW, Color.RED)
};
public static void main(String[] args) throws Exception {
@@ -96,8 +96,6 @@
Rectangle splashBounds = splashScreen.getBounds();
int screenX = (int) splashBounds.getCenterX();
int screenY = (int) splashBounds.getCenterY();
- System.out.println(screenX);
- System.out.println(screenY);
Robot robot = new Robot();
Color splashScreenColor = robot.getPixelColor(screenX, screenY);
--- a/jdk/test/java/awt/TrayIcon/TrayIconEventModifiers/TrayIconEventModifiersTest.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/test/java/awt/TrayIcon/TrayIconEventModifiers/TrayIconEventModifiersTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. 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
@@ -21,7 +21,11 @@
* questions.
*/
-import java.awt.*;
+import java.awt.EventQueue;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.SystemTray;
+import java.awt.TrayIcon;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
@@ -31,9 +35,10 @@
/*
* @test
+ * @bug 8161473
+ * @key headful
* @summary Check if MouseEvent has the proper modifiers when
* TrayIcon is clicked pressing the modifier keys
- * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com)
* @library /java/awt/patchlib
* @library ../../../../lib/testlibrary ../
* @build java.desktop/java.awt.Helper
@@ -213,6 +218,7 @@
mousePressed = false;
robot.keyPress(keyTypes[j]);
+ robot.waitForIdle();
robot.mousePress(buttonTypes[i]);
if (! mousePressed) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Window/ChangeWindowResizabilty/ChangeWindowResizabiltyTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @bug 8166897
+ @summary Some font overlap in the Optionpane dialog.
+ @run main ChangeWindowResizabiltyTest
+*/
+
+import java.awt.*;
+
+public class ChangeWindowResizabiltyTest {
+ public static void main(String[] args) throws Exception {
+ Robot robot = new Robot();
+ for(int i = 0; i < 10; i++) {
+ Dialog dialog = new Dialog((Frame) null);
+ Component panel = new Panel();
+ panel.setPreferredSize(new Dimension(200, 100));
+ dialog.add(panel);
+ dialog.pack();
+ dialog.setVisible(true);
+
+ dialog.setResizable(false);
+ robot.waitForIdle();
+ robot.delay(200);
+
+ System.out.println(panel.getLocationOnScreen());
+ System.out.println(dialog.getLocationOnScreen());
+ if (panel.getLocationOnScreen().y <
+ dialog.getLocationOnScreen().y + dialog.getInsets().top) {
+ dialog.dispose();
+ throw new RuntimeException(
+ "Wrong content position after setResizable(false)");
+ }
+
+ dialog.setResizable(true);
+ robot.waitForIdle();
+ robot.delay(200);
+ System.out.println(panel.getLocationOnScreen());
+ System.out.println(dialog.getLocationOnScreen());
+ if (panel.getLocationOnScreen().y <
+ dialog.getLocationOnScreen().y + dialog.getInsets().top) {
+ dialog.dispose();
+ throw new RuntimeException(
+ "Wrong content position after setResizable(true)");
+ }
+
+ dialog.dispose();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/KeyEvent/RobotCrash/RobotCrash.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @key headful
+ * @bug 8165555
+ * @summary VM crash after creating Robot second time and accessing key codes in
+ * single JVM mode.
+ * @run main RobotCrash
+ */
+import java.awt.Frame;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import javax.swing.SwingUtilities;
+
+public class RobotCrash implements Runnable {
+
+ private Frame frame;
+
+ public void robotKeyPressTest() throws Exception {
+
+ SwingUtilities.invokeAndWait(() -> {
+ frame = new Frame();
+ frame.setSize(300, 300);
+ frame.setVisible(true);
+ });
+
+ Robot robot = new Robot();
+ robot.waitForIdle();
+ Point pt = frame.getLocationOnScreen();
+ robot.mouseMove(((int) pt.getX() + frame.getWidth()) / 2,
+ ((int) pt.getY() + frame.getHeight()) / 2);
+ robot.waitForIdle();
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.waitForIdle();
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.waitForIdle();
+ robot.keyPress(KeyEvent.VK_ENTER);
+ robot.waitForIdle();
+ robot.keyRelease(KeyEvent.VK_ENTER);
+ robot.waitForIdle();
+
+ SwingUtilities.invokeAndWait(() -> {
+ frame.dispose();
+ });
+ }
+
+ @Override
+ public void run() {
+ try {
+ robotKeyPressTest();
+ } catch (Exception e) {
+ throw new RuntimeException("Test Failed" + e.getMessage());
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ for (int i = 0; i < 10; i++) {
+ Thread t1 = new Thread(new RobotCrash());
+ t1.start();
+ t1.join();
+ Thread t2 = new Thread(new RobotCrash());
+ t2.start();
+ t2.join();
+ Thread.sleep(1000);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/jdk/TestJDKAWTUtils.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8167126
+ */
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.Rectangle;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+public class TestJDKAWTUtils {
+
+ static JFrame f;
+ public static void main(String[] args) throws Exception {
+
+ SwingUtilities.invokeAndWait(() -> {
+ f = new JFrame("test");
+ JPanel p = new JPanel();
+ JButton b = new JButton("Hello");
+ b.setFont(new Font(Font.DIALOG, Font.PLAIN, 80));
+ p.setLayout(new BorderLayout());
+ p.add("Center", b);
+ f.getContentPane().add(p);
+ f.pack();
+ f.setVisible(true);
+ Rectangle r = new Rectangle(0, 0, 50, 50);
+ jdk.awt.AWTUtils.setComponentMixingCutoutShape(b, r);
+ });
+ Thread.sleep(2000);
+ SwingUtilities.invokeAndWait(() -> f.dispose());
+ }
+}
--- a/jdk/test/java/awt/security/WarningWindowDisposeTest/WarningWindowDisposeTest.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/test/java/awt/security/WarningWindowDisposeTest/WarningWindowDisposeTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. 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
@@ -23,9 +23,9 @@
/*
@test
- @bug 8037776
+ @key headful
+ @bug 8037776 8167288
@summary tests that the WarningWindow is properly disposed
- @author Petr Pchelko
@library ../../regtesthelpers/process
@build ProcessResults ProcessCommunicator
@run main WarningWindowDisposeTest
@@ -45,13 +45,17 @@
public static void main(String[] args) {
final AtomicBoolean passed = new AtomicBoolean(false);
new Thread(() -> {
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- throw new RuntimeException("Test FAILED!", e);
- }
- if (!passed.get()) {
- throw new RuntimeException("Test FAILED! The child process never exits");
+ for (int trial = 0; trial < 5; ++trial) {
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Test FAILED!", e);
+ }
+ if (passed.get()) {
+ break;
+ } else if (trial == 4) {
+ throw new RuntimeException("Child process never exits");
+ }
}
}, "TimeoutThread").start();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/ImageCompressionTypesTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @bug 6294607
+ * @summary Test verifies whether ImageWriteParam.getCompressionTypes()
+ * returns any duplicate compression type for ImageIO plugins.
+ * @run main ImageCompressionTypesTest
+ */
+
+import java.util.Iterator;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+
+public class ImageCompressionTypesTest {
+
+ static ImageWriter writer = null;
+
+ public ImageCompressionTypesTest(String format) {
+ Iterator it = ImageIO.getImageWritersByFormatName(format);
+ while (it.hasNext()) {
+ writer = (ImageWriter) it.next();
+ break;
+ }
+ ImageWriteParam param = writer.getDefaultWriteParam();
+
+ param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+ System.out.println("Checking compression types for : " + format);
+ String compTypes[] = param.getCompressionTypes();
+ if (compTypes.length > 1) {
+ for (int i = 0; i < compTypes.length; i++) {
+ for (int j = i + 1; j < compTypes.length; j++) {
+ if (compTypes[i].equalsIgnoreCase(compTypes[j])) {
+ throw new RuntimeException("Duplicate compression"
+ + " type exists for image format " + format);
+ }
+ }
+ }
+ }
+ }
+
+ public static void main(String args[]) {
+ final String[] formats = {"bmp", "png", "gif", "jpg", "tiff"};
+ for (String format : formats) {
+ new ImageCompressionTypesTest(format);
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/metadata/GetElementsByTagNameTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8167281
+ * @summary Test verifies that Element.getElementsByTagName("*") is not empty
+ * for valid image.
+ * @run main GetElementsByTagNameTest
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
+import org.w3c.dom.Element;
+
+public class GetElementsByTagNameTest {
+
+ public static void main(String[] args) throws IOException {
+ // Generate some trivial image and save it to a temporary array
+ ByteArrayOutputStream tmp = new ByteArrayOutputStream();
+ ImageIO.write(new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB),
+ "gif", tmp);
+
+ // Read the stream
+ ImageInputStream in = new MemoryCacheImageInputStream(
+ new ByteArrayInputStream(tmp.toByteArray()));
+ ImageReader reader = ImageIO.getImageReaders(in).next();
+ reader.setInput(in);
+
+ // Retrieve standard image metadata tree
+ IIOMetadata meta = reader.getImageMetadata(0);
+ if (meta == null || !meta.isStandardMetadataFormatSupported()) {
+ throw new Error("Test failure: Missing metadata");
+ }
+ Element root = (Element) meta.
+ getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
+
+ // Test getElementsByTagName("*")
+ if (root.getElementsByTagName("*").getLength() == 0) {
+ throw new RuntimeException("getElementsByTagName(\"*\") returns"
+ + " nothing");
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/metadata/NthItemNodeListTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8167281
+ * @summary Test verifies that accessing nth item in NodeList doesn't throw
+ * IndexOutOfBoundsException.
+ * @run main NthItemNodeListTest
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class NthItemNodeListTest {
+
+ public static void main(String[] args) throws IOException {
+ // Generate some trivial image and save it to a temporary array
+ ByteArrayOutputStream tmp = new ByteArrayOutputStream();
+ ImageIO.write(new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB),
+ "gif", tmp);
+
+ // Read it back in
+ ImageInputStream in = new MemoryCacheImageInputStream(
+ new ByteArrayInputStream(tmp.toByteArray()));
+ ImageReader reader = ImageIO.getImageReaders(in).next();
+ reader.setInput(in);
+
+ // Retrieve standard image metadata tree
+ IIOMetadata meta = reader.getImageMetadata(0);
+ if (meta == null || !meta.isStandardMetadataFormatSupported()) {
+ throw new Error("Test failure: Missing metadata");
+ }
+ Element root = (Element) meta.
+ getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
+
+ NodeList nodeList = root.
+ getElementsByTagName(root.getFirstChild().getNodeName());
+ /*
+ * Accessing the nth node should return null and not throw
+ * IndexOutOfBoundsException.
+ */
+ Node n = (nodeList.item(nodeList.getLength()));
+ }
+}
+
--- a/jdk/test/javax/print/attribute/Services_getDocFl.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/test/javax/print/attribute/Services_getDocFl.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. 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
@@ -28,7 +28,7 @@
/*
* @test
- * @bug 4901243 8040139
+ * @bug 4901243 8040139 8167291
* @summary JPG, GIF, and PNG DocFlavors (URL) should be supported if Postscript is supported.
* @run main Services_getDocFl
*/
@@ -58,6 +58,7 @@
pngImagesSupported = false;
gifImagesSupported = false;
jpgImagesSupported = false;
+ psSupported = false;
for (int j=0; j<flavors.length; j++) {
System.out.println(flavors[j]);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Clip/OpenNonIntegralNumberOfSampleframes.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.LineUnavailableException;
+
+/**
+ * @test
+ * @bug 8167435
+ */
+public final class OpenNonIntegralNumberOfSampleframes {
+
+ /**
+ * We will try to use all formats, in this case all our providers will be
+ * covered by supported/unsupported formats.
+ */
+ private static final List<AudioFormat> formats = new ArrayList<>(2900);
+
+ private static final Encoding[] encodings = {
+ Encoding.ALAW, Encoding.ULAW, Encoding.PCM_SIGNED,
+ Encoding.PCM_UNSIGNED, Encoding.PCM_FLOAT
+ };
+
+ private static final int[] sampleRates = {
+ 8000, 11025, 16000, 32000, 44100
+ };
+
+ private static final int[] sampleBits = {
+ 4, 8, 11, 16, 20, 24, 32, 48, 64, 128
+ };
+
+ private static final int[] channels = {
+ 1, 2, 3, 4, 5, 6
+ };
+
+ static {
+ for (final Boolean end : new boolean[]{false, true}) {
+ for (final int sampleSize : sampleBits) {
+ for (final int sampleRate : sampleRates) {
+ for (final int channel : channels) {
+ final int frameSize = ((sampleSize + 7) / 8) * channel;
+ if (frameSize == 1) {
+ // frameSize=1 is ok for any buffers, skip it
+ continue;
+ }
+ for (final Encoding enc : encodings) {
+ formats.add(
+ new AudioFormat(enc, sampleRate, sampleSize,
+ channel, frameSize,
+ sampleRate, end));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static void main(final String[] args) {
+ for (final AudioFormat af : formats) {
+ try (Clip clip = AudioSystem.getClip()) {
+ final int bufferSize = af.getFrameSize() + 1;
+ try {
+ clip.open(af, new byte[100], 0, bufferSize);
+ } catch (final IllegalArgumentException ignored) {
+ // expected exception
+ continue;
+ } catch (final LineUnavailableException e) {
+ // should not occur, we passed incorrect bufferSize
+ e.printStackTrace();
+ }
+ System.err.println("af = " + af);
+ System.err.println("bufferSize = " + bufferSize);
+ throw new RuntimeException("Expected exception is not thrown");
+ } catch (final LineUnavailableException ignored) {
+ // the test is not applicable
+ }
+ }
+ }
+}
--- a/jdk/test/javax/swing/JMenuItem/8139169/ScreenMenuBarInputTwice.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/test/javax/swing/JMenuItem/8139169/ScreenMenuBarInputTwice.java Thu Oct 27 14:52:01 2016 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. 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
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 8139169
+ * @bug 8139169 8158390
* @summary verifies if TextArea gets input twice due to Apple's Screen Menubar
* @requires (os.family=="mac")
* @library ../../regtesthelpers
@@ -65,15 +65,13 @@
public static void main(String[] args) throws Exception {
robot = new Robot();
+ robot.setAutoDelay(200);
+ robot.setAutoWaitForIdle(true);
createUIWithSeperateMenuBar();
- robot.delay(2000);
shortcutTestCase();
- robot.delay(2000);
cleanUp();
createUIWithIntegratedMenuBar();
- robot.delay(2000);
menuTestCase();
- robot.delay(2000);
cleanUp();
}
@@ -188,7 +186,6 @@
robot.keyRelease(VK_COMMA);
robot.keyRelease(VK_SHIFT);
robot.keyRelease(VK_META);
- robot.delay(2000);
checkText(textArea.getText());
}
@@ -198,13 +195,10 @@
robot.mouseMove(mousePoint.x, mousePoint.y);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
- robot.delay(2000);
mousePoint = Util.getCenterPoint(menuItem);
robot.mouseMove(mousePoint.x, mousePoint.y);
- robot.delay(2000);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
- robot.delay(2000);
checkText(textArea.getText());
}
--- a/jdk/test/javax/swing/JTextArea/ScrollbarFlicker/ScrollFlickerTest.java Thu Oct 27 14:50:23 2016 -0400
+++ b/jdk/test/javax/swing/JTextArea/ScrollbarFlicker/ScrollFlickerTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -29,8 +29,6 @@
import javax.swing.*;
import java.awt.*;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
public class ScrollFlickerTest {
@@ -56,18 +54,19 @@
robot.delay(200);
SwingUtilities.invokeAndWait(() -> {
- scroll.getViewport().addChangeListener((e) -> cnt++);
Insets insets = scroll.getInsets();
scroll.setSize(insets.left + insets.right +
scroll.getVerticalScrollBar().getPreferredSize().width, 50);
scroll.revalidate();
});
-
+ robot.delay(200);
+ SwingUtilities.invokeAndWait(() ->
+ scroll.getViewport().addChangeListener((e) -> cnt++));
robot.delay(1000);
SwingUtilities.invokeLater(frame::dispose);
- if (cnt > 2) {
+ if (cnt > 0) {
throw new RuntimeException("Scroll bar flickers");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/plaf/basic/BasicScrollPaneUI/8166591/TooMuchWheelRotationEventsTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+/*
+ * @test
+ * @bug 8166591
+ * @key headful
+ * @summary [macos 10.12] Trackpad scrolling of text on OS X 10.12 Sierra
+ * is very fast (Trackpad, Retina only)
+ * @run main/manual/othervm TooMuchWheelRotationEventsTest
+ */
+public class TooMuchWheelRotationEventsTest {
+
+ private static volatile boolean testResult = false;
+ private static volatile CountDownLatch countDownLatch;
+ private static final String INSTRUCTIONS = "INSTRUCTIONS:\n"
+ + "Try to check the issue on Mac OS X 10.12 Sierra with trackpad"
+ + " on Retina display.\n"
+ + "\n"
+ + "If the trackpad is not supported, press PASS\n"
+ + "\n"
+ + "Use the trackpad to slightly scroll the JTextArea horizontally and vertically.\n"
+ + "If the text area is scrolled too fast press FAIL, else press PASS.";
+
+ public static void main(String args[]) throws Exception {
+ countDownLatch = new CountDownLatch(1);
+
+ SwingUtilities.invokeLater(TooMuchWheelRotationEventsTest::createUI);
+ countDownLatch.await(15, TimeUnit.MINUTES);
+
+ if (!testResult) {
+ throw new RuntimeException("Test fails!");
+ }
+ }
+
+ private static void createUI() {
+
+ final JFrame mainFrame = new JFrame("Trackpad scrolling test");
+ GridBagLayout layout = new GridBagLayout();
+ JPanel mainControlPanel = new JPanel(layout);
+ JPanel resultButtonPanel = new JPanel(layout);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ JPanel testPanel = createTestPanel();
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainControlPanel.add(testPanel, gbc);
+
+ JTextArea instructionTextArea = new JTextArea();
+ instructionTextArea.setText(INSTRUCTIONS);
+ instructionTextArea.setEditable(false);
+ instructionTextArea.setBackground(Color.white);
+
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainControlPanel.add(instructionTextArea, gbc);
+
+ JButton passButton = new JButton("Pass");
+ passButton.setActionCommand("Pass");
+ passButton.addActionListener((ActionEvent e) -> {
+ testResult = true;
+ mainFrame.dispose();
+ countDownLatch.countDown();
+
+ });
+
+ JButton failButton = new JButton("Fail");
+ failButton.setActionCommand("Fail");
+ failButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ mainFrame.dispose();
+ countDownLatch.countDown();
+ }
+ });
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ resultButtonPanel.add(passButton, gbc);
+
+ gbc.gridx = 1;
+ gbc.gridy = 0;
+ resultButtonPanel.add(failButton, gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy = 2;
+ mainControlPanel.add(resultButtonPanel, gbc);
+
+ mainFrame.add(mainControlPanel);
+ mainFrame.pack();
+
+ mainFrame.addWindowListener(new WindowAdapter() {
+
+ @Override
+ public void windowClosing(WindowEvent e) {
+ mainFrame.dispose();
+ countDownLatch.countDown();
+ }
+ });
+ mainFrame.setVisible(true);
+ }
+
+ private static JPanel createTestPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+ JTextArea textArea = new JTextArea(20, 20);
+ textArea.setText(getLongString());
+ JScrollPane scrollPane = new JScrollPane(textArea);
+ panel.add(scrollPane);
+ return panel;
+ }
+
+ private static String getLongString() {
+
+ String lowCaseString = getLongString('a', 'z');
+ String upperCaseString = getLongString('A', 'Z');
+ String digitsString = getLongString('0', '9');
+
+ int repeat = 30;
+ StringBuilder lowCaseBuilder = new StringBuilder();
+ StringBuilder upperCaseBuilder = new StringBuilder();
+ StringBuilder digitsBuilder = new StringBuilder();
+
+ for (int i = 0; i < repeat; i++) {
+ lowCaseBuilder.append(lowCaseString).append(' ');
+ upperCaseBuilder.append(upperCaseString).append(' ');
+ digitsBuilder.append(digitsString).append(' ');
+ }
+
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < 200; i++) {
+ builder.append(upperCaseBuilder).append('\n')
+ .append(lowCaseBuilder).append('\n')
+ .append(digitsBuilder).append("\n\n\n");
+ }
+
+ return builder.toString();
+ }
+
+ private static String getLongString(char c1, char c2) {
+
+ char[] chars = new char[c2 - c1 + 1];
+ for (char i = c1; i <= c2; i++) {
+ chars[i - c1] = i;
+ }
+ return new String(chars);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/plaf/motif/8165485/MotifHiDPIIconsTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.ScrollPaneConstants;
+import javax.swing.SwingUtilities;
+
+/*
+ * @test
+ * @bug 8165485
+ * @summary Bad rendering of Swing UI controls with Motif L&F on HiDPI display
+ * @run main/manual/othervm -Dsun.java2d.uiScale=2
+ * -Dswing.defaultlaf=com.sun.java.swing.plaf.motif.MotifLookAndFeel MotifHiDPIIconsTest
+ */
+public class MotifHiDPIIconsTest {
+
+ private static volatile boolean testResult = false;
+ private static volatile CountDownLatch countDownLatch;
+ private static final String INSTRUCTIONS = "INSTRUCTIONS:\n"
+ + "Check that the icons are painted smoothly on Swing UI controls:\n"
+ + " - JRadioButton\n"
+ + " - JCheckBox\n"
+ + " - JComboBox\n"
+ + " - JScrollPane (vertical and horizontal scroll bars)\n"
+ + "\n"
+ + "If so, press PASS, else press FAIL.\n";
+
+ public static void main(String args[]) throws Exception {
+ countDownLatch = new CountDownLatch(1);
+
+ SwingUtilities.invokeLater(MotifHiDPIIconsTest::createUI);
+ countDownLatch.await(15, TimeUnit.MINUTES);
+
+ if (!testResult) {
+ throw new RuntimeException("Test fails!");
+ }
+ }
+
+ private static void createUI() {
+
+ final JFrame mainFrame = new JFrame("Motif L&F icons test");
+ GridBagLayout layout = new GridBagLayout();
+ JPanel mainControlPanel = new JPanel(layout);
+ JPanel resultButtonPanel = new JPanel(layout);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+
+
+ JPanel testPanel = createJPanel();
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainControlPanel.add(testPanel, gbc);
+
+ JTextArea instructionTextArea = new JTextArea();
+ instructionTextArea.setText(INSTRUCTIONS);
+ instructionTextArea.setEditable(false);
+ instructionTextArea.setBackground(Color.white);
+
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainControlPanel.add(instructionTextArea, gbc);
+
+ JButton passButton = new JButton("Pass");
+ passButton.setActionCommand("Pass");
+ passButton.addActionListener((ActionEvent e) -> {
+ testResult = true;
+ mainFrame.dispose();
+ countDownLatch.countDown();
+
+ });
+
+ JButton failButton = new JButton("Fail");
+ failButton.setActionCommand("Fail");
+ failButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ mainFrame.dispose();
+ countDownLatch.countDown();
+ }
+ });
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ resultButtonPanel.add(passButton, gbc);
+
+ gbc.gridx = 1;
+ gbc.gridy = 0;
+ resultButtonPanel.add(failButton, gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy = 2;
+ mainControlPanel.add(resultButtonPanel, gbc);
+
+ mainFrame.add(mainControlPanel);
+ mainFrame.pack();
+
+ mainFrame.addWindowListener(new WindowAdapter() {
+
+ @Override
+ public void windowClosing(WindowEvent e) {
+ mainFrame.dispose();
+ countDownLatch.countDown();
+ }
+ });
+ mainFrame.setVisible(true);
+ }
+
+ private static JPanel createJPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+
+ JPanel iconPanel = new JPanel(new FlowLayout());
+ JRadioButton radioButton = new JRadioButton();
+ radioButton.setSelected(false);
+ iconPanel.add(radioButton);
+ radioButton = new JRadioButton();
+ radioButton.setSelected(true);
+ iconPanel.add(radioButton);
+ panel.add(iconPanel);
+
+ iconPanel = new JPanel(new FlowLayout());
+ JCheckBox checkBox = new JCheckBox();
+ checkBox.setSelected(false);
+ iconPanel.add(checkBox);
+ checkBox = new JCheckBox();
+ checkBox.setSelected(true);
+ iconPanel.add(checkBox);
+ panel.add(iconPanel);
+
+ iconPanel = new JPanel(new FlowLayout());
+ JComboBox<String> comboBox = new JComboBox(new String[]{"111", "222"});
+ iconPanel.add(comboBox);
+ panel.add(iconPanel);
+
+ iconPanel = new JPanel(new FlowLayout());
+ JTextArea textArea = new JTextArea(3, 7);
+ textArea.setText("AAA");
+ JScrollPane scrollPane = new JScrollPane(textArea);
+ scrollPane.setHorizontalScrollBarPolicy(
+ ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.setVerticalScrollBarPolicy(
+ ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+ iconPanel.add(scrollPane);
+ panel.add(iconPanel);
+
+ return panel;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/Caret/8163124/CaretFloatingPointAPITest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.TextUI;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Caret;
+import javax.swing.text.DefaultHighlighter;
+import javax.swing.text.Document;
+import javax.swing.text.Highlighter;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.Position;
+
+/*
+ * @test
+ * @bug 8163175
+ * @summary PlainView.modelToView() method should return Rectangle2D
+ * @run main/manual CaretFloatingPointAPITest
+ */
+public class CaretFloatingPointAPITest {
+
+ private static volatile boolean testResult = false;
+ private static volatile CountDownLatch countDownLatch;
+ private static final String INSTRUCTIONS = "INSTRUCTIONS:\n\n"
+ + "Verify that cursor position is not rounded on HiDPI display.\n\n"
+ + "If the display does not support HiDPI mode press PASS.\n\n"
+ + "1. Press the Right-Arrow key several times to move the red caret"
+ + " in the text field.\n"
+ + "2. Check that the caret has the same position between chars"
+ + " in diffrent locations.\n\n"
+ + "If so, press PASS, else press FAIL.\n";
+
+ public static void main(String args[]) throws Exception {
+ countDownLatch = new CountDownLatch(1);
+
+ SwingUtilities.invokeLater(CaretFloatingPointAPITest::createUI);
+ countDownLatch.await(15, TimeUnit.MINUTES);
+
+ if (!testResult) {
+ throw new RuntimeException("Test fails!");
+ }
+ }
+
+ private static void createUI() {
+
+ final JFrame mainFrame = new JFrame("Metal L&F icons test");
+ GridBagLayout layout = new GridBagLayout();
+ JPanel mainControlPanel = new JPanel(layout);
+ JPanel resultButtonPanel = new JPanel(layout);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ JTextField textField = new JTextField("aaaaaaaaaaaaaaaaaaaaaaa");
+ Dimension size = new Dimension(400, 100);
+ textField.setPreferredSize(size);
+ textField.setFont(textField.getFont().deriveFont(28.0f));
+ textField.setCaretColor(Color.RED);
+ textField.setCaret(new CustomCaret());
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.insets = new Insets(5, 15, 5, 15);
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainControlPanel.add(textField, gbc);
+
+ JTextArea instructionTextArea = new JTextArea();
+ instructionTextArea.setText(INSTRUCTIONS);
+ instructionTextArea.setEditable(false);
+ instructionTextArea.setBackground(Color.white);
+
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainControlPanel.add(instructionTextArea, gbc);
+
+ JButton passButton = new JButton("Pass");
+ passButton.setActionCommand("Pass");
+ passButton.addActionListener((ActionEvent e) -> {
+ testResult = true;
+ mainFrame.dispose();
+ countDownLatch.countDown();
+
+ });
+
+ JButton failButton = new JButton("Fail");
+ failButton.setActionCommand("Fail");
+ failButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ mainFrame.dispose();
+ countDownLatch.countDown();
+ }
+ });
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+
+ resultButtonPanel.add(passButton, gbc);
+
+ gbc.gridx = 1;
+ gbc.gridy = 0;
+ resultButtonPanel.add(failButton, gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy = 2;
+ mainControlPanel.add(resultButtonPanel, gbc);
+
+ mainFrame.add(mainControlPanel);
+ mainFrame.pack();
+
+ mainFrame.addWindowListener(new WindowAdapter() {
+
+ @Override
+ public void windowClosing(WindowEvent e) {
+ mainFrame.dispose();
+ countDownLatch.countDown();
+ }
+ });
+ mainFrame.setVisible(true);
+ }
+
+ static class CustomCaret implements Caret {
+
+ private JTextComponent component;
+ private boolean visible;
+ private boolean selectionVisible = true;
+ int blinkRate;
+ int dot;
+ int mark;
+ Position.Bias dotBias;
+ Position.Bias markBias;
+ Object selectionTag;
+ Point2D magicCaretPosition;
+
+ private MouseListener mouseListener = new CaretMouseListener();
+
+ @Override
+ public void install(JTextComponent c) {
+ this.component = c;
+ c.addMouseListener(mouseListener);
+ }
+
+ @Override
+ public void deinstall(JTextComponent c) {
+ c.removeMouseListener(mouseListener);
+ this.component = null;
+ }
+
+ @Override
+ public void paint(Graphics g) {
+
+ if (component == null) {
+ return;
+ }
+
+ int dot = getDot();
+ Rectangle2D r = null;
+ try {
+ r = component.modelToView2D(dot);
+ } catch (BadLocationException e) {
+ return;
+ }
+
+ if (r == null) {
+ return;
+ }
+
+ Rectangle2D cr = getCaretRectangle(r);
+ repaint(cr.getBounds());
+
+ g.setColor(component.getCaretColor());
+ float cx = (float) cr.getX();
+ float cy = (float) cr.getY();
+ float cw = (float) cr.getWidth();
+ float ch = (float) cr.getHeight();
+ float c = cx + cw / 2;
+
+ Graphics2D g2d = (Graphics2D) g;
+ g2d.draw(new Line2D.Float(c, cy, c, cy + ch));
+ g2d.draw(new Line2D.Float(cx, cy, cx + cw, cy));
+ g2d.draw(new Line2D.Float(cx, cy + ch, cx + cw, cy + ch));
+ }
+
+ void repaint(Rectangle r) {
+ component.repaint(r);
+ }
+
+ Rectangle2D getCaretRectangle(Rectangle2D r) {
+ int d = 3;
+ double cx = r.getX() - d;
+ double cy = r.getY();
+ double cw = 2 * d;
+ double ch = r.getHeight();
+ return new Rectangle2D.Double(cx, cy, cw, ch);
+ }
+
+ @Override
+ public void addChangeListener(ChangeListener l) {
+ }
+
+ @Override
+ public void removeChangeListener(ChangeListener l) {
+ }
+
+ @Override
+ public boolean isVisible() {
+ return visible;
+ }
+
+ @Override
+ public void setVisible(boolean v) {
+ this.visible = true;
+ }
+
+ @Override
+ public boolean isSelectionVisible() {
+ return selectionVisible;
+ }
+
+ @Override
+ public void setSelectionVisible(boolean v) {
+ this.selectionVisible = v;
+ updateSelection();
+ }
+
+ @Override
+ public void setMagicCaretPosition(Point p) {
+ magicCaretPosition = p;
+ }
+
+ @Override
+ public Point getMagicCaretPosition() {
+ if (magicCaretPosition != null) {
+ return new Point((int) magicCaretPosition.getX(),
+ (int) magicCaretPosition.getY());
+ }
+ return null;
+ }
+
+ @Override
+ public void setBlinkRate(int rate) {
+ this.blinkRate = rate;
+ }
+
+ @Override
+ public int getBlinkRate() {
+ return blinkRate;
+ }
+
+ @Override
+ public int getDot() {
+ return dot;
+ }
+
+ @Override
+ public int getMark() {
+ return mark;
+ }
+
+ @Override
+ public void setDot(int dot) {
+ setDot(dot, Position.Bias.Forward);
+ }
+
+ private void setDot(int dot, Position.Bias bias) {
+ handleSetDot(dot, bias);
+ updateSelection();
+ }
+
+ @Override
+ public void moveDot(int dot) {
+ moveDot(dot, Position.Bias.Forward);
+ }
+
+ private void moveDot(int dot, Position.Bias bias) {
+ changeCaretPosition(dot, bias);
+ updateSelection();
+ }
+
+ void handleSetDot(int dot, Position.Bias dotBias) {
+
+ if (component == null) {
+ return;
+ }
+
+ Document doc = component.getDocument();
+ if (doc != null) {
+ dot = Math.min(dot, doc.getLength());
+ }
+
+ dot = Math.max(dot, 0);
+
+ if (dot == 0) {
+ dotBias = Position.Bias.Forward;
+ }
+
+ mark = dot;
+
+ if (this.dot != dot || this.dotBias != dotBias) {
+ changeCaretPosition(dot, dotBias);
+ updateSelection();
+ }
+
+ this.markBias = this.dotBias;
+ }
+
+ void changeCaretPosition(int dot, Position.Bias dotBias) {
+ this.dot = dot;
+ this.dotBias = dotBias;
+ setMagicCaretPosition(null);
+ SwingUtilities.invokeLater(this::repaintNewCaret);
+ }
+
+ private void updateSelection() {
+ Highlighter h = component.getHighlighter();
+ if (h != null) {
+ int p0 = Math.min(dot, mark);
+ int p1 = Math.max(dot, mark);
+
+ if (p0 == p1 || !selectionVisible) {
+ if (selectionTag != null) {
+ h.removeHighlight(selectionTag);
+ selectionTag = null;
+ }
+ } else {
+ try {
+ if (selectionTag != null) {
+ h.changeHighlight(selectionTag, p0, p1);
+ } else {
+ Highlighter.HighlightPainter p = getSelectionPainter();
+ selectionTag = h.addHighlight(p0, p1, p);
+ }
+ } catch (BadLocationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+
+ void repaintNewCaret() {
+ if (component != null) {
+ TextUI mapper = component.getUI();
+ Document doc = component.getDocument();
+ if ((mapper != null) && (doc != null)) {
+ Rectangle2D newLoc;
+ try {
+ newLoc = mapper.modelToView2D(component, this.dot, this.dotBias);
+ } catch (BadLocationException e) {
+ newLoc = null;
+ }
+ if (newLoc != null) {
+ adjustVisibility(newLoc.getBounds());
+ if (getMagicCaretPosition() == null) {
+ setMagicCaretPosition(new Point((int) newLoc.getX(),
+ (int) newLoc.getY()));
+ }
+ }
+ damage(newLoc.getBounds());
+ }
+ }
+ }
+
+ protected Highlighter.HighlightPainter getSelectionPainter() {
+ return DefaultHighlighter.DefaultPainter;
+ }
+
+ protected void adjustVisibility(Rectangle nloc) {
+ if (component == null) {
+ return;
+ }
+ if (SwingUtilities.isEventDispatchThread()) {
+ component.scrollRectToVisible(nloc);
+ } else {
+ SwingUtilities.invokeLater(() -> {
+ component.scrollRectToVisible(nloc);
+ });
+ }
+ }
+
+ protected synchronized void damage(Rectangle r) {
+ if (r != null && component != null) {
+ component.repaint(r);
+ }
+ }
+
+ private class CaretMouseListener extends MouseAdapter {
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ Point pt = new Point(e.getX(), e.getY());
+ Position.Bias[] biasRet = new Position.Bias[1];
+ int pos = component.getUI().viewToModel(component, pt, biasRet);
+ if (biasRet[0] == null) {
+ biasRet[0] = Position.Bias.Forward;
+ }
+ if (pos >= 0) {
+ setDot(pos);
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/JTextComponent/8156217/TextSelectionTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.text.JTextComponent;
+
+/**
+ * @test
+ * @bug 8156217
+ * @summary Selected text is shifted on HiDPI display
+ * @run main/manual/othervm -Dsun.java2d.uiScale=2 TextSelectionTest
+ */
+public class TextSelectionTest {
+
+ private static final String INSTRUCTIONS = "This is a manual test.\n"
+ + "\n"
+ + "Select the current text from the end to the beginning.\n"
+ + "\n"
+ + "If the text is slightly shiftted from one side to another\n"
+ + "and back during selection press Fail.\n"
+ + "Otherwise, press Pass.";
+
+ private static final CountDownLatch latch = new CountDownLatch(1);
+ private static volatile boolean passed = false;
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(TextSelectionTest::createAndShowGUI);
+ latch.await(3, TimeUnit.MINUTES);
+ System.out.println("passed: " + passed);
+ if (!passed) {
+ throw new RuntimeException("Test fails!");
+ }
+ }
+
+ private static void createAndShowGUI() {
+
+ JFrame frame = new JFrame("Follow the instructions below:");
+ frame.setSize(700, 500);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ JPanel panel = new JPanel(new BorderLayout());
+ JTextComponent textComponent = new JTextArea(INSTRUCTIONS);
+ textComponent.setEditable(false);
+ Font font = textComponent.getFont();
+ font = font.deriveFont(24.0f);
+ textComponent.setFont(font);
+ panel.add(textComponent, BorderLayout.CENTER);
+
+ JPanel buttonsPanel = new JPanel(new FlowLayout());
+ JButton passButton = new JButton("Pass");
+ passButton.addActionListener((e) -> {
+ passed = true;
+ latch.countDown();
+ frame.dispose();
+ });
+ JButton failsButton = new JButton("Fail");
+ failsButton.addActionListener((e) -> {
+ passed = false;
+ latch.countDown();
+ frame.dispose();
+ });
+
+ buttonsPanel.add(passButton);
+ buttonsPanel.add(failsButton);
+ panel.add(buttonsPanel, BorderLayout.SOUTH);
+
+ frame.getContentPane().add(panel);
+
+ frame.addWindowListener(new WindowAdapter() {
+
+ @Override
+ public void windowClosing(WindowEvent e) {
+ latch.countDown();
+ }
+ });
+ frame.setVisible(true);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/View/8156217/FPMethodCalledTest.java Thu Oct 27 14:52:01 2016 -0400
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.FlowLayout;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Robot;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+import javax.swing.plaf.metal.MetalTextFieldUI;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Element;
+import javax.swing.text.PasswordView;
+import javax.swing.text.PlainView;
+import javax.swing.text.View;
+import javax.swing.text.WrappedPlainView;
+
+/**
+ * @test
+ * @bug 8156217
+ * @key headful
+ * @summary Selected text is shifted on HiDPI display
+ * @run main FPMethodCalledTest
+ */
+public class FPMethodCalledTest {
+
+ private static JFrame frame;
+ private static JTextField textField;
+
+ public static void main(String[] args) throws Exception {
+
+ for (Test test : TESTS) {
+ test(test);
+ }
+ }
+
+ static void test(final Test test) throws Exception {
+ try {
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+ SwingUtilities.invokeAndWait(() -> {
+ createAndShowGUI(test);
+ });
+
+ robot.waitForIdle();
+
+ SwingUtilities.invokeAndWait(() -> {
+ textField.select(1, 3);
+ });
+
+ robot.waitForIdle();
+
+ SwingUtilities.invokeAndWait(() -> {
+ Resultable resultable = test.resultable;
+ if (!resultable.getResult()) {
+ throw new RuntimeException("Test fails for: " + resultable);
+ }
+ });
+ } finally {
+ SwingUtilities.invokeAndWait(() -> {
+ if (frame != null) {
+ frame.dispose();
+ }
+ });
+ }
+ }
+
+ static void createAndShowGUI(Test test) {
+
+ try {
+ UIManager.setLookAndFeel(new MetalLookAndFeel());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ frame = new JFrame();
+ frame.setSize(300, 300);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ JPanel panel = new JPanel(new FlowLayout());
+
+ String text = "AAAAAAA";
+ textField = test.isPasswordField()
+ ? new JPasswordField(text)
+ : new JTextField(text);
+
+ textField.setUI(new MetalTextFieldUI() {
+
+ @Override
+ public View create(Element elem) {
+ return test.createView(elem);
+ }
+ });
+
+ panel.add(textField);
+ frame.getContentPane().add(panel);
+ frame.setVisible(true);
+ }
+
+ private static final Test[] TESTS = {
+ new Test() {
+ @Override
+ View createView(Element elem) {
+ PlainViewINTAPI view = new PlainViewINTAPI(elem);
+ resultable = view;
+ return view;
+ }
+ },
+ new Test() {
+ @Override
+ View createView(Element elem) {
+ PlainViewFPAPI view = new PlainViewFPAPI(elem);
+ resultable = view;
+ return view;
+ }
+ },
+ new Test() {
+ @Override
+ View createView(Element elem) {
+ PlainViewMixedAPI view = new PlainViewMixedAPI(elem);
+ resultable = view;
+ return view;
+ }
+ },
+ new Test() {
+ @Override
+ View createView(Element elem) {
+ WrappedPlainViewINTAPI view = new WrappedPlainViewINTAPI(elem);
+ resultable = view;
+ return view;
+ }
+ },
+ new Test() {
+ @Override
+ View createView(Element elem) {
+ WrappedPlainViewFPAPI view = new WrappedPlainViewFPAPI(elem);
+ resultable = view;
+ return view;
+ }
+ },
+ new Test() {
+ @Override
+ View createView(Element elem) {
+ WrappedPlainViewMixedAPI view = new WrappedPlainViewMixedAPI(elem);
+ resultable = view;
+ return view;
+ }
+ },
+ new Test(true) {
+
+ @Override
+ View createView(Element elem) {
+ PasswordViewINTAPI view = new PasswordViewINTAPI(elem);
+ resultable = view;
+ return view;
+ }
+ },
+ new Test(true) {
+
+ @Override
+ View createView(Element elem) {
+ PasswordViewFPAPI view = new PasswordViewFPAPI(elem);
+ resultable = view;
+ return view;
+ }
+ },
+ new Test(true) {
+
+ @Override
+ View createView(Element elem) {
+ PasswordViewMixedAPI view = new PasswordViewMixedAPI(elem);
+ resultable = view;
+ return view;
+ }
+ }
+ };
+
+ static interface Resultable {
+
+ boolean getResult();
+ }
+
+ static abstract class Test {
+
+ Resultable resultable;
+ final boolean isPasswordField;
+
+ public Test() {
+ this(false);
+ }
+
+ public Test(boolean isPasswordField) {
+ this.isPasswordField = isPasswordField;
+ }
+
+ boolean isPasswordField() {
+ return isPasswordField;
+ }
+
+ abstract View createView(Element elem);
+ }
+
+ static class PlainViewINTAPI extends PlainView implements Resultable {
+
+ boolean drawLine = false;
+ boolean drawSelected = false;
+ boolean drawUnselected = false;
+
+ public PlainViewINTAPI(Element elem) {
+ super(elem);
+ }
+
+ @Override
+ protected void drawLine(int lineIndex, Graphics g, int x, int y) {
+ drawLine = true;
+ super.drawLine(lineIndex, g, x, y);
+ }
+
+ @Override
+ protected int drawSelectedText(Graphics g, int x, int y,
+ int p0, int p1) throws BadLocationException {
+ drawSelected = true;
+ return super.drawSelectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ protected int drawUnselectedText(Graphics g, int x, int y,
+ int p0, int p1) throws BadLocationException {
+ drawUnselected = true;
+ return super.drawUnselectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ public boolean getResult() {
+ return drawLine && drawSelected && drawUnselected;
+ }
+ }
+
+ static class PlainViewFPAPI extends PlainView implements Resultable {
+
+ boolean drawLine = false;
+ boolean drawSelected = false;
+ boolean drawUnselected = false;
+
+ public PlainViewFPAPI(Element elem) {
+ super(elem);
+ }
+
+ @Override
+ protected void drawLine(int lineIndex, Graphics2D g, float x, float y) {
+ drawLine = true;
+ super.drawLine(lineIndex, g, x, y);
+ }
+
+ @Override
+ protected float drawSelectedText(Graphics2D g, float x, float y,
+ int p0, int p1) throws BadLocationException {
+ drawSelected = true;
+ return super.drawSelectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ protected float drawUnselectedText(Graphics2D g, float x, float y,
+ int p0, int p1) throws BadLocationException {
+ drawUnselected = true;
+ return super.drawUnselectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ public boolean getResult() {
+ return drawSelected;
+ }
+ }
+
+ static class PlainViewMixedAPI extends PlainView implements Resultable {
+
+ boolean isIntMethodCalled = false;
+ boolean isFPMethodCalled = false;
+
+ public PlainViewMixedAPI(Element elem) {
+ super(elem);
+ }
+
+ @Override
+ protected int drawSelectedText(Graphics g, int x, int y,
+ int p0, int p1) throws BadLocationException {
+ isIntMethodCalled = true;
+ return super.drawSelectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ protected float drawSelectedText(Graphics2D g, float x, float y,
+ int p0, int p1) throws BadLocationException {
+ isFPMethodCalled = true;
+ return super.drawSelectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ public boolean getResult() {
+ return !isIntMethodCalled && isFPMethodCalled;
+ }
+ }
+
+ static class WrappedPlainViewINTAPI extends WrappedPlainView implements Resultable {
+
+ boolean drawLine = false;
+ boolean drawSelected = false;
+ boolean drawUnselected = false;
+
+ public WrappedPlainViewINTAPI(Element elem) {
+ super(elem);
+ }
+
+ @Override
+ protected void drawLine(int p0, int p1, Graphics g, int x, int y) {
+ drawLine = true;
+ super.drawLine(p0, p1, g, x, y);
+ }
+
+ @Override
+ protected int drawSelectedText(Graphics g, int x, int y,
+ int p0, int p1) throws BadLocationException {
+ drawSelected = true;
+ return super.drawSelectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ protected int drawUnselectedText(Graphics g, int x, int y,
+ int p0, int p1) throws BadLocationException {
+ drawUnselected = true;
+ return super.drawUnselectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ public boolean getResult() {
+ return drawLine && drawSelected && drawUnselected;
+ }
+ }
+
+ static class WrappedPlainViewFPAPI extends WrappedPlainView implements Resultable {
+
+ boolean drawLine = false;
+ boolean drawSelected = false;
+ boolean drawUnselected = false;
+
+ public WrappedPlainViewFPAPI(Element elem) {
+ super(elem);
+ }
+
+ @Override
+ protected void drawLine(int p0, int p1, Graphics2D g, float x, float y) {
+ drawLine = true;
+ super.drawLine(p0, p1, g, x, y);
+ }
+
+ @Override
+ protected float drawSelectedText(Graphics2D g, float x, float y,
+ int p0, int p1) throws BadLocationException {
+ drawSelected = true;
+ return super.drawSelectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ protected float drawUnselectedText(Graphics2D g, float x, float y,
+ int p0, int p1) throws BadLocationException {
+ drawUnselected = true;
+ return super.drawUnselectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ public boolean getResult() {
+ return drawLine && drawSelected && drawUnselected;
+ }
+ }
+
+ static class WrappedPlainViewMixedAPI extends WrappedPlainView implements Resultable {
+
+ boolean isIntMethodCalled = false;
+ boolean isFPMethodCalled = false;
+
+ public WrappedPlainViewMixedAPI(Element elem) {
+ super(elem);
+ }
+
+ @Override
+ protected int drawUnselectedText(Graphics g, int x, int y,
+ int p0, int p1) throws BadLocationException {
+ isIntMethodCalled = true;
+ return super.drawUnselectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ protected float drawUnselectedText(Graphics2D g, float x, float y,
+ int p0, int p1) throws BadLocationException {
+ isFPMethodCalled = true;
+ return super.drawUnselectedText(g, x, y, p0, p1);
+ }
+
+ @Override
+ public boolean getResult() {
+ return !isIntMethodCalled && isFPMethodCalled;
+ }
+ }
+
+ static class PasswordViewINTAPI extends PasswordView implements Resultable {
+
+ boolean isIntMethodCalled = false;
+
+ public PasswordViewINTAPI(Element elem) {
+ super(elem);
+
+ }
+
+ @Override
+ protected int drawEchoCharacter(Graphics g, int x, int y, char c) {
+ isIntMethodCalled = true;
+ return super.drawEchoCharacter(g, x, y, c);
+ }
+
+ @Override
+ public boolean getResult() {
+ return isIntMethodCalled;
+ }
+ }
+
+ static class PasswordViewFPAPI extends PasswordView implements Resultable {
+
+ boolean isFPMethodCalled = false;
+
+ public PasswordViewFPAPI(Element elem) {
+ super(elem);
+
+ }
+
+ @Override
+ protected float drawEchoCharacter(Graphics2D g, float x, float y, char c) {
+ isFPMethodCalled = true;
+ return super.drawEchoCharacter(g, x, y, c);
+ }
+
+ @Override
+ public boolean getResult() {
+ return isFPMethodCalled;
+ }
+ }
+
+ static class PasswordViewMixedAPI extends PasswordView implements Resultable {
+
+ boolean isIntMethodCalled = false;
+ boolean isFPMethodCalled = false;
+
+ public PasswordViewMixedAPI(Element elem) {
+ super(elem);
+
+ }
+
+ @Override
+ protected int drawEchoCharacter(Graphics g, int x, int y, char c) {
+ isIntMethodCalled = true;
+ return super.drawEchoCharacter(g, x, y, c);
+ }
+
+ @Override
+ protected float drawEchoCharacter(Graphics2D g, float x, float y, char c) {
+ isFPMethodCalled = true;
+ return super.drawEchoCharacter(g, x, y, c);
+ }
+
+ @Override
+ public boolean getResult() {
+ return !isIntMethodCalled && isFPMethodCalled;
+ }
+ }
+}