mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-20 23:36:18 +00:00
Merge
This commit is contained in:
commit
abea796b35
@ -44,6 +44,7 @@ SUNWprivate_1.1 {
|
||||
SplashSetFileJarName;
|
||||
SplashSetScaleFactor;
|
||||
SplashGetScaledImageName;
|
||||
SplashGetScaledImgNameMaxPstfixLen;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
@ -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\
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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],
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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
|
||||
|
||||
@ -41,6 +41,7 @@ extern jint* gButtonDownMasks;
|
||||
@interface AWTToolkit : NSObject { }
|
||||
+ (long) getEventCount;
|
||||
+ (void) eventCountPlusPlus;
|
||||
+ (jint) scrollStateWithEvent: (NSEvent*) event;
|
||||
@end
|
||||
|
||||
/*
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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];
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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]");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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 >= 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 >= 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;
|
||||
}
|
||||
|
||||
@ -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 >= 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 >= 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) {
|
||||
|
||||
@ -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.
|
||||
*
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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 >= p0
|
||||
* @return the X location of the end of the range >= 0
|
||||
* @exception BadLocationException if p0 or p1 are out of range
|
||||
*
|
||||
* @deprecated replaced by
|
||||
* {@link #drawUnselectedText(Graphics2D, float, float, int, int)}
|
||||
*/
|
||||
@Deprecated(since = "9")
|
||||
@Override
|
||||
protected int drawUnselectedText(Graphics g, int x, int y,
|
||||
int p0, int p1) throws BadLocationException {
|
||||
return (int) drawUnselectedTextImpl(g, x, y, p0, p1, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float drawUnselectedText(Graphics2D g, float x, float y,
|
||||
int p0, int p1)
|
||||
throws BadLocationException
|
||||
{
|
||||
return drawUnselectedTextImpl(g, x, y, p0, p1, true);
|
||||
}
|
||||
|
||||
private float drawUnselectedTextImpl(Graphics g, float x, float y,
|
||||
int p0, int p1,
|
||||
boolean useFPAPI)
|
||||
throws BadLocationException
|
||||
{
|
||||
Container c = getContainer();
|
||||
if (c instanceof JPasswordField) {
|
||||
JPasswordField f = (JPasswordField) c;
|
||||
if (! f.echoCharIsSet()) {
|
||||
return super.drawUnselectedText(g, x, y, p0, p1);
|
||||
if (!f.echoCharIsSet()) {
|
||||
boolean useDrawUnselectedFPAPI = useFPAPI
|
||||
&& drawUnselectedTextOverridden
|
||||
&& g instanceof Graphics2D;
|
||||
return (useDrawUnselectedFPAPI )
|
||||
? super.drawUnselectedText((Graphics2D) g, x, y, p0, p1)
|
||||
: super.drawUnselectedText(g, (int) x, (int) y, p0, p1);
|
||||
}
|
||||
if (f.isEnabled()) {
|
||||
g.setColor(f.getForeground());
|
||||
@ -79,8 +108,13 @@ 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 >= p0
|
||||
* @return the X location of the end of the range >= 0
|
||||
* @exception BadLocationException if p0 or p1 are out of range
|
||||
*
|
||||
* @deprecated replaced by
|
||||
* {@link #drawSelectedText(Graphics2D, float, float, int, int)}
|
||||
*/
|
||||
@Deprecated(since = "9")
|
||||
@Override
|
||||
protected int drawSelectedText(Graphics g, int x,
|
||||
int y, int p0, int p1) throws BadLocationException {
|
||||
return (int) drawSelectedTextImpl(g, x, y, p0, p1, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float drawSelectedText(Graphics2D g, float x, float y,
|
||||
int p0, int p1) throws BadLocationException
|
||||
{
|
||||
return drawSelectedTextImpl(g, x, y, p0, p1, true);
|
||||
}
|
||||
|
||||
private float drawSelectedTextImpl(Graphics g, float x, float y,
|
||||
int p0, int p1,
|
||||
boolean useFPAPI)
|
||||
throws BadLocationException {
|
||||
g.setColor(selected);
|
||||
Container c = getContainer();
|
||||
if (c instanceof JPasswordField) {
|
||||
JPasswordField f = (JPasswordField) c;
|
||||
if (! f.echoCharIsSet()) {
|
||||
return super.drawSelectedText(g, x, y, p0, p1);
|
||||
if (!f.echoCharIsSet()) {
|
||||
boolean useDrawUnselectedFPAPI = useFPAPI
|
||||
&& drawSelectedTextOverridden
|
||||
&& g instanceof Graphics2D;
|
||||
return (useFPAPI)
|
||||
? super.drawSelectedText((Graphics2D) g, x, y, p0, p1)
|
||||
: super.drawSelectedText(g, (int) x, (int) y, p0, p1);
|
||||
}
|
||||
char echoChar = f.getEchoChar();
|
||||
int n = p1 - p0;
|
||||
boolean useEchoCharFPAPI = useFPAPI
|
||||
&& drawEchoCharacterOverridden
|
||||
&& g instanceof Graphics2D;
|
||||
for (int i = 0; i < n; i++) {
|
||||
x = drawEchoCharacter(g, x, y, echoChar);
|
||||
x = (useEchoCharFPAPI)
|
||||
? drawEchoCharacter((Graphics2D) g, x, y, echoChar)
|
||||
: drawEchoCharacter(g, (int) x, (int) y, echoChar);
|
||||
|
||||
}
|
||||
}
|
||||
return x;
|
||||
@ -130,12 +194,13 @@ public class PasswordView extends FieldView {
|
||||
* @param y the starting Y coordinate >= 0
|
||||
* @param c the echo character
|
||||
* @return the updated X position >= 0
|
||||
*
|
||||
* @deprecated replaced by
|
||||
* {@link #drawEchoCharacter(Graphics2D, float, float, char)}
|
||||
*/
|
||||
@Deprecated(since = "9")
|
||||
protected int drawEchoCharacter(Graphics g, int x, int y, char c) {
|
||||
ONE[0] = c;
|
||||
SwingUtilities2.drawChars(Utilities.getJComponent(this),
|
||||
g, ONE, 0, 1, x, y);
|
||||
return x + g.getFontMetrics().charWidth(c);
|
||||
return (int) drawEchoCharacterImpl(g, x, y, c, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,18 +209,29 @@ 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 >= 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 >= 0
|
||||
* @return the X location of the end of the range >= 0
|
||||
* @exception BadLocationException if the range is invalid
|
||||
*
|
||||
* @deprecated replaced by
|
||||
* {@link #drawUnselectedText(Graphics2D, float, float, int, int)}
|
||||
*/
|
||||
@Deprecated(since = "9")
|
||||
protected int drawUnselectedText(Graphics g, int x, int y,
|
||||
int p0, int p1) throws BadLocationException {
|
||||
return (int) drawUnselectedTextImpl(g, x, y, p0, p1, false);
|
||||
}
|
||||
|
||||
private float callDrawUnselectedText(Graphics g, float x, float y,
|
||||
int p0, int p1)
|
||||
throws BadLocationException
|
||||
{
|
||||
return drawUnselectedTextOverridden && (g instanceof Graphics2D)
|
||||
? drawUnselectedText((Graphics2D) g, x, y, p0, p1)
|
||||
: drawUnselectedText(g, (int) x, (int) y, p0, p1);
|
||||
}
|
||||
|
||||
private float drawUnselectedTextImpl(Graphics g, float x, float y,
|
||||
int p0, int p1,
|
||||
boolean useFPAPI)
|
||||
throws BadLocationException
|
||||
{
|
||||
g.setColor(unselected);
|
||||
Document doc = getDocument();
|
||||
Segment s = SegmentCache.getSharedSegment();
|
||||
doc.getText(p0, p1 - p0, s);
|
||||
int ret = Utilities.drawTabbedText(this, s, x, y, g, this, p0);
|
||||
float ret = Utilities.drawTabbedText(this, s, x, y, g, this, p0, null,
|
||||
useFPAPI);
|
||||
SegmentCache.releaseSharedSegment(s);
|
||||
return ret;
|
||||
}
|
||||
@ -194,10 +217,6 @@ 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 >= 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 >= 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 >= 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 >= 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 >= 0
|
||||
* @return the offset into the text >= 0
|
||||
*
|
||||
* @deprecated replaced by
|
||||
* {@link #getTabbedTextOffset(Segment, FontMetrics, float, float,
|
||||
* TabExpander, int, boolean)}
|
||||
*/
|
||||
@Deprecated(since = "9")
|
||||
public static final int getTabbedTextOffset(Segment s, FontMetrics metrics,
|
||||
int x0, int x, TabExpander e,
|
||||
int startOffset) {
|
||||
@ -346,7 +395,7 @@ 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 >= 0
|
||||
* @param round whether or not to round
|
||||
* @return the offset into the text >= 0
|
||||
*
|
||||
* @deprecated replaced by
|
||||
* {@link #getTabbedTextOffset(Segment, FontMetrics, float, float,
|
||||
* TabExpander, int, boolean)}
|
||||
*/
|
||||
@Deprecated(since = "9")
|
||||
public static final int getTabbedTextOffset(Segment s,
|
||||
FontMetrics metrics,
|
||||
int x0, int x, TabExpander e,
|
||||
int startOffset,
|
||||
boolean round) {
|
||||
return getTabbedTextOffset(null, s, metrics, x0, x, e, startOffset, round, null);
|
||||
return getTabbedTextOffset(null, s, metrics, x0, x, e, startOffset,
|
||||
round, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -390,6 +445,8 @@ 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 >= 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 >= 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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 >= 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 >= 0
|
||||
* @param p1 the ending document location to use >= p1
|
||||
* @param g the graphics context
|
||||
@ -154,12 +152,17 @@ public class WrappedPlainView extends BoxView implements TabExpander {
|
||||
* @param y the starting Y position >= 0
|
||||
* @see #drawUnselectedText
|
||||
* @see #drawSelectedText
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
protected void drawLine(int p0, int p1, Graphics2D g, float x, float y) {
|
||||
drawLine(p0, p1, (Graphics) g, (int) x, (int) y);
|
||||
drawLineImpl(p0, p1, g, x, y, true);
|
||||
}
|
||||
|
||||
private int drawText(Element elem, int p0, int p1, Graphics g, int x, int y) throws BadLocationException {
|
||||
private float drawText(Element elem, int p0, int p1, Graphics g,
|
||||
float x, float y)
|
||||
throws BadLocationException
|
||||
{
|
||||
p1 = Math.min(getDocument().getLength(), p1);
|
||||
AttributeSet attr = elem.getAttributes();
|
||||
|
||||
@ -171,23 +174,23 @@ 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 >= p0
|
||||
* @return the X location of the end of the range >= 0
|
||||
* @exception BadLocationException if the range is invalid
|
||||
*
|
||||
* @deprecated replaced by
|
||||
* {@link #drawUnselectedText(Graphics2D, float, float, int, int)}
|
||||
*/
|
||||
@Deprecated(since = "9")
|
||||
protected int drawUnselectedText(Graphics g, int x, int y,
|
||||
int p0, int p1) throws BadLocationException {
|
||||
int p0, int p1) throws BadLocationException
|
||||
{
|
||||
return (int) drawUnselectedTextImpl(g, x, y, p0, p1, false);
|
||||
}
|
||||
|
||||
private float callDrawUnselectedText(Graphics g, float x, float y,
|
||||
int p0, int p1)
|
||||
throws BadLocationException
|
||||
{
|
||||
return drawUnselectedTextOverridden && g instanceof Graphics2D
|
||||
? drawUnselectedText((Graphics2D) g, x, y, p0, p1)
|
||||
: drawUnselectedText(g, (int) x, (int) y, p0, p1);
|
||||
}
|
||||
|
||||
private float drawUnselectedTextImpl(Graphics g, float x, float y,
|
||||
int p0, int p1, boolean useFPAPI)
|
||||
throws BadLocationException
|
||||
{
|
||||
g.setColor(unselected);
|
||||
Document doc = getDocument();
|
||||
Segment segment = SegmentCache.getSharedSegment();
|
||||
doc.getText(p0, p1 - p0, segment);
|
||||
int ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0);
|
||||
float ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0,
|
||||
null, useFPAPI);
|
||||
SegmentCache.releaseSharedSegment(segment);
|
||||
return ret;
|
||||
}
|
||||
@ -221,10 +246,6 @@ 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 >= 0
|
||||
* @param y the starting Y coordinate >= 0
|
||||
@ -232,10 +253,12 @@ public class WrappedPlainView extends BoxView implements TabExpander {
|
||||
* @param p1 the ending position in the model >= p0
|
||||
* @return the X location of the end of the range >= 0
|
||||
* @exception BadLocationException if the range is invalid
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
protected float drawUnselectedText(Graphics2D g, float x, float y,
|
||||
int p0, int p1) throws BadLocationException {
|
||||
return drawUnselectedText((Graphics) g, (int) x, (int) y, p0, p1);
|
||||
return drawUnselectedTextImpl(g, x, y, p0, p1, true);
|
||||
}
|
||||
/**
|
||||
* Renders the given range in the model as selected text. This
|
||||
@ -250,14 +273,37 @@ public class WrappedPlainView extends BoxView implements TabExpander {
|
||||
* @param p1 the ending position in the model >= p0
|
||||
* @return the location of the end of the range.
|
||||
* @exception BadLocationException if the range is invalid
|
||||
*
|
||||
* @deprecated replaced by
|
||||
* {@link #drawSelectedText(Graphics2D, float, float, int, int)}
|
||||
*/
|
||||
protected int drawSelectedText(Graphics g, int x,
|
||||
int y, int p0, int p1) throws BadLocationException {
|
||||
@Deprecated(since = "9")
|
||||
protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1)
|
||||
throws BadLocationException
|
||||
{
|
||||
return (int) drawSelectedTextImpl(g, x, y, p0, p1, false);
|
||||
}
|
||||
|
||||
private float callDrawSelectedText(Graphics g, float x, float y,
|
||||
int p0, int p1)
|
||||
throws BadLocationException
|
||||
{
|
||||
return drawSelectedTextOverridden && g instanceof Graphics2D
|
||||
? drawSelectedText((Graphics2D) g, x, y, p0, p1)
|
||||
: drawSelectedText(g, (int) x, (int) y, p0, p1);
|
||||
}
|
||||
|
||||
private float drawSelectedTextImpl(Graphics g, float x, float y,
|
||||
int p0, int p1,
|
||||
boolean useFPAPI)
|
||||
throws BadLocationException
|
||||
{
|
||||
g.setColor(selected);
|
||||
Document doc = getDocument();
|
||||
Segment segment = SegmentCache.getSharedSegment();
|
||||
doc.getText(p0, p1 - p0, segment);
|
||||
int ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0);
|
||||
float ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0,
|
||||
null, useFPAPI);
|
||||
SegmentCache.releaseSharedSegment(segment);
|
||||
return ret;
|
||||
}
|
||||
@ -268,10 +314,6 @@ 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 >= 0
|
||||
* @param y the starting Y coordinate >= 0
|
||||
@ -279,10 +321,12 @@ public class WrappedPlainView extends BoxView implements TabExpander {
|
||||
* @param p1 the ending position in the model >= p0
|
||||
* @return the location of the end of the range.
|
||||
* @exception BadLocationException if the range is invalid
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
protected float drawSelectedText(Graphics2D g, float x, float y,
|
||||
int p0, int p1) throws BadLocationException {
|
||||
return drawSelectedText((Graphics) g, (int) x, (int) y, p0, p1);
|
||||
return drawSelectedTextImpl(g, x, y, p0, p1, true);
|
||||
}
|
||||
/**
|
||||
* Gives access to a buffer that can be used to fetch
|
||||
@ -395,7 +439,13 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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 = ∅
|
||||
fp_gdk_threads_leave = ∅
|
||||
fp_gdk_threads_enter = dl_symbol("gdk_threads_enter");
|
||||
fp_gdk_threads_leave = dl_symbol("gdk_threads_leave");
|
||||
|
||||
/**
|
||||
* Functions for sun_awt_X11_GtkFileDialogPeer.c
|
||||
@ -556,6 +573,9 @@ 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;
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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.
|
||||
*
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
95
jdk/src/jdk.desktop/share/classes/jdk/awt/AWTUtils.java
Normal file
95
jdk/src/jdk.desktop/share/classes/jdk/awt/AWTUtils.java
Normal 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);
|
||||
}
|
||||
}
|
||||
34
jdk/src/jdk.desktop/share/classes/module-info.java
Normal file
34
jdk/src/jdk.desktop/share/classes/module-info.java
Normal 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;
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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");
|
||||
|
||||
@ -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[]) {
|
||||
|
||||
@ -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>
|
||||
@ -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
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
92
jdk/test/java/awt/event/KeyEvent/RobotCrash/RobotCrash.java
Normal file
92
jdk/test/java/awt/event/KeyEvent/RobotCrash/RobotCrash.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
59
jdk/test/java/awt/jdk/TestJDKAWTUtils.java
Normal file
59
jdk/test/java/awt/jdk/TestJDKAWTUtils.java
Normal 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());
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
|
||||
|
||||
71
jdk/test/javax/imageio/ImageCompressionTypesTest.java
Normal file
71
jdk/test/javax/imageio/ImageCompressionTypesTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
77
jdk/test/javax/imageio/metadata/NthItemNodeListTest.java
Normal file
77
jdk/test/javax/imageio/metadata/NthItemNodeListTest.java
Normal 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()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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]);
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
189
jdk/test/javax/swing/plaf/motif/8165485/MotifHiDPIIconsTest.java
Normal file
189
jdk/test/javax/swing/plaf/motif/8165485/MotifHiDPIIconsTest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
499
jdk/test/javax/swing/text/View/8156217/FPMethodCalledTest.java
Normal file
499
jdk/test/javax/swing/text/View/8156217/FPMethodCalledTest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user