This commit is contained in:
Sean Mullan 2016-10-27 14:52:01 -04:00
commit abea796b35
100 changed files with 4878 additions and 1077 deletions

View File

@ -44,6 +44,7 @@ SUNWprivate_1.1 {
SplashSetFileJarName;
SplashSetScaleFactor;
SplashGetScaledImageName;
SplashGetScaledImgNameMaxPstfixLen;
local:
*;
};

View File

@ -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 @@ java.launcher.opt.header = Usage: {0} [options] class [args...]\n\
\ (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 @@ java.launcher.opt.footer =\ -cp <class search path of directories and zip
\ 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\

View File

@ -29,11 +29,9 @@ import sun.lwawt.LWWindowPeer;
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 @@ class CAccessibility implements PropertyChangeListener {
}
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 @@ class CAccessibility implements PropertyChangeListener {
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) {

View File

@ -39,7 +39,10 @@ import javax.swing.event.ChangeListener;
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 @@ class CAccessible extends CFRetainedResource implements Accessible {
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 @@ class CAccessible extends CFRetainedResource implements Accessible {
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);
}
}
}
}
}

View File

@ -97,7 +97,7 @@ public class CEmbeddedFrame extends EmbeddedFrame {
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,

View File

@ -44,6 +44,8 @@ final class CPlatformResponder {
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 @@ final class CPlatformResponder {
*/
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 @@ final class CPlatformResponder {
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;
}
}
}

View File

@ -194,7 +194,8 @@ public class CPlatformView extends CFRetainedResource {
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,

View File

@ -32,6 +32,13 @@ import java.awt.event.*;
* 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 @@ final class NSEvent {
private int y;
private double scrollDeltaY;
private double scrollDeltaX;
private int scrollPhase;
private int absX;
private int absY;
@ -62,7 +70,7 @@ final class NSEvent {
// 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 @@ final class NSEvent {
this.absY = absY;
this.scrollDeltaY = scrollDeltaY;
this.scrollDeltaX = scrollDeltaX;
this.scrollPhase = scrollPhase;
}
int getType() {
@ -107,6 +116,10 @@ final class NSEvent {
return scrollDeltaX;
}
int getScrollPhase() {
return scrollPhase;
}
int getAbsX() {
return absX;
}

View File

@ -383,7 +383,7 @@ static BOOL shouldUsePressAndHold() {
}
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 @@ static BOOL shouldUsePressAndHold() {
(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");

View File

@ -317,7 +317,7 @@ AWT_ASSERT_APPKIT_THREAD;
[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 @@ AWT_ASSERT_APPKIT_THREAD;
// 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 @@ AWT_ASSERT_APPKIT_THREAD;
// 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 @@ AWT_ASSERT_APPKIT_THREAD;
- (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 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowSt
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 @@ JNF_COCOA_ENTER(env);
} else {
[JNFException raise:env as:kIllegalArgumentException reason:"unknown event type"];
}
JNF_COCOA_EXIT(env);
}
@ -1476,7 +1478,7 @@ JNF_COCOA_ENTER(env);
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

View File

@ -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],

View File

@ -139,9 +139,9 @@ static NSSize ScaledImageSizeForStatusBar(NSSize imageSize, BOOL autosize) {
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 @@ static NSSize ScaledImageSizeForStatusBar(NSSize imageSize, BOOL autosize) {
(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");

View File

@ -66,7 +66,6 @@ static JNF_CLASS_CACHE(sjc_CAccessible, "sun/lwawt/macosx/CAccessible");
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 @@ static NSObject *sAttributeNamesLOCK = nil;
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 @@ static NSObject *sAttributeNamesLOCK = nil;
+ (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 @@ static NSObject *sAttributeNamesLOCK = nil;
// 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 @@ static NSObject *sAttributeNamesLOCK = nil;
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 @@ static NSObject *sAttributeNamesLOCK = nil;
return value;
}
- (BOOL)accessibilityIsChildrenAttributeSettable
{
return NO;
@ -939,6 +973,13 @@ static NSObject *sAttributeNamesLOCK = nil;
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 @@ static NSObject *sAttributeNamesLOCK = nil;
}
return fNSRole;
}
- (BOOL)accessibilityIsRoleAttributeSettable
{
return NO;
@ -1046,8 +1088,7 @@ static NSObject *sAttributeNamesLOCK = nil;
- (NSString *)accessibilitySubroleAttribute
{
NSString *value = nil;
if ([[self javaRole] isEqualToString:@"passwordtext"])
{
if ([[self javaRole] isEqualToString:@"passwordtext"]) {
value = NSAccessibilitySecureTextFieldSubrole;
}
/*
@ -1123,6 +1164,45 @@ static NSObject *sAttributeNamesLOCK = nil;
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
@ -1343,6 +1423,54 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env);
}
/*
* 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

View File

@ -41,6 +41,7 @@ extern jint* gButtonDownMasks;
@interface AWTToolkit : NSObject { }
+ (long) getEventCount;
+ (void) eventCountPlusPlus;
+ (jint) scrollStateWithEvent: (NSEvent*) event;
@end
/*

View File

@ -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 @@ static long eventCount;
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

View File

@ -193,6 +193,44 @@ GetFamilyNameForFontName(NSString* fontname)
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 @@ GetFilteredFonts()
}
}
/*
* 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;
}

View File

@ -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 @@ BOOL isSWTRunning() {
}
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 @@ jboolean SplashGetScaledImageName(const char* jar, const char* file,
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 @@ SplashReconfigure(Splash * splash) {
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;
}

View File

@ -1314,7 +1314,7 @@ class GIFImageWriteParam extends ImageWriteParam {
super(locale);
this.canWriteCompressed = true;
this.canWriteProgressive = true;
this.compressionTypes = new String[] {"LZW", "lzw"};
this.compressionTypes = new String[] {"LZW"};
this.compressionType = compressionTypes[0];
}

View File

@ -298,31 +298,24 @@ public class MotifComboBoxUI extends BasicComboBoxUI implements Serializable {
public void paintIcon(Component c, Graphics g, int xo, int yo) {
int w = getIconWidth();
int h = getIconHeight();
int x1 = xo + w - 1;
int y1 = yo;
int x2 = xo + w / 2;
int y2 = yo + h - 1;
g.setColor(fill);
g.fillPolygon(new int[]{xo, x1, x2}, new int[]{yo, y1, y2}, 3);
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);
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.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
}

View File

@ -249,17 +249,11 @@ public class MotifIconFactory implements Serializable
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 @@ public class MotifIconFactory implements Serializable
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);
}
}

View File

@ -117,95 +117,57 @@ public class MotifScrollBarButton extends BasicArrowButton
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;
}
}

View File

@ -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.Objects;
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 @@ public final class AlawCodec extends SunCodec {
}
}
@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

View File

@ -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 @@ public final class AudioFloatFormatConverter extends FormatConversionProvider {
@Override
public Encoding[] getTargetEncodings() {
return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
Encoding.PCM_FLOAT };
return getSourceEncodings();
}
@Override

View File

@ -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 @@ final class DirectAudioDevice extends AbstractMixer {
// $$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);

View File

@ -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.Objects;
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 {
public final class PCMtoPCMCodec extends FormatConversionProvider {
private static final AudioFormat.Encoding[] inputEncodings = {
AudioFormat.Encoding.PCM_SIGNED,
AudioFormat.Encoding.PCM_UNSIGNED,
};
@Override
public AudioFormat.Encoding[] getSourceEncodings() {
return new Encoding[]{Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED};
}
private static final AudioFormat.Encoding[] outputEncodings = {
AudioFormat.Encoding.PCM_SIGNED,
AudioFormat.Encoding.PCM_UNSIGNED,
};
/**
* Constructs a new PCMtoPCM codec object.
*/
public PCMtoPCMCodec() {
super( inputEncodings, outputEncodings);
@Override
public AudioFormat.Encoding[] getTargetEncodings() {
return getSourceEncodings();
}
@Override

View File

@ -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 @@ public final class SoftMixingClip extends SoftMixingDataLine implements Clip {
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);

View File

@ -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;
}
}

View File

@ -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 @@ public final class Toolkit {
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)

View File

@ -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.Objects;
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 @@ public final class UlawCodec extends SunCodec {
}
}
/**
* 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

View File

@ -851,8 +851,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
{
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 @@ public abstract class Component implements ImageObserver, MenuContainer,
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 @@ public abstract class Component implements ImageObserver, MenuContainer,
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 @@ public abstract class Component implements ImageObserver, MenuContainer,
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);
}

View File

@ -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 @@ public final class DisplayMode {
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object dm) {
if (dm instanceof DisplayMode) {
return equals((DisplayMode)dm);
@ -153,9 +154,20 @@ public final class DisplayMode {
/**
* {@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]");
}
}

View File

@ -154,6 +154,10 @@ import static sun.font.EAttribute.*;
* 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

View File

@ -65,6 +65,16 @@ import sun.awt.image.SunWritableRaster;
* <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>

View File

@ -122,7 +122,7 @@ class IIONodeList implements NodeList {
}
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 @@ public class IIOMetadataNode implements Element, NodeList {
}
private void getElementsByTagName(String name, List<Node> l) {
if (nodeName.equals(name)) {
if (nodeName.equals(name) || "*".equals(name)) {
l.add(this);
}

View File

@ -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 @@ public abstract class FormatConversionProvider {
* {@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 @@ public abstract class FormatConversionProvider {
* {@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 @@ public abstract class FormatConversionProvider {
* @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 @@ public abstract class FormatConversionProvider {
* @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);
}
/**

View File

@ -46,7 +46,11 @@ public abstract class TextUI extends ComponentUI
* @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 @@ public abstract class TextUI extends ComponentUI
* @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 @@ public abstract class TextUI extends ComponentUI
* should be in the same coordinate system as the mouse
* events.
* @return the offset from the start of the document &gt;= 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 @@ public abstract class TextUI extends ComponentUI
*
* @return the location within the model that best represents the
* given point in the view &gt;= 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 @@ public abstract class TextUI extends ComponentUI
* @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;
}

View File

@ -28,6 +28,8 @@ import java.util.*;
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 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory {
* @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 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory {
* @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 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory {
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 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory {
* @return the offset from the start of the document &gt;= 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 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory {
* @return the offset from the start of the document &gt;= 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 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory {
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) {

View File

@ -38,6 +38,8 @@ import javax.swing.plaf.ComponentUI;
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 @@ public class MultiTextUI extends TextUI {
*
* @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 @@ public class MultiTextUI extends TextUI {
*
* @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 @@ public class MultiTextUI extends TextUI {
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 @@ public class MultiTextUI extends TextUI {
* @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 @@ public class MultiTextUI extends TextUI {
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.
*

View File

@ -98,26 +98,27 @@ class GlyphPainter1 extends GlyphView.GlyphPainter {
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 @@ class GlyphPainter1 extends GlyphView.GlyphPainter {
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;

View File

@ -145,8 +145,9 @@ class GlyphPainter2 extends GlyphView.GlyphPainter {
// 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;
}
/**

View File

@ -49,6 +49,8 @@ import java.awt.im.InputContext;
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,11 +1372,37 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A
* @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.
@ -1388,11 +1416,35 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A
* 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

View File

@ -27,6 +27,7 @@ package javax.swing.text;
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 @@ public class ParagraphView extends FlowView implements TabExpander {
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;
}
/**

View File

@ -26,7 +26,11 @@ package javax.swing.text;
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 @@ public class PasswordView extends FieldView {
* @param p1 the ending offset in the model &gt;= p0
* @return the X location of the end of the range &gt;= 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 @@ public class PasswordView extends FieldView {
}
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 @@ public class PasswordView extends FieldView {
* @param p1 the ending offset in the model &gt;= p0
* @return the X location of the end of the range &gt;= 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 @@ public class PasswordView extends FieldView {
* @param y the starting Y coordinate &gt;= 0
* @param c the echo character
* @return the updated X position &gt;= 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 @@ public class PasswordView extends FieldView {
* 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 @@ public class PasswordView extends FieldView {
}
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);
}
});
}
}

View File

@ -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
@ -60,17 +63,6 @@ public class PlainView extends View implements TabExpander {
return size;
}
/**
* 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
@ -84,8 +76,16 @@ public class PlainView extends View implements TabExpander {
* @param y the starting Y position &gt;= 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 @@ public class PlainView extends View implements TabExpander {
* {@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 @@ public class PlainView extends View implements TabExpander {
} 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 @@ public class PlainView extends View implements TabExpander {
* @param p1 the ending position in the model &gt;= 0
* @return the X location of the end of the range &gt;= 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 @@ public class PlainView extends View implements TabExpander {
* 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 @@ public class PlainView extends View implements TabExpander {
* @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 @@ public class PlainView extends View implements TabExpander {
* @param p1 the ending position in the model &gt;= 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 @@ public class PlainView extends View implements TabExpander {
* 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 @@ public class PlainView extends View implements TabExpander {
* @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 @@ public class PlainView extends View implements TabExpander {
// 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 @@ public class PlainView extends View implements TabExpander {
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 @@ public class PlainView extends View implements TabExpander {
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 @@ public class PlainView extends View implements TabExpander {
* given point in the view &gt;= 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 @@ public class PlainView extends View implements TabExpander {
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 @@ public class PlainView extends View implements TabExpander {
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 @@ public class PlainView extends View implements TabExpander {
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 @@ public class PlainView extends View implements TabExpander {
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 @@ public class PlainView extends View implements TabExpander {
Font font;
Segment lineBuffer;
int tabSize;
float tabSize;
int tabBase;
int sel0;
@ -796,4 +876,46 @@ public class PlainView extends View implements TabExpander {
*/
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;
}
}

View File

@ -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 @@ public class Utilities {
* tabs will be expanded as a space character.
* @param startOffset starting offset of the text in the document &gt;= 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 @@ public class Utilities {
* 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 @@ public class Utilities {
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 @@ public class Utilities {
&& 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 @@ public class Utilities {
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 @@ public class Utilities {
}
}
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 @@ public class Utilities {
* tabs will be expanded as a space character.
* @param startOffset starting offset of the text in the document &gt;= 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 @@ public class Utilities {
* 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 @@ public class Utilities {
// 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) {
int nextX = x;
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)
{
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 @@ public class Utilities {
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 @@ public class Utilities {
} 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 @@ public class Utilities {
* tabs will be expanded as a space character.
* @param startOffset starting offset of the text in the document &gt;= 0
* @return the offset into the text &gt;= 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 @@ public class Utilities {
int startOffset,
int[] justificationData) {
return getTabbedTextOffset(view, s, metrics, x0, x, e, startOffset, true,
justificationData);
justificationData, false);
}
/**
@ -365,13 +414,19 @@ public class Utilities {
* @param startOffset starting offset of the text in the document &gt;= 0
* @param round whether or not to round
* @return the offset into the text &gt;= 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 @@ public class Utilities {
* @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 @@ public class Utilities {
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 @@ public class Utilities {
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 @@ public class Utilities {
)){
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 @@ public class Utilities {
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 @@ public class Utilities {
} 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 @@ public class Utilities {
* 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 @@ public class Utilities {
* 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 @@ public class Utilities {
* @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 @@ public class Utilities {
* @return the position &gt;= 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 @@ public class Utilities {
* @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 @@ public class Utilities {
* @return the position &gt;= 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 @@ public class Utilities {
* @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 @@ public class Utilities {
*/
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 @@ public class Utilities {
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);
}
/**

View File

@ -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)
@ -86,17 +90,6 @@ public class WrappedPlainView extends BoxView implements TabExpander {
return size;
}
/**
* 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
@ -111,8 +104,17 @@ public class WrappedPlainView extends BoxView implements TabExpander {
* @param y the starting Y position &gt;= 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 @@ public class WrappedPlainView extends BoxView implements TabExpander {
* <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 &gt;= 0
* @param p1 the ending document location to use &gt;= p1
* @param g the graphics context
@ -154,12 +152,17 @@ public class WrappedPlainView extends BoxView implements TabExpander {
* @param y the starting Y position &gt;= 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 @@ public class WrappedPlainView extends BoxView implements TabExpander {
} 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 @@ public class WrappedPlainView extends BoxView implements TabExpander {
* @param p1 the ending position in the model &gt;= p0
* @return the X location of the end of the range &gt;= 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 @@ public class WrappedPlainView extends BoxView implements TabExpander {
* 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 &gt;= 0
* @param y the starting Y coordinate &gt;= 0
@ -232,10 +253,12 @@ public class WrappedPlainView extends BoxView implements TabExpander {
* @param p1 the ending position in the model &gt;= p0
* @return the X location of the end of the range &gt;= 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 @@ public class WrappedPlainView extends BoxView implements TabExpander {
* @param p1 the ending position in the model &gt;= 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 @@ public class WrappedPlainView extends BoxView implements TabExpander {
* 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 &gt;= 0
* @param y the starting Y coordinate &gt;= 0
@ -279,10 +321,12 @@ public class WrappedPlainView extends BoxView implements TabExpander {
* @param p1 the ending position in the model &gt;= 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 @@ public class WrappedPlainView extends BoxView implements TabExpander {
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 class WrappedPlainView extends BoxView implements TabExpander {
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 @@ public class WrappedPlainView extends BoxView implements TabExpander {
Segment lineBuffer;
boolean widthChanging;
int tabBase;
int tabSize;
float tabSize;
boolean wordWrap;
int sel0;
@ -668,6 +718,7 @@ public class WrappedPlainView extends BoxView implements TabExpander {
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 @@ public class WrappedPlainView extends BoxView implements TabExpander {
: 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 @@ public class WrappedPlainView extends BoxView implements TabExpander {
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;
}
}

View File

@ -88,6 +88,9 @@ module java.desktop {
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;

View File

@ -107,7 +107,7 @@ public final class AWTAccessor {
/*
* 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 @@ public final class AWTAccessor {
AWTAccessor.dropTargetContextAccessor = accessor;
}
}
}

View File

@ -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 @@ public class IconInfo {
}
this.scaledWidth = width;
this.scaledHeight = height;
this.rawLength = getScaledRawLength();
this.rawLength = getScaledRawLength(width, height);
}
/*
@ -112,14 +112,14 @@ public class IconInfo {
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;
}

View File

@ -142,8 +142,8 @@ public abstract class KeyboardFocusManagerPeerImpl implements KeyboardFocusManag
}
// 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.

View File

@ -1512,9 +1512,9 @@ public abstract class SunToolkit extends Toolkit
*/
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 @@ public abstract class SunToolkit extends Toolkit
@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

View File

@ -1902,11 +1902,7 @@ public final class SunGraphics2D
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];

View File

@ -28,10 +28,13 @@ package sun.java2d.pipe;
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.
@ -117,6 +120,34 @@ public final class Region {
return newv;
}
/**
* 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
@ -557,6 +588,33 @@ public final class Region {
return getIntersectionXYXY(x, y, dimAdd(x, w), dimAdd(y, h));
}
/**
* 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

View File

@ -30,6 +30,7 @@ import java.awt.*;
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 @@ public class SwingUtilities2 {
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 @@ public class SwingUtilities2 {
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 @@ public class SwingUtilities2 {
}
}
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 @@ public class SwingUtilities2 {
}
}
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 @@ public class SwingUtilities2 {
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 {

View File

@ -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 @@ int SplashStreamInitMemory(SplashStream * pStream, void* pData, int size) {
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);
}

View File

@ -150,7 +150,9 @@ void SplashUpdateScreenData(Splash * splash);
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);

View File

@ -301,7 +301,10 @@ abstract class XDecoratedPeer extends XWindowPeer {
}
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 @@ abstract class XDecoratedPeer extends XWindowPeer {
// 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 @@ abstract class XDecoratedPeer extends XWindowPeer {
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 @@ abstract class XDecoratedPeer extends XWindowPeer {
winAttr.functions = fs;
XWM.setShellResizable(this);
} else if (isResizable() && !resizable) {
currentInsets = new Insets(0, 0, 0, 0);
resetWMSetInsets();
if (!isEmbedded()) {
setReparented(false);

View File

@ -118,6 +118,19 @@ typedef struct {
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 @@ XRROutputInfo * XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources,
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;

View File

@ -1667,6 +1667,11 @@ typedef XRROutputInfo * (*XRRGetOutputInfoType)(Display *dpy,
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 XRRGetScreenResourcesType awt_XRRGetScreenResources;
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 @@ X11GD_InitXrandrFuncs(JNIEnv *env)
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 @@ Java_sun_awt_X11GraphicsDevice_getCurrentDisplayMode
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 @@ Java_sun_awt_X11GraphicsDevice_enumDisplayModes
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;

View File

@ -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)

View File

@ -351,9 +351,6 @@ struct _GtkProgressBar
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 GList* (*fp_g_list_append) (GList *list, gpointer data);
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);

View File

@ -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 @@ static void* dl_symbol(const char* name)
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 @@ GtkApi* gtk3_load(JNIEnv *env, const char* lib_name)
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 @@ GtkApi* gtk3_load(JNIEnv *env, const char* lib_name)
fp_g_path_get_dirname = dl_symbol("g_path_get_dirname");
fp_gdk_threads_enter = &empty;
fp_gdk_threads_leave = &empty;
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 @@ GtkApi* gtk3_load(JNIEnv *env, const char* lib_name)
dlclose(gtk3_libhandle);
gtk3_libhandle = NULL;
dlclose(gthread_libhandle);
gthread_libhandle = NULL;
return NULL;
}
@ -651,6 +671,7 @@ static int gtk3_unload()
dlerror();
dlclose(gtk3_libhandle);
dlclose(gthread_libhandle);
if ((gtk3_error = dlerror()) != NULL)
{
return FALSE;

View File

@ -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 @@ typedef struct GtkApi {
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 */

View File

@ -818,6 +818,32 @@ isXKBenabled(Display *display) {
}
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 @@ isKPevent(XEvent *event)
*/
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 @@ handleKeyEventWithNumLockMask_New(XEvent *event, KeySym *keysym)
}
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 @@ handleKeyEventWithNumLockMask(XEvent *event, KeySym *keysym)
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 @@ handleKeyEventWithNumLockMask(XEvent *event, KeySym *keysym)
}
}
/* This function is called as the keyChar parameter of a call to
* awt_post_java_key_event. It depends on being called after adjustKeySym.
*

View File

@ -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 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_IsXsunKPBehavior
// 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 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XQueryKeymap
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

View File

@ -97,10 +97,7 @@ static gboolean unity_load() {
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 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setNativeMenu
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);

View File

@ -753,6 +753,9 @@ SplashScreenThread(void *param) {
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 @@ SplashGetScaledImageName(const char* jarName, const char* fileName,
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);
}

View File

@ -535,6 +535,9 @@ SplashScreenThread(LPVOID param)
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 @@ SplashGetScaledImageName(const char* jarName, const char* fileName,
*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);
}

View File

@ -41,13 +41,13 @@ import javax.swing.plaf.TreeUI;
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 @@ final public class AccessBridge {
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);

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -156,6 +156,7 @@ public abstract class JSObject {
*/
@Deprecated(since = "9")
@SuppressWarnings("exports")
public static JSObject getWindow(Applet applet) throws JSException {
return ProviderLoader.callGetWindow(applet);
}

View File

@ -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();
}
}
}

View File

@ -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();
}
});
}
}

View File

@ -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);
}
}
}
}

View File

@ -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;
}
}

View File

@ -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 class SubMenuShowTest extends Applet {
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 @@ public class SubMenuShowTest extends Applet {
});
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");

View File

@ -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 class ActionEventTest extends Frame {
public ActionEventTest() {
try {
robot = new Robot();
robot.setAutoDelay(100);
robot.setAutoWaitForIdle(true);
} catch(AWTException e) {
throw new RuntimeException(e.getMessage());
}
@ -56,7 +58,6 @@ public class ActionEventTest extends Frame {
setLayout(new FlowLayout());
pack();
setVisible(true);
robot.waitForIdle();
}
void performTest() {
@ -86,11 +87,9 @@ public class ActionEventTest extends Frame {
// 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[]) {

View File

@ -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>

View File

@ -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 extends Applet
{
public void init()
{
setLayout(new BorderLayout());
public class InvisibleParentTest {
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 );
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);
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 {
setSize (200,200);
setVisible(true);
validate();
mainFrame = new JFrame("InvisibleParentTest");
mainFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
Component c = this;
while ((c != null) && !(c instanceof Window))
{
c = c.getParent();
}
if (c != null)
{
((Window)c).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";
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();
});
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

View File

@ -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");
}
}
}

View File

@ -43,7 +43,7 @@ import sun.java2d.SunGraphics2D;
/**
* @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 @@ public class MultiResolutionSplashTest {
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 @@ public class MultiResolutionSplashTest {
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 @@ public class MultiResolutionSplashTest {
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 @@ public class MultiResolutionSplashTest {
static void testFocus() throws Exception {
System.out.println("Focus Test!");
Robot robot = new Robot();
robot.setAutoDelay(50);
@ -150,18 +139,18 @@ public class MultiResolutionSplashTest {
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 class MultiResolutionSplashTest {
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 @@ public class MultiResolutionSplashTest {
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 class MultiResolutionSplashTest {
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;
}
}
}

View File

@ -44,7 +44,7 @@ import java.util.Map;
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 @@ public class UnixMultiResolutionSplashTest {
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 @@ public class UnixMultiResolutionSplashTest {
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);

View File

@ -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 @@ import java.awt.image.BufferedImage;
/*
* @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 @@ public class TrayIconEventModifiersTest {
mousePressed = false;
robot.keyPress(keyTypes[j]);
robot.waitForIdle();
robot.mousePress(buttonTypes[i]);
if (! mousePressed) {

View File

@ -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();
}
}
}

View File

@ -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);
}
}
}

View File

@ -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());
}
}

View File

@ -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 class WarningWindowDisposeTest {
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();

View File

@ -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);
}
}
}

View File

@ -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");
}
}
}

View File

@ -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()));
}
}

View File

@ -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 @@ import javax.print.attribute.HashPrintRequestAttributeSet;
/*
* @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 @@ public class Services_getDocFl {
pngImagesSupported = false;
gifImagesSupported = false;
jpgImagesSupported = false;
psSupported = false;
for (int j=0; j<flavors.length; j++) {
System.out.println(flavors[j]);

View File

@ -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
}
}
}
}

View File

@ -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 class ScreenMenuBarInputTwice {
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 @@ public class ScreenMenuBarInputTwice {
robot.keyRelease(VK_COMMA);
robot.keyRelease(VK_SHIFT);
robot.keyRelease(VK_META);
robot.delay(2000);
checkText(textArea.getText());
}
@ -198,13 +195,10 @@ public class ScreenMenuBarInputTwice {
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());
}

View File

@ -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 @@ public class ScrollFlickerTest {
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");
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}