Merge
This commit is contained in:
commit
b1415f3d2d
@ -85,3 +85,13 @@ vpath %.c $(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen
|
|||||||
CPPFLAGS += -I$(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen -I$(SHARE_SRC)/native/$(PKGDIR)/splashscreen
|
CPPFLAGS += -I$(PLATFORM_SRC)/native/$(PKGDIR)/splashscreen -I$(SHARE_SRC)/native/$(PKGDIR)/splashscreen
|
||||||
CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR)/image/jpeg -I$(SHARE_SRC)/native/java/util/zip/zlib-1.1.3
|
CPPFLAGS += -I$(SHARE_SRC)/native/$(PKGDIR)/image/jpeg -I$(SHARE_SRC)/native/java/util/zip/zlib-1.1.3
|
||||||
|
|
||||||
|
ifeq ($(PLATFORM), linux)
|
||||||
|
ifeq ($(ARCH_DATA_MODEL), 64)
|
||||||
|
# 64-bit gcc has problems compiling MMX instructions.
|
||||||
|
# Google it for more details. Possibly the newer versions of
|
||||||
|
# the PNG-library and/or the new compiler will not need this
|
||||||
|
# option in the future.
|
||||||
|
CPPFLAGS += -DPNG_NO_MMX_CODE
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -260,6 +260,7 @@ generated.clean:
|
|||||||
$(RM) -r $(WRAPPER_GENERATOR_TEMPDIR)
|
$(RM) -r $(WRAPPER_GENERATOR_TEMPDIR)
|
||||||
$(RM) -r $(WRAPPER_GENERATOR_DIR)
|
$(RM) -r $(WRAPPER_GENERATOR_DIR)
|
||||||
$(RM) -r $(GEN_DIR)/*.java
|
$(RM) -r $(GEN_DIR)/*.java
|
||||||
|
$(RM) -r $(TEMPDIR)/.gen_icons
|
||||||
|
|
||||||
ifdef OPENJDK
|
ifdef OPENJDK
|
||||||
ICONS_PATH_PREFIX=$(PLATFORM_SRC)
|
ICONS_PATH_PREFIX=$(PLATFORM_SRC)
|
||||||
|
@ -634,6 +634,11 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
*/
|
*/
|
||||||
private PropertyChangeSupport changeSupport;
|
private PropertyChangeSupport changeSupport;
|
||||||
|
|
||||||
|
private transient final Object changeSupportLock = new Object();
|
||||||
|
private Object getChangeSupportLock() {
|
||||||
|
return changeSupportLock;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isPacked = false;
|
boolean isPacked = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -935,24 +940,26 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
*/
|
*/
|
||||||
public GraphicsConfiguration getGraphicsConfiguration() {
|
public GraphicsConfiguration getGraphicsConfiguration() {
|
||||||
synchronized(getTreeLock()) {
|
synchronized(getTreeLock()) {
|
||||||
GraphicsConfiguration gc = graphicsConfig;
|
if (graphicsConfig != null) {
|
||||||
Component parent = getParent();
|
return graphicsConfig;
|
||||||
while ((gc == null) && (parent != null)) {
|
} else if (getParent() != null) {
|
||||||
gc = parent.getGraphicsConfiguration();
|
return getParent().getGraphicsConfiguration();
|
||||||
parent = parent.getParent();
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return gc;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {
|
final GraphicsConfiguration getGraphicsConfiguration_NoClientCode() {
|
||||||
GraphicsConfiguration gc = this.graphicsConfig;
|
GraphicsConfiguration graphicsConfig = this.graphicsConfig;
|
||||||
Component par = this.parent;
|
Container parent = this.parent;
|
||||||
while ((gc == null) && (par != null)) {
|
if (graphicsConfig != null) {
|
||||||
gc = par.getGraphicsConfiguration_NoClientCode();
|
return graphicsConfig;
|
||||||
par = par.parent;
|
} else if (parent != null) {
|
||||||
|
return parent.getGraphicsConfiguration_NoClientCode();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return gc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4602,7 +4609,8 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
e.isPopupTrigger(),
|
e.isPopupTrigger(),
|
||||||
e.getScrollType(),
|
e.getScrollType(),
|
||||||
e.getScrollAmount(),
|
e.getScrollAmount(),
|
||||||
e.getWheelRotation());
|
e.getWheelRotation(),
|
||||||
|
e.getPreciseWheelRotation());
|
||||||
((AWTEvent)e).copyPrivateDataInto(newMWE);
|
((AWTEvent)e).copyPrivateDataInto(newMWE);
|
||||||
// When dispatching a wheel event to
|
// When dispatching a wheel event to
|
||||||
// ancestor, there is no need trying to find descendant
|
// ancestor, there is no need trying to find descendant
|
||||||
@ -6484,7 +6492,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
// will need some help.
|
// will need some help.
|
||||||
Container parent = this.parent;
|
Container parent = this.parent;
|
||||||
if (parent != null && parent.peer instanceof LightweightPeer) {
|
if (parent != null && parent.peer instanceof LightweightPeer) {
|
||||||
nativeInLightFixer = new NativeInLightFixer();
|
relocateComponent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
invalidate();
|
invalidate();
|
||||||
@ -6595,10 +6603,6 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nativeInLightFixer != null) {
|
|
||||||
nativeInLightFixer.uninstall();
|
|
||||||
}
|
|
||||||
|
|
||||||
ComponentPeer p = peer;
|
ComponentPeer p = peer;
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
boolean isLightweight = isLightweight();
|
boolean isLightweight = isLightweight();
|
||||||
@ -7836,8 +7840,9 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
* @see #getPropertyChangeListeners
|
* @see #getPropertyChangeListeners
|
||||||
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
||||||
*/
|
*/
|
||||||
public synchronized void addPropertyChangeListener(
|
public void addPropertyChangeListener(
|
||||||
PropertyChangeListener listener) {
|
PropertyChangeListener listener) {
|
||||||
|
synchronized (getChangeSupportLock()) {
|
||||||
if (listener == null) {
|
if (listener == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -7846,6 +7851,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
}
|
}
|
||||||
changeSupport.addPropertyChangeListener(listener);
|
changeSupport.addPropertyChangeListener(listener);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a PropertyChangeListener from the listener list. This method
|
* Removes a PropertyChangeListener from the listener list. This method
|
||||||
@ -7860,13 +7866,15 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
* @see #getPropertyChangeListeners
|
* @see #getPropertyChangeListeners
|
||||||
* @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
|
* @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
|
||||||
*/
|
*/
|
||||||
public synchronized void removePropertyChangeListener(
|
public void removePropertyChangeListener(
|
||||||
PropertyChangeListener listener) {
|
PropertyChangeListener listener) {
|
||||||
|
synchronized (getChangeSupportLock()) {
|
||||||
if (listener == null || changeSupport == null) {
|
if (listener == null || changeSupport == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
changeSupport.removePropertyChangeListener(listener);
|
changeSupport.removePropertyChangeListener(listener);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of all the property change listeners
|
* Returns an array of all the property change listeners
|
||||||
@ -7882,12 +7890,14 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
* @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
|
* @see java.beans.PropertyChangeSupport#getPropertyChangeListeners
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
|
public PropertyChangeListener[] getPropertyChangeListeners() {
|
||||||
|
synchronized (getChangeSupportLock()) {
|
||||||
if (changeSupport == null) {
|
if (changeSupport == null) {
|
||||||
return new PropertyChangeListener[0];
|
return new PropertyChangeListener[0];
|
||||||
}
|
}
|
||||||
return changeSupport.getPropertyChangeListeners();
|
return changeSupport.getPropertyChangeListeners();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a PropertyChangeListener to the listener list for a specific
|
* Adds a PropertyChangeListener to the listener list for a specific
|
||||||
@ -7920,9 +7930,10 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
* @see #getPropertyChangeListeners(java.lang.String)
|
* @see #getPropertyChangeListeners(java.lang.String)
|
||||||
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
* @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
|
||||||
*/
|
*/
|
||||||
public synchronized void addPropertyChangeListener(
|
public void addPropertyChangeListener(
|
||||||
String propertyName,
|
String propertyName,
|
||||||
PropertyChangeListener listener) {
|
PropertyChangeListener listener) {
|
||||||
|
synchronized (getChangeSupportLock()) {
|
||||||
if (listener == null) {
|
if (listener == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -7931,6 +7942,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
}
|
}
|
||||||
changeSupport.addPropertyChangeListener(propertyName, listener);
|
changeSupport.addPropertyChangeListener(propertyName, listener);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a <code>PropertyChangeListener</code> from the listener
|
* Removes a <code>PropertyChangeListener</code> from the listener
|
||||||
@ -7948,14 +7960,16 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
* @see #getPropertyChangeListeners(java.lang.String)
|
* @see #getPropertyChangeListeners(java.lang.String)
|
||||||
* @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
|
* @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
|
||||||
*/
|
*/
|
||||||
public synchronized void removePropertyChangeListener(
|
public void removePropertyChangeListener(
|
||||||
String propertyName,
|
String propertyName,
|
||||||
PropertyChangeListener listener) {
|
PropertyChangeListener listener) {
|
||||||
|
synchronized (getChangeSupportLock()) {
|
||||||
if (listener == null || changeSupport == null) {
|
if (listener == null || changeSupport == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
changeSupport.removePropertyChangeListener(propertyName, listener);
|
changeSupport.removePropertyChangeListener(propertyName, listener);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of all the listeners which have been associated
|
* Returns an array of all the listeners which have been associated
|
||||||
@ -7971,13 +7985,15 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
* @see #getPropertyChangeListeners
|
* @see #getPropertyChangeListeners
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public synchronized PropertyChangeListener[] getPropertyChangeListeners(
|
public PropertyChangeListener[] getPropertyChangeListeners(
|
||||||
String propertyName) {
|
String propertyName) {
|
||||||
|
synchronized (getChangeSupportLock()) {
|
||||||
if (changeSupport == null) {
|
if (changeSupport == null) {
|
||||||
return new PropertyChangeListener[0];
|
return new PropertyChangeListener[0];
|
||||||
}
|
}
|
||||||
return changeSupport.getPropertyChangeListeners(propertyName);
|
return changeSupport.getPropertyChangeListeners(propertyName);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for reporting bound property changes for Object properties.
|
* Support for reporting bound property changes for Object properties.
|
||||||
@ -7991,7 +8007,10 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
*/
|
*/
|
||||||
protected void firePropertyChange(String propertyName,
|
protected void firePropertyChange(String propertyName,
|
||||||
Object oldValue, Object newValue) {
|
Object oldValue, Object newValue) {
|
||||||
PropertyChangeSupport changeSupport = this.changeSupport;
|
PropertyChangeSupport changeSupport;
|
||||||
|
synchronized (getChangeSupportLock()) {
|
||||||
|
changeSupport = this.changeSupport;
|
||||||
|
}
|
||||||
if (changeSupport == null ||
|
if (changeSupport == null ||
|
||||||
(oldValue != null && newValue != null && oldValue.equals(newValue))) {
|
(oldValue != null && newValue != null && oldValue.equals(newValue))) {
|
||||||
return;
|
return;
|
||||||
@ -8491,8 +8510,6 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
setComponentOrientation(orientation);
|
setComponentOrientation(orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
transient NativeInLightFixer nativeInLightFixer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks that this component meets the prerequesites to be focus owner:
|
* Checks that this component meets the prerequesites to be focus owner:
|
||||||
* - it is enabled, visible, focusable
|
* - it is enabled, visible, focusable
|
||||||
@ -8518,189 +8535,26 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This odd class is to help out a native component that has been
|
* Fix the location of the HW component in a LW container hierarchy.
|
||||||
* embedded in a lightweight component. Moving lightweight
|
|
||||||
* components around and changing their visibility is not seen
|
|
||||||
* by the native window system. This is a feature for lightweights,
|
|
||||||
* but a problem for native components that depend upon the
|
|
||||||
* lightweights. An instance of this class listens to the lightweight
|
|
||||||
* parents of an associated native component (the outer class).
|
|
||||||
*
|
|
||||||
* @author Timothy Prinzing
|
|
||||||
*/
|
*/
|
||||||
final class NativeInLightFixer implements ComponentListener, ContainerListener {
|
final void relocateComponent() {
|
||||||
|
|
||||||
NativeInLightFixer() {
|
|
||||||
lightParents = new Vector();
|
|
||||||
install(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void install(Container parent) {
|
|
||||||
lightParents.clear();
|
|
||||||
Container p = parent;
|
|
||||||
boolean isLwParentsVisible = true;
|
|
||||||
// stash a reference to the components that are being observed so that
|
|
||||||
// we can reliably remove ourself as a listener later.
|
|
||||||
for (; p.peer instanceof LightweightPeer; p = p.parent) {
|
|
||||||
|
|
||||||
// register listeners and stash a reference
|
|
||||||
p.addComponentListener(this);
|
|
||||||
p.addContainerListener(this);
|
|
||||||
lightParents.addElement(p);
|
|
||||||
isLwParentsVisible &= p.isVisible();
|
|
||||||
}
|
|
||||||
// register with the native host (native parent of associated native)
|
|
||||||
// to get notified if the top-level lightweight is removed.
|
|
||||||
nativeHost = p;
|
|
||||||
p.addContainerListener(this);
|
|
||||||
|
|
||||||
// kick start the fixup. Since the event isn't looked at
|
|
||||||
// we can simulate movement notification.
|
|
||||||
componentMoved(null);
|
|
||||||
if (!isLwParentsVisible) {
|
|
||||||
synchronized (getTreeLock()) {
|
synchronized (getTreeLock()) {
|
||||||
if (peer != null) {
|
if (peer == null) {
|
||||||
peer.hide();
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void uninstall() {
|
|
||||||
if (nativeHost != null) {
|
|
||||||
removeReferences();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- ComponentListener -------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when one of the lightweight parents has been resized.
|
|
||||||
* This doesn't change the position of the native child so it
|
|
||||||
* is ignored.
|
|
||||||
*/
|
|
||||||
public void componentResized(ComponentEvent e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when one of the lightweight parents has been moved.
|
|
||||||
* The native peer must be told of the new position which is
|
|
||||||
* relative to the native container that is hosting the
|
|
||||||
* lightweight components.
|
|
||||||
*/
|
|
||||||
public void componentMoved(ComponentEvent e) {
|
|
||||||
synchronized (getTreeLock()) {
|
|
||||||
int nativeX = x;
|
int nativeX = x;
|
||||||
int nativeY = y;
|
int nativeY = y;
|
||||||
for(Component c = parent; (c != null) &&
|
for (Component cont = getContainer();
|
||||||
(c.peer instanceof LightweightPeer);
|
cont != null && cont.isLightweight();
|
||||||
c = c.parent) {
|
cont = cont.getContainer())
|
||||||
|
{
|
||||||
nativeX += c.x;
|
nativeX += cont.x;
|
||||||
nativeY += c.y;
|
nativeY += cont.y;
|
||||||
}
|
}
|
||||||
if (peer != null) {
|
|
||||||
peer.setBounds(nativeX, nativeY, width, height,
|
peer.setBounds(nativeX, nativeY, width, height,
|
||||||
ComponentPeer.SET_LOCATION);
|
ComponentPeer.SET_LOCATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when a lightweight parent component has been
|
|
||||||
* shown. The associated native component must also be
|
|
||||||
* shown if it hasn't had an overriding hide done on it.
|
|
||||||
*/
|
|
||||||
public void componentShown(ComponentEvent e) {
|
|
||||||
if (shouldShow()) {
|
|
||||||
synchronized (getTreeLock()) {
|
|
||||||
if (peer != null) {
|
|
||||||
peer.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when one of the lightweight parents become visible.
|
|
||||||
* Returns true if component and all its lightweight
|
|
||||||
* parents are visible.
|
|
||||||
*/
|
|
||||||
private boolean shouldShow() {
|
|
||||||
boolean isLwParentsVisible = visible;
|
|
||||||
for (int i = lightParents.size() - 1;
|
|
||||||
i >= 0 && isLwParentsVisible;
|
|
||||||
i--)
|
|
||||||
{
|
|
||||||
isLwParentsVisible &=
|
|
||||||
((Container) lightParents.elementAt(i)).isVisible();
|
|
||||||
}
|
|
||||||
return isLwParentsVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when component has been hidden.
|
|
||||||
*/
|
|
||||||
public void componentHidden(ComponentEvent e) {
|
|
||||||
if (visible) {
|
|
||||||
synchronized (getTreeLock()) {
|
|
||||||
if (peer != null) {
|
|
||||||
peer.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- ContainerListener ------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when a component has been added to a lightweight
|
|
||||||
* parent. This doesn't effect the native component.
|
|
||||||
*/
|
|
||||||
public void componentAdded(ContainerEvent e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when a lightweight parent has been removed.
|
|
||||||
* This means the services of this listener are no longer
|
|
||||||
* required and it should remove all references (ie
|
|
||||||
* registered listeners).
|
|
||||||
*/
|
|
||||||
public void componentRemoved(ContainerEvent e) {
|
|
||||||
Component c = e.getChild();
|
|
||||||
if (c == Component.this) {
|
|
||||||
removeReferences();
|
|
||||||
} else {
|
|
||||||
int n = lightParents.size();
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
Container p = (Container) lightParents.elementAt(i);
|
|
||||||
if (p == c) {
|
|
||||||
removeReferences();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes references to this object so it can be
|
|
||||||
* garbage collected.
|
|
||||||
*/
|
|
||||||
void removeReferences() {
|
|
||||||
int n = lightParents.size();
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
Container c = (Container) lightParents.elementAt(i);
|
|
||||||
c.removeComponentListener(this);
|
|
||||||
c.removeContainerListener(this);
|
|
||||||
}
|
|
||||||
nativeHost.removeContainerListener(this);
|
|
||||||
lightParents.clear();
|
|
||||||
nativeHost = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector lightParents;
|
|
||||||
Container nativeHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the <code>Window</code> ancestor of the component.
|
* Returns the <code>Window</code> ancestor of the component.
|
||||||
@ -9452,6 +9306,19 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
|
|
||||||
// ************************** MIXING CODE *******************************
|
// ************************** MIXING CODE *******************************
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether we can trust the current bounds of the component.
|
||||||
|
* The return value of false indicates that the container of the
|
||||||
|
* component is invalid, and therefore needs to be layed out, which would
|
||||||
|
* probably mean changing the bounds of its children.
|
||||||
|
* Null-layout of the container or absence of the container mean
|
||||||
|
* the bounds of the component are final and can be trusted.
|
||||||
|
*/
|
||||||
|
private boolean areBoundsValid() {
|
||||||
|
Container cont = getContainer();
|
||||||
|
return cont == null || cont.isValid() || cont.getLayout() == null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the shape to the component
|
* Applies the shape to the component
|
||||||
* @param shape Shape to be applied to the component
|
* @param shape Shape to be applied to the component
|
||||||
@ -9475,7 +9342,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
// to modify the object outside of the mixing code.
|
// to modify the object outside of the mixing code.
|
||||||
this.compoundShape = shape;
|
this.compoundShape = shape;
|
||||||
|
|
||||||
if (isValid()) {
|
if (areBoundsValid()) {
|
||||||
Point compAbsolute = getLocationOnWindow();
|
Point compAbsolute = getLocationOnWindow();
|
||||||
|
|
||||||
if (mixingLog.isLoggable(Level.FINER)) {
|
if (mixingLog.isLoggable(Level.FINER)) {
|
||||||
@ -9602,7 +9469,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
|||||||
|
|
||||||
void applyCurrentShape() {
|
void applyCurrentShape() {
|
||||||
checkTreeLock();
|
checkTreeLock();
|
||||||
if (!isValid()) {
|
if (!areBoundsValid()) {
|
||||||
return; // Because applyCompoundShape() ignores such components anyway
|
return; // Because applyCompoundShape() ignores such components anyway
|
||||||
}
|
}
|
||||||
if (mixingLog.isLoggable(Level.FINE)) {
|
if (mixingLog.isLoggable(Level.FINE)) {
|
||||||
|
@ -832,16 +832,8 @@ public class Container extends Component {
|
|||||||
}
|
}
|
||||||
if (!comp.isLightweight() && isLightweight()) {
|
if (!comp.isLightweight() && isLightweight()) {
|
||||||
// If component is heavyweight and one of the containers is lightweight
|
// If component is heavyweight and one of the containers is lightweight
|
||||||
// some NativeInLightFixer activity should be performed
|
// the location of the component should be fixed.
|
||||||
if (!curParent.isLightweight()) {
|
comp.relocateComponent();
|
||||||
// Moving from heavyweight container to lightweight container - should create NativeInLightFixer
|
|
||||||
// since addNotify does this
|
|
||||||
comp.nativeInLightFixer = new NativeInLightFixer();
|
|
||||||
} else {
|
|
||||||
// Component already has NativeInLightFixer - just reinstall it
|
|
||||||
// because hierarchy changed and he needs to rebuild list of parents to listen.
|
|
||||||
comp.nativeInLightFixer.install(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2267,6 +2259,7 @@ public class Container extends Component {
|
|||||||
EventTargetFilter filter,
|
EventTargetFilter filter,
|
||||||
boolean searchHeavyweightChildren,
|
boolean searchHeavyweightChildren,
|
||||||
boolean searchHeavyweightDescendants) {
|
boolean searchHeavyweightDescendants) {
|
||||||
|
synchronized (getTreeLock()) {
|
||||||
int ncomponents = this.ncomponents;
|
int ncomponents = this.ncomponents;
|
||||||
Component component[] = this.component;
|
Component component[] = this.component;
|
||||||
|
|
||||||
@ -2279,11 +2272,12 @@ public class Container extends Component {
|
|||||||
!(comp.peer instanceof LightweightPeer))) &&
|
!(comp.peer instanceof LightweightPeer))) &&
|
||||||
comp.contains(x - comp.x, y - comp.y)) {
|
comp.contains(x - comp.x, y - comp.y)) {
|
||||||
|
|
||||||
// found a component that intersects the point, see if there is
|
// found a component that intersects the point, see if there
|
||||||
// a deeper possibility.
|
// is a deeper possibility.
|
||||||
if (comp instanceof Container) {
|
if (comp instanceof Container) {
|
||||||
Container child = (Container) comp;
|
Container child = (Container) comp;
|
||||||
Component deeper = child.getMouseEventTarget(x - child.x,
|
Component deeper = child.getMouseEventTarget(
|
||||||
|
x - child.x,
|
||||||
y - child.y,
|
y - child.y,
|
||||||
includeSelf,
|
includeSelf,
|
||||||
filter,
|
filter,
|
||||||
@ -2293,8 +2287,8 @@ public class Container extends Component {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (filter.accept(comp)) {
|
if (filter.accept(comp)) {
|
||||||
// there isn't a deeper target, but this component is a
|
// there isn't a deeper target, but this component
|
||||||
// target
|
// is a target
|
||||||
return comp;
|
return comp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2307,14 +2301,15 @@ public class Container extends Component {
|
|||||||
isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
|
isPeerOK = (peer instanceof LightweightPeer) || includeSelf;
|
||||||
isMouseOverMe = contains(x,y);
|
isMouseOverMe = contains(x,y);
|
||||||
|
|
||||||
// didn't find a child target, return this component if it's a possible
|
// didn't find a child target, return this component if it's
|
||||||
// target
|
// a possible target
|
||||||
if (isMouseOverMe && isPeerOK && filter.accept(this)) {
|
if (isMouseOverMe && isPeerOK && filter.accept(this)) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
// no possible target
|
// no possible target
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static interface EventTargetFilter {
|
static interface EventTargetFilter {
|
||||||
boolean accept(final Component comp);
|
boolean accept(final Component comp);
|
||||||
@ -3950,6 +3945,83 @@ public class Container extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void recursiveShowHeavyweightChildren() {
|
||||||
|
if (!hasHeavyweightDescendants() || !isVisible()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int index = 0; index < getComponentCount(); index++) {
|
||||||
|
Component comp = getComponent(index);
|
||||||
|
if (comp.isLightweight()) {
|
||||||
|
if (comp instanceof Container) {
|
||||||
|
((Container)comp).recursiveShowHeavyweightChildren();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (comp.isVisible()) {
|
||||||
|
ComponentPeer peer = comp.getPeer();
|
||||||
|
if (peer != null) {
|
||||||
|
peer.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recursiveHideHeavyweightChildren() {
|
||||||
|
if (!hasHeavyweightDescendants()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int index = 0; index < getComponentCount(); index++) {
|
||||||
|
Component comp = getComponent(index);
|
||||||
|
if (comp.isLightweight()) {
|
||||||
|
if (comp instanceof Container) {
|
||||||
|
((Container)comp).recursiveHideHeavyweightChildren();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (comp.isVisible()) {
|
||||||
|
ComponentPeer peer = comp.getPeer();
|
||||||
|
if (peer != null) {
|
||||||
|
peer.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recursiveRelocateHeavyweightChildren(Point origin) {
|
||||||
|
for (int index = 0; index < getComponentCount(); index++) {
|
||||||
|
Component comp = getComponent(index);
|
||||||
|
if (comp.isLightweight()) {
|
||||||
|
if (comp instanceof Container &&
|
||||||
|
((Container)comp).hasHeavyweightDescendants())
|
||||||
|
{
|
||||||
|
final Point newOrigin = new Point(origin);
|
||||||
|
newOrigin.translate(comp.getX(), comp.getY());
|
||||||
|
((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ComponentPeer peer = comp.getPeer();
|
||||||
|
if (peer != null) {
|
||||||
|
peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(),
|
||||||
|
comp.getWidth(), comp.getHeight(),
|
||||||
|
ComponentPeer.SET_LOCATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Consider the heavyweight container hides or shows the HW descendants
|
||||||
|
* automatically. Therefore we care of LW containers' visibility only.
|
||||||
|
*/
|
||||||
|
private boolean isRecursivelyVisibleUpToHeavyweightContainer() {
|
||||||
|
if (!isLightweight()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return isVisible() && (getContainer() == null ||
|
||||||
|
getContainer().isRecursivelyVisibleUpToHeavyweightContainer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
void mixOnShowing() {
|
void mixOnShowing() {
|
||||||
synchronized (getTreeLock()) {
|
synchronized (getTreeLock()) {
|
||||||
if (mixingLog.isLoggable(Level.FINE)) {
|
if (mixingLog.isLoggable(Level.FINE)) {
|
||||||
@ -3958,6 +4030,10 @@ public class Container extends Component {
|
|||||||
|
|
||||||
boolean isLightweight = isLightweight();
|
boolean isLightweight = isLightweight();
|
||||||
|
|
||||||
|
if (isLightweight && isRecursivelyVisibleUpToHeavyweightContainer()) {
|
||||||
|
recursiveShowHeavyweightChildren();
|
||||||
|
}
|
||||||
|
|
||||||
if (!isLightweight || (isLightweight && hasHeavyweightDescendants())) {
|
if (!isLightweight || (isLightweight && hasHeavyweightDescendants())) {
|
||||||
recursiveApplyCurrentShape();
|
recursiveApplyCurrentShape();
|
||||||
}
|
}
|
||||||
@ -3966,6 +4042,42 @@ public class Container extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void mixOnHiding(boolean isLightweight) {
|
||||||
|
synchronized (getTreeLock()) {
|
||||||
|
if (mixingLog.isLoggable(Level.FINE)) {
|
||||||
|
mixingLog.fine("this = " + this +
|
||||||
|
"; isLightweight=" + isLightweight);
|
||||||
|
}
|
||||||
|
if (isLightweight) {
|
||||||
|
recursiveHideHeavyweightChildren();
|
||||||
|
}
|
||||||
|
super.mixOnHiding(isLightweight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void mixOnReshaping() {
|
||||||
|
synchronized (getTreeLock()) {
|
||||||
|
if (mixingLog.isLoggable(Level.FINE)) {
|
||||||
|
mixingLog.fine("this = " + this);
|
||||||
|
}
|
||||||
|
if (isLightweight() && hasHeavyweightDescendants()) {
|
||||||
|
final Point origin = new Point(getX(), getY());
|
||||||
|
for (Container cont = getContainer();
|
||||||
|
cont != null && cont.isLightweight();
|
||||||
|
cont = cont.getContainer())
|
||||||
|
{
|
||||||
|
origin.translate(cont.getX(), cont.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
recursiveRelocateHeavyweightChildren(origin);
|
||||||
|
}
|
||||||
|
super.mixOnReshaping();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
void mixOnZOrderChanging(int oldZorder, int newZorder) {
|
void mixOnZOrderChanging(int oldZorder, int newZorder) {
|
||||||
synchronized (getTreeLock()) {
|
synchronized (getTreeLock()) {
|
||||||
if (mixingLog.isLoggable(Level.FINE)) {
|
if (mixingLog.isLoggable(Level.FINE)) {
|
||||||
@ -4431,7 +4543,8 @@ class LightweightDispatcher implements java.io.Serializable, AWTEventListener {
|
|||||||
e.isPopupTrigger(),
|
e.isPopupTrigger(),
|
||||||
((MouseWheelEvent)e).getScrollType(),
|
((MouseWheelEvent)e).getScrollType(),
|
||||||
((MouseWheelEvent)e).getScrollAmount(),
|
((MouseWheelEvent)e).getScrollAmount(),
|
||||||
((MouseWheelEvent)e).getWheelRotation());
|
((MouseWheelEvent)e).getWheelRotation(),
|
||||||
|
((MouseWheelEvent)e).getPreciseWheelRotation());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
retargeted = new MouseEvent(target,
|
retargeted = new MouseEvent(target,
|
||||||
|
@ -154,7 +154,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
|
|||||||
private boolean doRestoreFocus(Component toFocus, Component vetoedComponent,
|
private boolean doRestoreFocus(Component toFocus, Component vetoedComponent,
|
||||||
boolean clearOnFailure)
|
boolean clearOnFailure)
|
||||||
{
|
{
|
||||||
if (toFocus.isShowing() && toFocus.isFocusable() &&
|
if (toFocus != vetoedComponent && toFocus.isShowing() && toFocus.isFocusable() &&
|
||||||
toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK)) {
|
toFocus.requestFocus(false, CausedFocusEvent.Cause.ROLLBACK)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,7 +24,6 @@
|
|||||||
*/
|
*/
|
||||||
package java.awt;
|
package java.awt;
|
||||||
|
|
||||||
import java.applet.Applet;
|
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
import java.awt.im.InputContext;
|
import java.awt.im.InputContext;
|
||||||
import java.awt.image.BufferStrategy;
|
import java.awt.image.BufferStrategy;
|
||||||
@ -355,18 +354,21 @@ public class Window extends Container implements Accessible {
|
|||||||
static class WindowDisposerRecord implements sun.java2d.DisposerRecord {
|
static class WindowDisposerRecord implements sun.java2d.DisposerRecord {
|
||||||
final WeakReference<Window> owner;
|
final WeakReference<Window> owner;
|
||||||
final WeakReference weakThis;
|
final WeakReference weakThis;
|
||||||
final AppContext context;
|
final WeakReference<AppContext> context;
|
||||||
WindowDisposerRecord(AppContext context, Window victim) {
|
WindowDisposerRecord(AppContext context, Window victim) {
|
||||||
owner = new WeakReference<Window>(victim.getOwner());
|
owner = new WeakReference<Window>(victim.getOwner());
|
||||||
weakThis = victim.weakThis;
|
weakThis = victim.weakThis;
|
||||||
this.context = context;
|
this.context = new WeakReference<AppContext>(context);
|
||||||
}
|
}
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
Window parent = owner.get();
|
Window parent = owner.get();
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
parent.removeOwnedWindow(weakThis);
|
parent.removeOwnedWindow(weakThis);
|
||||||
}
|
}
|
||||||
Window.removeFromWindowList(context, weakThis);
|
AppContext ac = context.get();
|
||||||
|
if (null != ac) {
|
||||||
|
Window.removeFromWindowList(ac, weakThis);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,7 +826,10 @@ public class Window extends Container implements Accessible {
|
|||||||
static private final AtomicBoolean
|
static private final AtomicBoolean
|
||||||
beforeFirstWindowShown = new AtomicBoolean(true);
|
beforeFirstWindowShown = new AtomicBoolean(true);
|
||||||
|
|
||||||
static final void closeSplashScreen() {
|
final void closeSplashScreen() {
|
||||||
|
if (isTrayIconWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (beforeFirstWindowShown.getAndSet(false)) {
|
if (beforeFirstWindowShown.getAndSet(false)) {
|
||||||
SunToolkit.closeSplashScreen();
|
SunToolkit.closeSplashScreen();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -49,7 +49,6 @@ import java.util.WeakHashMap;
|
|||||||
|
|
||||||
import sun.awt.datatransfer.DataTransferer;
|
import sun.awt.datatransfer.DataTransferer;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SystemFlavorMap is a configurable map between "natives" (Strings), which
|
* The SystemFlavorMap is a configurable map between "natives" (Strings), which
|
||||||
* correspond to platform-specific data formats, and "flavors" (DataFlavors),
|
* correspond to platform-specific data formats, and "flavors" (DataFlavors),
|
||||||
@ -117,15 +116,50 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
/**
|
/**
|
||||||
* Maps native Strings to Lists of DataFlavors (or base type Strings for
|
* Maps native Strings to Lists of DataFlavors (or base type Strings for
|
||||||
* text DataFlavors).
|
* text DataFlavors).
|
||||||
|
* Do not use the field directly, use getNativeToFlavor() instead.
|
||||||
*/
|
*/
|
||||||
private Map nativeToFlavor = new HashMap();
|
private Map nativeToFlavor = new HashMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor to nativeToFlavor map. Since we use lazy initialization we must
|
||||||
|
* use this accessor instead of direct access to the field which may not be
|
||||||
|
* initialized yet. This method will initialize the field if needed.
|
||||||
|
*
|
||||||
|
* @return nativeToFlavor
|
||||||
|
*/
|
||||||
|
private Map getNativeToFlavor() {
|
||||||
|
if (!isMapInitialized) {
|
||||||
|
initSystemFlavorMap();
|
||||||
|
}
|
||||||
|
return nativeToFlavor;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
|
* Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
|
||||||
* native Strings.
|
* native Strings.
|
||||||
|
* Do not use the field directly, use getFlavorToNative() instead.
|
||||||
*/
|
*/
|
||||||
private Map flavorToNative = new HashMap();
|
private Map flavorToNative = new HashMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor to flavorToNative map. Since we use lazy initialization we must
|
||||||
|
* use this accessor instead of direct access to the field which may not be
|
||||||
|
* initialized yet. This method will initialize the field if needed.
|
||||||
|
*
|
||||||
|
* @return flavorToNative
|
||||||
|
*/
|
||||||
|
private synchronized Map getFlavorToNative() {
|
||||||
|
if (!isMapInitialized) {
|
||||||
|
initSystemFlavorMap();
|
||||||
|
}
|
||||||
|
return flavorToNative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows if the object has been initialized.
|
||||||
|
*/
|
||||||
|
private boolean isMapInitialized = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches the result of getNativesForFlavor(). Maps DataFlavors to
|
* Caches the result of getNativesForFlavor(). Maps DataFlavors to
|
||||||
* SoftReferences which reference Lists of String natives.
|
* SoftReferences which reference Lists of String natives.
|
||||||
@ -169,15 +203,24 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
return fm;
|
return fm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a SystemFlavorMap by reading flavormap.properties and
|
|
||||||
* AWT.DnD.flavorMapFileURL.
|
|
||||||
*/
|
|
||||||
private SystemFlavorMap() {
|
private SystemFlavorMap() {
|
||||||
BufferedReader flavormapDotProperties = (BufferedReader)
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a SystemFlavorMap by reading flavormap.properties and
|
||||||
|
* AWT.DnD.flavorMapFileURL.
|
||||||
|
* For thread-safety must be called under lock on this.
|
||||||
|
*/
|
||||||
|
private void initSystemFlavorMap() {
|
||||||
|
if (isMapInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isMapInitialized = true;
|
||||||
|
BufferedReader flavormapDotProperties =
|
||||||
java.security.AccessController.doPrivileged(
|
java.security.AccessController.doPrivileged(
|
||||||
new java.security.PrivilegedAction() {
|
new java.security.PrivilegedAction<BufferedReader>() {
|
||||||
public Object run() {
|
public BufferedReader run() {
|
||||||
String fileName =
|
String fileName =
|
||||||
System.getProperty("java.home") +
|
System.getProperty("java.home") +
|
||||||
File.separator +
|
File.separator +
|
||||||
@ -197,12 +240,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
BufferedReader flavormapURL = (BufferedReader)
|
BufferedReader flavormapURL =
|
||||||
java.security.AccessController.doPrivileged(
|
java.security.AccessController.doPrivileged(
|
||||||
new java.security.PrivilegedAction() {
|
new java.security.PrivilegedAction<BufferedReader>() {
|
||||||
public Object run() {
|
public BufferedReader run() {
|
||||||
String url = Toolkit.getDefaultToolkit().getProperty
|
String url = Toolkit.getProperty("AWT.DnD.flavorMapFileURL", null);
|
||||||
("AWT.DnD.flavorMapFileURL", null);
|
|
||||||
|
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -237,7 +279,6 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copied code from java.util.Properties. Parsing the data ourselves is the
|
* Copied code from java.util.Properties. Parsing the data ourselves is the
|
||||||
* only way to handle duplicate keys and values.
|
* only way to handle duplicate keys and values.
|
||||||
@ -388,11 +429,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
// For text/* flavors, store mappings in separate maps to
|
// For text/* flavors, store mappings in separate maps to
|
||||||
// enable dynamic mapping generation at a run-time.
|
// enable dynamic mapping generation at a run-time.
|
||||||
if ("text".equals(flavor.getPrimaryType())) {
|
if ("text".equals(flavor.getPrimaryType())) {
|
||||||
store(value, key, flavorToNative);
|
store(value, key, getFlavorToNative());
|
||||||
store(key, value, nativeToFlavor);
|
store(key, value, getNativeToFlavor());
|
||||||
} else {
|
} else {
|
||||||
store(flavor, key, flavorToNative);
|
store(flavor, key, getFlavorToNative());
|
||||||
store(key, flavor, nativeToFlavor);
|
store(key, flavor, getNativeToFlavor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,7 +535,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
* only if the specified native is encoded as a Java MIME type.
|
* only if the specified native is encoded as a Java MIME type.
|
||||||
*/
|
*/
|
||||||
private List nativeToFlavorLookup(String nat) {
|
private List nativeToFlavorLookup(String nat) {
|
||||||
List flavors = (List)nativeToFlavor.get(nat);
|
List flavors = (List)getNativeToFlavor().get(nat);
|
||||||
|
|
||||||
if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
|
if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
|
||||||
DataTransferer transferer = DataTransferer.getInstance();
|
DataTransferer transferer = DataTransferer.getInstance();
|
||||||
@ -530,15 +571,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
|
|
||||||
if (flavor != null) {
|
if (flavor != null) {
|
||||||
flavors = new ArrayList(1);
|
flavors = new ArrayList(1);
|
||||||
nativeToFlavor.put(nat, flavors);
|
getNativeToFlavor().put(nat, flavors);
|
||||||
flavors.add(flavor);
|
flavors.add(flavor);
|
||||||
getFlavorsForNativeCache.remove(nat);
|
getFlavorsForNativeCache.remove(nat);
|
||||||
getFlavorsForNativeCache.remove(null);
|
getFlavorsForNativeCache.remove(null);
|
||||||
|
|
||||||
List natives = (List)flavorToNative.get(flavor);
|
List natives = (List)getFlavorToNative().get(flavor);
|
||||||
if (natives == null) {
|
if (natives == null) {
|
||||||
natives = new ArrayList(1);
|
natives = new ArrayList(1);
|
||||||
flavorToNative.put(flavor, natives);
|
getFlavorToNative().put(flavor, natives);
|
||||||
}
|
}
|
||||||
natives.add(nat);
|
natives.add(nat);
|
||||||
getNativesForFlavorCache.remove(flavor);
|
getNativesForFlavorCache.remove(flavor);
|
||||||
@ -559,7 +600,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
*/
|
*/
|
||||||
private List flavorToNativeLookup(final DataFlavor flav,
|
private List flavorToNativeLookup(final DataFlavor flav,
|
||||||
final boolean synthesize) {
|
final boolean synthesize) {
|
||||||
List natives = (List)flavorToNative.get(flav);
|
List natives = (List)getFlavorToNative().get(flav);
|
||||||
|
|
||||||
if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
|
if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
|
||||||
DataTransferer transferer = DataTransferer.getInstance();
|
DataTransferer transferer = DataTransferer.getInstance();
|
||||||
@ -584,15 +625,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
if (synthesize) {
|
if (synthesize) {
|
||||||
String encoded = encodeDataFlavor(flav);
|
String encoded = encodeDataFlavor(flav);
|
||||||
natives = new ArrayList(1);
|
natives = new ArrayList(1);
|
||||||
flavorToNative.put(flav, natives);
|
getFlavorToNative().put(flav, natives);
|
||||||
natives.add(encoded);
|
natives.add(encoded);
|
||||||
getNativesForFlavorCache.remove(flav);
|
getNativesForFlavorCache.remove(flav);
|
||||||
getNativesForFlavorCache.remove(null);
|
getNativesForFlavorCache.remove(null);
|
||||||
|
|
||||||
List flavors = (List)nativeToFlavor.get(encoded);
|
List flavors = (List)getNativeToFlavor().get(encoded);
|
||||||
if (flavors == null) {
|
if (flavors == null) {
|
||||||
flavors = new ArrayList(1);
|
flavors = new ArrayList(1);
|
||||||
nativeToFlavor.put(encoded, flavors);
|
getNativeToFlavor().put(encoded, flavors);
|
||||||
}
|
}
|
||||||
flavors.add(flav);
|
flavors.add(flav);
|
||||||
getFlavorsForNativeCache.remove(encoded);
|
getFlavorsForNativeCache.remove(encoded);
|
||||||
@ -645,7 +686,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flav == null) {
|
if (flav == null) {
|
||||||
retval = new ArrayList(nativeToFlavor.keySet());
|
retval = new ArrayList(getNativeToFlavor().keySet());
|
||||||
} else if (disabledMappingGenerationKeys.contains(flav)) {
|
} else if (disabledMappingGenerationKeys.contains(flav)) {
|
||||||
// In this case we shouldn't synthesize a native for this flavor,
|
// In this case we shouldn't synthesize a native for this flavor,
|
||||||
// since its mappings were explicitly specified.
|
// since its mappings were explicitly specified.
|
||||||
@ -655,7 +696,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
// For text/* flavors, flavor-to-native mappings specified in
|
// For text/* flavors, flavor-to-native mappings specified in
|
||||||
// flavormap.properties are stored per flavor's base type.
|
// flavormap.properties are stored per flavor's base type.
|
||||||
if ("text".equals(flav.getPrimaryType())) {
|
if ("text".equals(flav.getPrimaryType())) {
|
||||||
retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
|
retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
|
||||||
if (retval != null) {
|
if (retval != null) {
|
||||||
// To prevent the List stored in the map from modification.
|
// To prevent the List stored in the map from modification.
|
||||||
retval = new ArrayList(retval);
|
retval = new ArrayList(retval);
|
||||||
@ -663,7 +704,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Also include text/plain natives, but don't duplicate Strings
|
// Also include text/plain natives, but don't duplicate Strings
|
||||||
List textPlainList = (List)flavorToNative.get(TEXT_PLAIN_BASE_TYPE);
|
List textPlainList = (List)getFlavorToNative().get(TEXT_PLAIN_BASE_TYPE);
|
||||||
|
|
||||||
if (textPlainList != null && !textPlainList.isEmpty()) {
|
if (textPlainList != null && !textPlainList.isEmpty()) {
|
||||||
// To prevent the List stored in the map from modification.
|
// To prevent the List stored in the map from modification.
|
||||||
@ -699,7 +740,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
|
} else if (DataTransferer.isFlavorNoncharsetTextType(flav)) {
|
||||||
retval = (List)flavorToNative.get(flav.mimeType.getBaseType());
|
retval = (List)getFlavorToNative().get(flav.mimeType.getBaseType());
|
||||||
|
|
||||||
if (retval == null || retval.isEmpty()) {
|
if (retval == null || retval.isEmpty()) {
|
||||||
retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
|
retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND);
|
||||||
@ -1025,10 +1066,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
throw new NullPointerException("null arguments not permitted");
|
throw new NullPointerException("null arguments not permitted");
|
||||||
}
|
}
|
||||||
|
|
||||||
List natives = (List)flavorToNative.get(flav);
|
List natives = (List)getFlavorToNative().get(flav);
|
||||||
if (natives == null) {
|
if (natives == null) {
|
||||||
natives = new ArrayList(1);
|
natives = new ArrayList(1);
|
||||||
flavorToNative.put(flav, natives);
|
getFlavorToNative().put(flav, natives);
|
||||||
} else if (natives.contains(nat)) {
|
} else if (natives.contains(nat)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1071,7 +1112,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
throw new NullPointerException("null arguments not permitted");
|
throw new NullPointerException("null arguments not permitted");
|
||||||
}
|
}
|
||||||
|
|
||||||
flavorToNative.remove(flav);
|
getFlavorToNative().remove(flav);
|
||||||
for (int i = 0; i < natives.length; i++) {
|
for (int i = 0; i < natives.length; i++) {
|
||||||
addUnencodedNativeForFlavor(flav, natives[i]);
|
addUnencodedNativeForFlavor(flav, natives[i]);
|
||||||
}
|
}
|
||||||
@ -1105,10 +1146,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
throw new NullPointerException("null arguments not permitted");
|
throw new NullPointerException("null arguments not permitted");
|
||||||
}
|
}
|
||||||
|
|
||||||
List flavors = (List)nativeToFlavor.get(nat);
|
List flavors = (List)getNativeToFlavor().get(nat);
|
||||||
if (flavors == null) {
|
if (flavors == null) {
|
||||||
flavors = new ArrayList(1);
|
flavors = new ArrayList(1);
|
||||||
nativeToFlavor.put(nat, flavors);
|
getNativeToFlavor().put(nat, flavors);
|
||||||
} else if (flavors.contains(flav)) {
|
} else if (flavors.contains(flav)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1150,7 +1191,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
|
|||||||
throw new NullPointerException("null arguments not permitted");
|
throw new NullPointerException("null arguments not permitted");
|
||||||
}
|
}
|
||||||
|
|
||||||
nativeToFlavor.remove(nat);
|
getNativeToFlavor().remove(nat);
|
||||||
for (int i = 0; i < flavors.length; i++) {
|
for (int i = 0; i < flavors.length; i++) {
|
||||||
addFlavorForUnencodedNative(nat, flavors[i]);
|
addFlavorForUnencodedNative(nat, flavors[i]);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -110,7 +110,11 @@ public class DropTarget implements DropTargetListener, Serializable {
|
|||||||
setActive(act);
|
setActive(act);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fm != null) flavorMap = fm;
|
if (fm != null) {
|
||||||
|
flavorMap = fm;
|
||||||
|
} else {
|
||||||
|
flavorMap = SystemFlavorMap.getDefaultFlavorMap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -850,5 +854,5 @@ public class DropTarget implements DropTargetListener, Serializable {
|
|||||||
* The FlavorMap
|
* The FlavorMap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap();
|
private transient FlavorMap flavorMap;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -74,6 +74,19 @@ import java.awt.Component;
|
|||||||
* methods for conforming to the underlying platform settings. These
|
* methods for conforming to the underlying platform settings. These
|
||||||
* platform settings can be changed at any time by the user. MouseWheelEvents
|
* platform settings can be changed at any time by the user. MouseWheelEvents
|
||||||
* reflect the most recent settings.
|
* reflect the most recent settings.
|
||||||
|
* <P>
|
||||||
|
* The <code>MouseWheelEvent</code> class includes methods for
|
||||||
|
* getting the number of "clicks" by which the mouse wheel is rotated.
|
||||||
|
* The {@link #getWheelRotation} method returns the integer number
|
||||||
|
* of "clicks" corresponding to the number of notches by which the wheel was
|
||||||
|
* rotated. In addition to this method, the <code>MouseWheelEvent</code>
|
||||||
|
* class provides the {@link #getPreciseWheelRotation} method which returns
|
||||||
|
* a double number of "clicks" in case a partial rotation occurred.
|
||||||
|
* The {@link #getPreciseWheelRotation} method is useful if a mouse supports
|
||||||
|
* a high-resolution wheel, such as a freely rotating wheel with no
|
||||||
|
* notches. Applications can benefit by using this method to process
|
||||||
|
* mouse wheel events more precisely, and thus, making visual perception
|
||||||
|
* smoother.
|
||||||
*
|
*
|
||||||
* @author Brent Christian
|
* @author Brent Christian
|
||||||
* @see MouseWheelListener
|
* @see MouseWheelListener
|
||||||
@ -131,6 +144,13 @@ public class MouseWheelEvent extends MouseEvent {
|
|||||||
*/
|
*/
|
||||||
int wheelRotation;
|
int wheelRotation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates how far the mouse wheel was rotated.
|
||||||
|
*
|
||||||
|
* @see #getPreciseWheelRotation
|
||||||
|
*/
|
||||||
|
double preciseWheelRotation;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* serialVersionUID
|
* serialVersionUID
|
||||||
*/
|
*/
|
||||||
@ -165,8 +185,8 @@ public class MouseWheelEvent extends MouseEvent {
|
|||||||
* <code>WHEEL_BLOCK_SCROLL</code>
|
* <code>WHEEL_BLOCK_SCROLL</code>
|
||||||
* @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
|
* @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
|
||||||
* the number of units to be scrolled
|
* the number of units to be scrolled
|
||||||
* @param wheelRotation the amount that the mouse wheel was rotated (the
|
* @param wheelRotation the integer number of "clicks" by which the mouse
|
||||||
* number of "clicks")
|
* wheel was rotated
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if <code>source</code> is null
|
* @throws IllegalArgumentException if <code>source</code> is null
|
||||||
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
|
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
|
||||||
@ -211,8 +231,8 @@ public class MouseWheelEvent extends MouseEvent {
|
|||||||
* <code>WHEEL_BLOCK_SCROLL</code>
|
* <code>WHEEL_BLOCK_SCROLL</code>
|
||||||
* @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
|
* @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
|
||||||
* the number of units to be scrolled
|
* the number of units to be scrolled
|
||||||
* @param wheelRotation the amount that the mouse wheel was rotated (the
|
* @param wheelRotation the integer number of "clicks" by which the mouse
|
||||||
* number of "clicks")
|
* wheel was rotated
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if <code>source</code> is null
|
* @throws IllegalArgumentException if <code>source</code> is null
|
||||||
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
|
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
|
||||||
@ -223,12 +243,68 @@ public class MouseWheelEvent extends MouseEvent {
|
|||||||
int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
|
int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
|
||||||
int scrollType, int scrollAmount, int wheelRotation) {
|
int scrollType, int scrollAmount, int wheelRotation) {
|
||||||
|
|
||||||
|
this(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger,
|
||||||
|
scrollType, scrollAmount, wheelRotation, wheelRotation);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a <code>MouseWheelEvent</code> object with the specified
|
||||||
|
* source component, type, modifiers, coordinates, absolute coordinates,
|
||||||
|
* scroll type, scroll amount, and wheel rotation.
|
||||||
|
* <p>Note that passing in an invalid <code>id</code> parameter results
|
||||||
|
* in unspecified behavior. This method throws an
|
||||||
|
* <code>IllegalArgumentException</code> if <code>source</code> equals
|
||||||
|
* <code>null</code>.
|
||||||
|
* <p>Even if inconsistent values for relative and absolute coordinates
|
||||||
|
* are passed to the constructor, a <code>MouseWheelEvent</code> instance
|
||||||
|
* is still created and no exception is thrown.
|
||||||
|
*
|
||||||
|
* @param source the <code>Component</code> that originated the event
|
||||||
|
* @param id the integer value that identifies the event
|
||||||
|
* @param when a long value that gives the time when the event occurred
|
||||||
|
* @param modifiers the modifier keys down during event
|
||||||
|
* (shift, ctrl, alt, meta)
|
||||||
|
* @param x the horizontal <code>x</code> coordinate for the
|
||||||
|
* mouse location
|
||||||
|
* @param y the vertical <code>y</code> coordinate for the
|
||||||
|
* mouse location
|
||||||
|
* @param xAbs the absolute horizontal <code>x</code> coordinate for
|
||||||
|
* the mouse location
|
||||||
|
* @param yAbs the absolute vertical <code>y</code> coordinate for
|
||||||
|
* the mouse location
|
||||||
|
* @param clickCount the number of mouse clicks associated with the event
|
||||||
|
* @param popupTrigger a boolean value, <code>true</code> if this event is a trigger
|
||||||
|
* for a popup-menu
|
||||||
|
* @param scrollType the type of scrolling which should take place in
|
||||||
|
* response to this event; valid values are
|
||||||
|
* <code>WHEEL_UNIT_SCROLL</code> and
|
||||||
|
* <code>WHEEL_BLOCK_SCROLL</code>
|
||||||
|
* @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
|
||||||
|
* the number of units to be scrolled
|
||||||
|
* @param wheelRotation the integer number of "clicks" by which the mouse wheel
|
||||||
|
* was rotated
|
||||||
|
* @param preciseWheelRotation the double number of "clicks" by which the mouse wheel
|
||||||
|
* was rotated
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if <code>source</code> is null
|
||||||
|
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
|
||||||
|
* @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, int, int, boolean, int)
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public MouseWheelEvent (Component source, int id, long when, int modifiers,
|
||||||
|
int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
|
||||||
|
int scrollType, int scrollAmount, int wheelRotation, double preciseWheelRotation) {
|
||||||
|
|
||||||
super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount,
|
super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount,
|
||||||
popupTrigger, MouseEvent.NOBUTTON);
|
popupTrigger, MouseEvent.NOBUTTON);
|
||||||
|
|
||||||
this.scrollType = scrollType;
|
this.scrollType = scrollType;
|
||||||
this.scrollAmount = scrollAmount;
|
this.scrollAmount = scrollAmount;
|
||||||
this.wheelRotation = wheelRotation;
|
this.wheelRotation = wheelRotation;
|
||||||
|
this.preciseWheelRotation = preciseWheelRotation;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -267,16 +343,34 @@ public class MouseWheelEvent extends MouseEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of "clicks" the mouse wheel was rotated.
|
* Returns the number of "clicks" the mouse wheel was rotated, as an integer.
|
||||||
|
* A partial rotation may occur if the mouse supports a high-resolution wheel.
|
||||||
|
* In this case, the method returns zero until a full "click" has been accumulated.
|
||||||
*
|
*
|
||||||
* @return negative values if the mouse wheel was rotated up/away from
|
* @return negative values if the mouse wheel was rotated up/away from
|
||||||
* the user, and positive values if the mouse wheel was rotated down/
|
* the user, and positive values if the mouse wheel was rotated down/
|
||||||
* towards the user
|
* towards the user
|
||||||
|
* @see #getPreciseWheelRotation
|
||||||
*/
|
*/
|
||||||
public int getWheelRotation() {
|
public int getWheelRotation() {
|
||||||
return wheelRotation;
|
return wheelRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of "clicks" the mouse wheel was rotated, as a double.
|
||||||
|
* A partial rotation may occur if the mouse supports a high-resolution wheel.
|
||||||
|
* In this case, the return value will include a fractional "click".
|
||||||
|
*
|
||||||
|
* @return negative values if the mouse wheel was rotated up or away from
|
||||||
|
* the user, and positive values if the mouse wheel was rotated down or
|
||||||
|
* towards the user
|
||||||
|
* @see #getWheelRotation
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
public double getPreciseWheelRotation() {
|
||||||
|
return preciseWheelRotation;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a convenience method to aid in the implementation of
|
* This is a convenience method to aid in the implementation of
|
||||||
* the common-case MouseWheelListener - to scroll a ScrollPane or
|
* the common-case MouseWheelListener - to scroll a ScrollPane or
|
||||||
@ -348,6 +442,6 @@ public class MouseWheelEvent extends MouseEvent {
|
|||||||
}
|
}
|
||||||
return super.paramString()+",scrollType="+scrollTypeStr+
|
return super.paramString()+",scrollType="+scrollTypeStr+
|
||||||
",scrollAmount="+getScrollAmount()+",wheelRotation="+
|
",scrollAmount="+getScrollAmount()+",wheelRotation="+
|
||||||
getWheelRotation();
|
getWheelRotation()+",preciseWheelRotation="+getPreciseWheelRotation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -40,6 +40,8 @@ import java.util.IdentityHashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.beans.PropertyChangeSupport;
|
import java.beans.PropertyChangeSupport;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
|
||||||
@ -126,6 +128,7 @@ import java.beans.PropertyChangeListener;
|
|||||||
* @author Fred Ecks
|
* @author Fred Ecks
|
||||||
*/
|
*/
|
||||||
public final class AppContext {
|
public final class AppContext {
|
||||||
|
private static final Logger log = Logger.getLogger("sun.awt.AppContext");
|
||||||
|
|
||||||
/* Since the contents of an AppContext are unique to each Java
|
/* Since the contents of an AppContext are unique to each Java
|
||||||
* session, this class should never be serialized. */
|
* session, this class should never be serialized. */
|
||||||
@ -143,13 +146,15 @@ public final class AppContext {
|
|||||||
* Returns a set containing all <code>AppContext</code>s.
|
* Returns a set containing all <code>AppContext</code>s.
|
||||||
*/
|
*/
|
||||||
public static Set<AppContext> getAppContexts() {
|
public static Set<AppContext> getAppContexts() {
|
||||||
|
synchronized (threadGroup2appContext) {
|
||||||
return new HashSet<AppContext>(threadGroup2appContext.values());
|
return new HashSet<AppContext>(threadGroup2appContext.values());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The main "system" AppContext, used by everything not otherwise
|
/* The main "system" AppContext, used by everything not otherwise
|
||||||
contained in another AppContext.
|
contained in another AppContext.
|
||||||
*/
|
*/
|
||||||
private static AppContext mainAppContext = null;
|
private static volatile AppContext mainAppContext = null;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The hash map associated with this AppContext. A private delegate
|
* The hash map associated with this AppContext. A private delegate
|
||||||
@ -174,13 +179,12 @@ public final class AppContext {
|
|||||||
public static final String DISPOSED_PROPERTY_NAME = "disposed";
|
public static final String DISPOSED_PROPERTY_NAME = "disposed";
|
||||||
public static final String GUI_DISPOSED = "guidisposed";
|
public static final String GUI_DISPOSED = "guidisposed";
|
||||||
|
|
||||||
private boolean isDisposed = false; // true if AppContext is disposed
|
private volatile boolean isDisposed = false; // true if AppContext is disposed
|
||||||
|
|
||||||
public boolean isDisposed() {
|
public boolean isDisposed() {
|
||||||
return isDisposed;
|
return isDisposed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// On the main Thread, we get the ThreadGroup, make a corresponding
|
// On the main Thread, we get the ThreadGroup, make a corresponding
|
||||||
// AppContext, and instantiate the Java EventQueue. This way, legacy
|
// AppContext, and instantiate the Java EventQueue. This way, legacy
|
||||||
@ -209,7 +213,7 @@ public final class AppContext {
|
|||||||
* number is 1. If so, it returns the sole AppContext without
|
* number is 1. If so, it returns the sole AppContext without
|
||||||
* checking Thread.currentThread().
|
* checking Thread.currentThread().
|
||||||
*/
|
*/
|
||||||
private static int numAppContexts;
|
private static volatile int numAppContexts;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The context ClassLoader that was used to create this AppContext.
|
* The context ClassLoader that was used to create this AppContext.
|
||||||
@ -236,14 +240,15 @@ public final class AppContext {
|
|||||||
threadGroup2appContext.put(threadGroup, this);
|
threadGroup2appContext.put(threadGroup, this);
|
||||||
|
|
||||||
this.contextClassLoader =
|
this.contextClassLoader =
|
||||||
(ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
|
AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||||
public Object run() {
|
public ClassLoader run() {
|
||||||
return Thread.currentThread().getContextClassLoader();
|
return Thread.currentThread().getContextClassLoader();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MostRecentThreadAppContext mostRecentThreadAppContext = null;
|
private static final ThreadLocal<AppContext> threadAppContext =
|
||||||
|
new ThreadLocal<AppContext>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the appropriate AppContext for the caller,
|
* Returns the appropriate AppContext for the caller,
|
||||||
@ -260,29 +265,17 @@ public final class AppContext {
|
|||||||
if (numAppContexts == 1) // If there's only one system-wide,
|
if (numAppContexts == 1) // If there's only one system-wide,
|
||||||
return mainAppContext; // return the main system AppContext.
|
return mainAppContext; // return the main system AppContext.
|
||||||
|
|
||||||
final Thread currentThread = Thread.currentThread();
|
AppContext appContext = threadAppContext.get();
|
||||||
|
|
||||||
AppContext appContext = null;
|
if (null == appContext) {
|
||||||
|
appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>()
|
||||||
// Note: this most recent Thread/AppContext caching is thread-hot.
|
{
|
||||||
// A simple test using SwingSet found that 96.8% of lookups
|
public AppContext run() {
|
||||||
// were matched using the most recent Thread/AppContext. By
|
|
||||||
// instantiating a simple MostRecentThreadAppContext object on
|
|
||||||
// cache misses, the cache hits can be processed without
|
|
||||||
// synchronization.
|
|
||||||
|
|
||||||
MostRecentThreadAppContext recent = mostRecentThreadAppContext;
|
|
||||||
if ((recent != null) && (recent.thread == currentThread)) {
|
|
||||||
appContext = recent.appContext; // Cache hit
|
|
||||||
} else {
|
|
||||||
appContext = (AppContext)AccessController.doPrivileged(
|
|
||||||
new PrivilegedAction() {
|
|
||||||
public Object run() {
|
|
||||||
// Get the current ThreadGroup, and look for it and its
|
// Get the current ThreadGroup, and look for it and its
|
||||||
// parents in the hash from ThreadGroup to AppContext --
|
// parents in the hash from ThreadGroup to AppContext --
|
||||||
// it should be found, because we use createNewContext()
|
// it should be found, because we use createNewContext()
|
||||||
// when new AppContext objects are created.
|
// when new AppContext objects are created.
|
||||||
ThreadGroup currentThreadGroup = currentThread.getThreadGroup();
|
ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup();
|
||||||
ThreadGroup threadGroup = currentThreadGroup;
|
ThreadGroup threadGroup = currentThreadGroup;
|
||||||
AppContext context = threadGroup2appContext.get(threadGroup);
|
AppContext context = threadGroup2appContext.get(threadGroup);
|
||||||
while (context == null) {
|
while (context == null) {
|
||||||
@ -307,8 +300,7 @@ public final class AppContext {
|
|||||||
// (we do this before checking with any AWTSecurityManager, so if
|
// (we do this before checking with any AWTSecurityManager, so if
|
||||||
// this Thread equates with the main AppContext in the cache, it
|
// this Thread equates with the main AppContext in the cache, it
|
||||||
// still will)
|
// still will)
|
||||||
mostRecentThreadAppContext =
|
threadAppContext.set(context);
|
||||||
new MostRecentThreadAppContext(currentThread, context);
|
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
@ -321,9 +313,9 @@ public final class AppContext {
|
|||||||
// allow it to choose the AppContext to return.
|
// allow it to choose the AppContext to return.
|
||||||
SecurityManager securityManager = System.getSecurityManager();
|
SecurityManager securityManager = System.getSecurityManager();
|
||||||
if ((securityManager != null) &&
|
if ((securityManager != null) &&
|
||||||
(securityManager instanceof AWTSecurityManager)) {
|
(securityManager instanceof AWTSecurityManager))
|
||||||
AWTSecurityManager awtSecMgr =
|
{
|
||||||
(AWTSecurityManager)securityManager;
|
AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager;
|
||||||
AppContext secAppContext = awtSecMgr.getAppContext();
|
AppContext secAppContext = awtSecMgr.getAppContext();
|
||||||
if (secAppContext != null) {
|
if (secAppContext != null) {
|
||||||
appContext = secAppContext; // Return what we're told
|
appContext = secAppContext; // Return what we're told
|
||||||
@ -385,7 +377,13 @@ public final class AppContext {
|
|||||||
public void run() {
|
public void run() {
|
||||||
Window[] windowsToDispose = Window.getOwnerlessWindows();
|
Window[] windowsToDispose = Window.getOwnerlessWindows();
|
||||||
for (Window w : windowsToDispose) {
|
for (Window w : windowsToDispose) {
|
||||||
|
try {
|
||||||
w.dispose();
|
w.dispose();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
if (log.isLoggable(Level.FINER)) {
|
||||||
|
log.log(Level.FINER, "exception occured while disposing app context", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AccessController.doPrivileged(new PrivilegedAction() {
|
AccessController.doPrivileged(new PrivilegedAction() {
|
||||||
public Object run() {
|
public Object run() {
|
||||||
@ -444,7 +442,7 @@ public final class AppContext {
|
|||||||
// Threads in the ThreadGroup to exit.
|
// Threads in the ThreadGroup to exit.
|
||||||
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
long endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;
|
long endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
|
||||||
while ((this.threadGroup.activeCount() > 0) &&
|
while ((this.threadGroup.activeCount() > 0) &&
|
||||||
(System.currentTimeMillis() < endTime)) {
|
(System.currentTimeMillis() < endTime)) {
|
||||||
try {
|
try {
|
||||||
@ -459,7 +457,7 @@ public final class AppContext {
|
|||||||
// Threads in the ThreadGroup to die.
|
// Threads in the ThreadGroup to die.
|
||||||
|
|
||||||
startTime = System.currentTimeMillis();
|
startTime = System.currentTimeMillis();
|
||||||
endTime = startTime + (long)THREAD_INTERRUPT_TIMEOUT;
|
endTime = startTime + THREAD_INTERRUPT_TIMEOUT;
|
||||||
while ((this.threadGroup.activeCount() > 0) &&
|
while ((this.threadGroup.activeCount() > 0) &&
|
||||||
(System.currentTimeMillis() < endTime)) {
|
(System.currentTimeMillis() < endTime)) {
|
||||||
try {
|
try {
|
||||||
@ -478,10 +476,7 @@ public final class AppContext {
|
|||||||
}
|
}
|
||||||
threadGroup2appContext.remove(this.threadGroup);
|
threadGroup2appContext.remove(this.threadGroup);
|
||||||
|
|
||||||
MostRecentThreadAppContext recent = mostRecentThreadAppContext;
|
threadAppContext.set(null);
|
||||||
if ((recent != null) && (recent.appContext == this))
|
|
||||||
mostRecentThreadAppContext = null;
|
|
||||||
// If the "most recent" points to this, clear it for GC
|
|
||||||
|
|
||||||
// Finally, we destroy the ThreadGroup entirely.
|
// Finally, we destroy the ThreadGroup entirely.
|
||||||
try {
|
try {
|
||||||
@ -664,6 +659,7 @@ public final class AppContext {
|
|||||||
* Returns a string representation of this AppContext.
|
* Returns a string representation of this AppContext.
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]";
|
return getClass().getName() + "[threadGroup=" + threadGroup.getName() + "]";
|
||||||
}
|
}
|
||||||
@ -769,15 +765,6 @@ public final class AppContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class MostRecentThreadAppContext {
|
|
||||||
final Thread thread;
|
|
||||||
final AppContext appContext;
|
|
||||||
MostRecentThreadAppContext(Thread key, AppContext value) {
|
|
||||||
thread = key;
|
|
||||||
appContext = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class MostRecentKeyValue {
|
final class MostRecentKeyValue {
|
||||||
Object key;
|
Object key;
|
||||||
Object value;
|
Object value;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -270,17 +270,16 @@ public abstract class DataTransferer {
|
|||||||
* instead, null will be returned.
|
* instead, null will be returned.
|
||||||
*/
|
*/
|
||||||
public static DataTransferer getInstance() {
|
public static DataTransferer getInstance() {
|
||||||
if (transferer == null) {
|
|
||||||
synchronized (DataTransferer.class) {
|
synchronized (DataTransferer.class) {
|
||||||
if (transferer == null) {
|
if (transferer == null) {
|
||||||
final String name = SunToolkit.
|
final String name = SunToolkit.getDataTransfererClassName();
|
||||||
getDataTransfererClassName();
|
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
PrivilegedAction action = new PrivilegedAction() {
|
PrivilegedAction<DataTransferer> action = new PrivilegedAction<DataTransferer>()
|
||||||
public Object run() {
|
{
|
||||||
|
public DataTransferer run() {
|
||||||
Class cls = null;
|
Class cls = null;
|
||||||
Method method = null;
|
Method method = null;
|
||||||
Object ret = null;
|
DataTransferer ret = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cls = Class.forName(name);
|
cls = Class.forName(name);
|
||||||
@ -298,8 +297,7 @@ public abstract class DataTransferer {
|
|||||||
}
|
}
|
||||||
if (cls != null) {
|
if (cls != null) {
|
||||||
try {
|
try {
|
||||||
method = cls.getDeclaredMethod
|
method = cls.getDeclaredMethod("getInstanceImpl");
|
||||||
("getInstanceImpl");
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -311,7 +309,7 @@ public abstract class DataTransferer {
|
|||||||
}
|
}
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
try {
|
try {
|
||||||
ret = method.invoke(null);
|
ret = (DataTransferer) method.invoke(null);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new AWTError("Cannot instantiate DataTransferer: " + name);
|
throw new AWTError("Cannot instantiate DataTransferer: " + name);
|
||||||
@ -323,9 +321,7 @@ public abstract class DataTransferer {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
transferer = (DataTransferer)
|
transferer = AccessController.doPrivileged(action);
|
||||||
AccessController.doPrivileged(action);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -39,6 +39,8 @@ import sun.misc.Unsafe;
|
|||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
class MotifDnDConstants {
|
class MotifDnDConstants {
|
||||||
|
// utility class can not be instantiated
|
||||||
|
private MotifDnDConstants() {}
|
||||||
// Note that offsets in all native structures below do not depend on the
|
// Note that offsets in all native structures below do not depend on the
|
||||||
// architecture.
|
// architecture.
|
||||||
private static final Unsafe unsafe = XlibWrapper.unsafe;
|
private static final Unsafe unsafe = XlibWrapper.unsafe;
|
||||||
@ -55,8 +57,7 @@ class MotifDnDConstants {
|
|||||||
XAtom.get("XmTRANSFER_SUCCESS");
|
XAtom.get("XmTRANSFER_SUCCESS");
|
||||||
static final XAtom XA_XmTRANSFER_FAILURE =
|
static final XAtom XA_XmTRANSFER_FAILURE =
|
||||||
XAtom.get("XmTRANSFER_FAILURE");
|
XAtom.get("XmTRANSFER_FAILURE");
|
||||||
static final XSelection MotifDnDSelection =
|
static final XSelection MotifDnDSelection = new XSelection(XA_MOTIF_ATOM_0);
|
||||||
new XSelection(XA_MOTIF_ATOM_0, null);
|
|
||||||
|
|
||||||
public static final byte MOTIF_DND_PROTOCOL_VERSION = 0;
|
public static final byte MOTIF_DND_PROTOCOL_VERSION = 0;
|
||||||
|
|
||||||
@ -231,6 +232,9 @@ class MotifDnDConstants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final class Swapper {
|
public static final class Swapper {
|
||||||
|
// utility class can not be instantiated
|
||||||
|
private Swapper() {}
|
||||||
|
|
||||||
public static short swap(short s) {
|
public static short swap(short s) {
|
||||||
return (short)(((s & 0xFF00) >>> 8) | ((s & 0xFF) << 8));
|
return (short)(((s & 0xFF00) >>> 8) | ((s & 0xFF) << 8));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -933,7 +933,7 @@ class MotifDnDDropTargetProtocol extends XDropTargetProtocol {
|
|||||||
|
|
||||||
XSelection selection = XSelection.getSelection(selectionAtom);
|
XSelection selection = XSelection.getSelection(selectionAtom);
|
||||||
if (selection == null) {
|
if (selection == null) {
|
||||||
selection = new XSelection(selectionAtom, null);
|
selection = new XSelection(selectionAtom);
|
||||||
}
|
}
|
||||||
|
|
||||||
return selection.getData(format, time_stamp);
|
return selection.getData(format, time_stamp);
|
||||||
@ -1056,7 +1056,7 @@ class MotifDnDDropTargetProtocol extends XDropTargetProtocol {
|
|||||||
// the original structure can be freed before this
|
// the original structure can be freed before this
|
||||||
// SunDropTargetEvent is dispatched.
|
// SunDropTargetEvent is dispatched.
|
||||||
if (xclient != null) {
|
if (xclient != null) {
|
||||||
int size = new XClientMessageEvent(nativeCtxt).getSize();
|
int size = XClientMessageEvent.getSize();
|
||||||
|
|
||||||
nativeCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize());
|
nativeCtxt = unsafe.allocateMemory(size + 4 * Native.getLongSize());
|
||||||
|
|
||||||
|
30
jdk/src/solaris/classes/sun/awt/X11/OwnershipListener.java
Normal file
30
jdk/src/solaris/classes/sun/awt/X11/OwnershipListener.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sun.awt.X11;
|
||||||
|
|
||||||
|
interface OwnershipListener {
|
||||||
|
public void ownershipChanged(final boolean isOwner);
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -58,7 +58,7 @@ package sun.awt.X11;
|
|||||||
import sun.misc.Unsafe;
|
import sun.misc.Unsafe;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class XAtom {
|
public final class XAtom {
|
||||||
|
|
||||||
// Order of lock: XAWTLock -> XAtom.class
|
// Order of lock: XAWTLock -> XAtom.class
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ public class XAtom {
|
|||||||
public static XAtom get(String name) {
|
public static XAtom get(String name) {
|
||||||
XAtom xatom = lookup(name);
|
XAtom xatom = lookup(name);
|
||||||
if (xatom == null) {
|
if (xatom == null) {
|
||||||
xatom = new XAtom(name);
|
xatom = new XAtom(XToolkit.getDisplay(), name);
|
||||||
}
|
}
|
||||||
return xatom;
|
return xatom;
|
||||||
}
|
}
|
||||||
@ -232,10 +232,6 @@ public class XAtom {
|
|||||||
this(display, name, true);
|
this(display, name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private XAtom(String name) {
|
|
||||||
this(XToolkit.getDisplay(), name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public XAtom(String name, boolean autoIntern) {
|
public XAtom(String name, boolean autoIntern) {
|
||||||
this(XToolkit.getDisplay(), name, autoIntern);
|
this(XToolkit.getDisplay(), name, autoIntern);
|
||||||
}
|
}
|
||||||
@ -262,7 +258,7 @@ public class XAtom {
|
|||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public XAtom(long display, String name, boolean autoIntern) {
|
private XAtom(long display, String name, boolean autoIntern) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.display = display;
|
this.display = display;
|
||||||
if (autoIntern) {
|
if (autoIntern) {
|
||||||
@ -651,28 +647,6 @@ public class XAtom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes atom with name and display values
|
|
||||||
*/
|
|
||||||
public void setValues(long display, String name, boolean autoIntern) {
|
|
||||||
this.display = display;
|
|
||||||
this.name = name;
|
|
||||||
if (autoIntern) {
|
|
||||||
XToolkit.awtLock();
|
|
||||||
try {
|
|
||||||
atom = XlibWrapper.InternAtom(display,name,0);
|
|
||||||
} finally {
|
|
||||||
XToolkit.awtUnlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
register();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValues(long display, long atom) {
|
|
||||||
this.display = display;
|
|
||||||
this.atom = atom;
|
|
||||||
register();
|
|
||||||
}
|
|
||||||
public void setValues(long display, String name, long atom) {
|
public void setValues(long display, String name, long atom) {
|
||||||
this.display = display;
|
this.display = display;
|
||||||
this.atom = atom;
|
this.atom = atom;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,30 +26,32 @@
|
|||||||
package sun.awt.X11;
|
package sun.awt.X11;
|
||||||
|
|
||||||
import java.awt.datatransfer.Transferable;
|
import java.awt.datatransfer.Transferable;
|
||||||
|
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import sun.awt.UNIXToolkit;
|
||||||
import sun.awt.datatransfer.DataTransferer;
|
import sun.awt.datatransfer.DataTransferer;
|
||||||
import sun.awt.datatransfer.SunClipboard;
|
import sun.awt.datatransfer.SunClipboard;
|
||||||
import sun.awt.datatransfer.ClipboardTransferable;
|
import sun.awt.datatransfer.ClipboardTransferable;
|
||||||
|
|
||||||
import sun.security.action.GetIntegerAction;
|
import sun.security.action.GetIntegerAction;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class which interfaces with the X11 selection service in order to support
|
* A class which interfaces with the X11 selection service in order to support
|
||||||
* data transfer via Clipboard operations.
|
* data transfer via Clipboard operations.
|
||||||
*/
|
*/
|
||||||
public class XClipboard extends SunClipboard implements Runnable {
|
public final class XClipboard extends SunClipboard implements OwnershipListener
|
||||||
|
{
|
||||||
private final XSelection selection;
|
private final XSelection selection;
|
||||||
|
// Time of calling XConvertSelection().
|
||||||
|
private long convertSelectionTime;
|
||||||
|
// The flag used not to call XConvertSelection() if the previous SelectionNotify
|
||||||
|
// has not been processed by checkChange().
|
||||||
|
private volatile boolean isSelectionNotifyProcessed;
|
||||||
|
// The property in which the owner should place requested targets
|
||||||
|
// when tracking changes of available data flavors (practically targets).
|
||||||
|
private volatile XAtom targetsPropertyAtom;
|
||||||
|
|
||||||
private static final Object classLock = new Object();
|
private static final Object classLock = new Object();
|
||||||
|
|
||||||
@ -57,31 +59,33 @@ public class XClipboard extends SunClipboard implements Runnable {
|
|||||||
|
|
||||||
private static int pollInterval;
|
private static int pollInterval;
|
||||||
|
|
||||||
private static Set listenedClipboards;
|
private static Map<Long, XClipboard> targetsAtom2Clipboard;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a system clipboard object.
|
* Creates a system clipboard object.
|
||||||
*/
|
*/
|
||||||
public XClipboard(String name, String selectionName) {
|
public XClipboard(String name, String selectionName) {
|
||||||
super(name);
|
super(name);
|
||||||
selection = new XSelection(XAtom.get(selectionName), this);
|
selection = new XSelection(XAtom.get(selectionName));
|
||||||
|
selection.registerOwershipListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* The action to be run when we lose ownership
|
|
||||||
* NOTE: This method may be called by privileged threads.
|
* NOTE: This method may be called by privileged threads.
|
||||||
* DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
* DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||||
*/
|
*/
|
||||||
public void run() {
|
public void ownershipChanged(final boolean isOwner) {
|
||||||
|
if (isOwner) {
|
||||||
|
checkChangeHere(contents);
|
||||||
|
} else {
|
||||||
lostOwnershipImpl();
|
lostOwnershipImpl();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected synchronized void setContentsNative(Transferable contents) {
|
protected synchronized void setContentsNative(Transferable contents) {
|
||||||
SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable
|
SortedMap formatMap = DataTransferer.getInstance().getFormatsForTransferable
|
||||||
(contents, DataTransferer.adaptFlavorMap(flavorMap));
|
(contents, DataTransferer.adaptFlavorMap(flavorMap));
|
||||||
long[] formats =
|
long[] formats = DataTransferer.keysToLongArray(formatMap);
|
||||||
DataTransferer.getInstance().keysToLongArray(formatMap);
|
|
||||||
|
|
||||||
if (!selection.setOwner(contents, formatMap, formats,
|
if (!selection.setOwner(contents, formatMap, formats,
|
||||||
XToolkit.getCurrentServerTime())) {
|
XToolkit.getCurrentServerTime())) {
|
||||||
@ -94,6 +98,7 @@ public class XClipboard extends SunClipboard implements Runnable {
|
|||||||
return selection.getSelectionAtom().getAtom();
|
return selection.getSelectionAtom().getAtom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized Transferable getContents(Object requestor) {
|
public synchronized Transferable getContents(Object requestor) {
|
||||||
if (contents != null) {
|
if (contents != null) {
|
||||||
return contents;
|
return contents;
|
||||||
@ -115,62 +120,163 @@ public class XClipboard extends SunClipboard implements Runnable {
|
|||||||
return selection.getData(format, XToolkit.getCurrentServerTime());
|
return selection.getData(format, XToolkit.getCurrentServerTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called on the toolkit thread under awtLock.
|
private void checkChangeHere(Transferable contents) {
|
||||||
public void checkChange(long[] formats) {
|
|
||||||
if (!selection.isOwner()) {
|
|
||||||
super.checkChange(formats);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkChangeHere(Transferable contents) {
|
|
||||||
if (areFlavorListenersRegistered()) {
|
if (areFlavorListenersRegistered()) {
|
||||||
super.checkChange(DataTransferer.getInstance().
|
checkChange(DataTransferer.getInstance().
|
||||||
getFormatsForTransferableAsArray(contents, flavorMap));
|
getFormatsForTransferableAsArray(contents, flavorMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void registerClipboardViewerChecked() {
|
private static int getPollInterval() {
|
||||||
|
synchronized (XClipboard.classLock) {
|
||||||
if (pollInterval <= 0) {
|
if (pollInterval <= 0) {
|
||||||
pollInterval = ((Integer)AccessController.doPrivileged(
|
pollInterval = AccessController.doPrivileged(
|
||||||
new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
|
new GetIntegerAction("awt.datatransfer.clipboard.poll.interval",
|
||||||
defaultPollInterval))).intValue();
|
defaultPollInterval));
|
||||||
if (pollInterval <= 0) {
|
if (pollInterval <= 0) {
|
||||||
pollInterval = defaultPollInterval;
|
pollInterval = defaultPollInterval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selection.initializeSelectionForTrackingChanges();
|
return pollInterval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private XAtom getTargetsPropertyAtom() {
|
||||||
|
if (null == targetsPropertyAtom) {
|
||||||
|
targetsPropertyAtom =
|
||||||
|
XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selection.getSelectionAtom().getName());
|
||||||
|
}
|
||||||
|
return targetsPropertyAtom;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerClipboardViewerChecked() {
|
||||||
|
// for XConvertSelection() to be called for the first time in getTargetsDelayed()
|
||||||
|
isSelectionNotifyProcessed = true;
|
||||||
|
|
||||||
boolean mustSchedule = false;
|
boolean mustSchedule = false;
|
||||||
synchronized (XClipboard.classLock) {
|
synchronized (XClipboard.classLock) {
|
||||||
if (listenedClipboards == null) {
|
if (targetsAtom2Clipboard == null) {
|
||||||
listenedClipboards = new HashSet(2);
|
targetsAtom2Clipboard = new HashMap<Long, XClipboard>(2);
|
||||||
|
}
|
||||||
|
mustSchedule = targetsAtom2Clipboard.isEmpty();
|
||||||
|
targetsAtom2Clipboard.put(getTargetsPropertyAtom().getAtom(), this);
|
||||||
|
if (mustSchedule) {
|
||||||
|
XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
|
||||||
|
new SelectionNotifyHandler());
|
||||||
}
|
}
|
||||||
mustSchedule = listenedClipboards.isEmpty();
|
|
||||||
listenedClipboards.add(this);
|
|
||||||
}
|
}
|
||||||
if (mustSchedule) {
|
if (mustSchedule) {
|
||||||
XToolkit.schedule(new CheckChangeTimerTask(), pollInterval);
|
XToolkit.schedule(new CheckChangeTimerTask(), XClipboard.getPollInterval());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CheckChangeTimerTask implements Runnable {
|
private static class CheckChangeTimerTask implements Runnable {
|
||||||
public void run() {
|
public void run() {
|
||||||
for (Iterator iter = listenedClipboards.iterator(); iter.hasNext();) {
|
for (XClipboard clpbrd : targetsAtom2Clipboard.values()) {
|
||||||
XClipboard clpbrd = (XClipboard)iter.next();
|
clpbrd.getTargetsDelayed();
|
||||||
clpbrd.selection.getTargetsDelayed();
|
|
||||||
}
|
}
|
||||||
synchronized (XClipboard.classLock) {
|
synchronized (XClipboard.classLock) {
|
||||||
if (listenedClipboards != null && !listenedClipboards.isEmpty()) {
|
if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
|
||||||
XToolkit.schedule(this, pollInterval);
|
XToolkit.schedule(this, XClipboard.getPollInterval());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SelectionNotifyHandler implements XEventDispatcher {
|
||||||
|
public void dispatchEvent(XEvent ev) {
|
||||||
|
if (ev.get_type() == XlibWrapper.SelectionNotify) {
|
||||||
|
final XSelectionEvent xse = ev.get_xselection();
|
||||||
|
XClipboard clipboard = null;
|
||||||
|
synchronized (XClipboard.classLock) {
|
||||||
|
if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
|
||||||
|
XToolkit.removeEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final long propertyAtom = xse.get_property();
|
||||||
|
clipboard = targetsAtom2Clipboard.get(propertyAtom);
|
||||||
|
}
|
||||||
|
if (null != clipboard) {
|
||||||
|
clipboard.checkChange(xse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void unregisterClipboardViewerChecked() {
|
protected void unregisterClipboardViewerChecked() {
|
||||||
selection.deinitializeSelectionForTrackingChanges();
|
isSelectionNotifyProcessed = false;
|
||||||
synchronized (XClipboard.classLock) {
|
synchronized (XClipboard.classLock) {
|
||||||
listenedClipboards.remove(this);
|
targetsAtom2Clipboard.remove(getTargetsPropertyAtom().getAtom());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkChange() will be called on SelectionNotify
|
||||||
|
private void getTargetsDelayed() {
|
||||||
|
XToolkit.awtLock();
|
||||||
|
try {
|
||||||
|
long curTime = System.currentTimeMillis();
|
||||||
|
if (isSelectionNotifyProcessed || curTime >= (convertSelectionTime + UNIXToolkit.getDatatransferTimeout()))
|
||||||
|
{
|
||||||
|
convertSelectionTime = curTime;
|
||||||
|
XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
|
||||||
|
selection.getSelectionAtom().getAtom(),
|
||||||
|
XDataTransferer.TARGETS_ATOM.getAtom(),
|
||||||
|
getTargetsPropertyAtom().getAtom(),
|
||||||
|
XWindow.getXAWTRootWindow().getWindow(),
|
||||||
|
XlibWrapper.CurrentTime);
|
||||||
|
isSelectionNotifyProcessed = false;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
XToolkit.awtUnlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tracks changes of available formats.
|
||||||
|
* NOTE: This method may be called by privileged threads.
|
||||||
|
* DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||||
|
*/
|
||||||
|
private void checkChange(XSelectionEvent xse) {
|
||||||
|
final long propertyAtom = xse.get_property();
|
||||||
|
if (propertyAtom != getTargetsPropertyAtom().getAtom()) {
|
||||||
|
// wrong atom
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final XAtom selectionAtom = XAtom.get(xse.get_selection());
|
||||||
|
final XSelection changedSelection = XSelection.getSelection(selectionAtom);
|
||||||
|
|
||||||
|
if (null == changedSelection || changedSelection != selection) {
|
||||||
|
// unknown selection - do nothing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isSelectionNotifyProcessed = true;
|
||||||
|
|
||||||
|
if (selection.isOwner()) {
|
||||||
|
// selection is owner - do not need formats
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long[] formats = null;
|
||||||
|
|
||||||
|
if (propertyAtom == XlibWrapper.None) {
|
||||||
|
// We treat None property atom as "empty selection".
|
||||||
|
formats = new long[0];
|
||||||
|
} else {
|
||||||
|
WindowPropertyGetter targetsGetter =
|
||||||
|
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
|
||||||
|
XAtom.get(propertyAtom), 0,
|
||||||
|
XSelection.MAX_LENGTH, true,
|
||||||
|
XlibWrapper.AnyPropertyType);
|
||||||
|
try {
|
||||||
|
targetsGetter.execute();
|
||||||
|
formats = XSelection.getFormats(targetsGetter);
|
||||||
|
} finally {
|
||||||
|
targetsGetter.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkChange(formats);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,17 +31,13 @@ import java.awt.Color;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.DefaultKeyboardFocusManager;
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Event;
|
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Image;
|
import java.awt.Image;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.KeyboardFocusManager;
|
import java.awt.KeyboardFocusManager;
|
||||||
import java.awt.MenuBar;
|
|
||||||
import java.awt.Point;
|
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.SystemColor;
|
import java.awt.SystemColor;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
@ -60,12 +56,9 @@ import java.awt.event.InvocationEvent;
|
|||||||
import java.awt.image.ImageObserver;
|
import java.awt.image.ImageObserver;
|
||||||
import java.awt.image.ImageProducer;
|
import java.awt.image.ImageProducer;
|
||||||
import java.awt.image.VolatileImage;
|
import java.awt.image.VolatileImage;
|
||||||
import java.awt.peer.CanvasPeer;
|
|
||||||
import java.awt.peer.ComponentPeer;
|
import java.awt.peer.ComponentPeer;
|
||||||
import java.awt.peer.ContainerPeer;
|
import java.awt.peer.ContainerPeer;
|
||||||
import java.awt.peer.LightweightPeer;
|
import java.awt.peer.LightweightPeer;
|
||||||
import java.awt.peer.PanelPeer;
|
|
||||||
import java.awt.peer.WindowPeer;
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -821,7 +814,7 @@ public class XComponentPeer extends XWindow implements ComponentPeer, DropTarget
|
|||||||
public void setFont(Font f) {
|
public void setFont(Font f) {
|
||||||
synchronized (getStateLock()) {
|
synchronized (getStateLock()) {
|
||||||
if (f == null) {
|
if (f == null) {
|
||||||
f = defaultFont;
|
f = XWindow.getDefaultFont();
|
||||||
}
|
}
|
||||||
font = f;
|
font = f;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -39,16 +39,37 @@ import sun.awt.ComponentAccessor;
|
|||||||
* This class implements window which serves as content window for decorated frames.
|
* This class implements window which serves as content window for decorated frames.
|
||||||
* Its purpose to provide correct events dispatching for the complex
|
* Its purpose to provide correct events dispatching for the complex
|
||||||
* constructs such as decorated frames.
|
* constructs such as decorated frames.
|
||||||
|
*
|
||||||
|
* It should always be located at (- left inset, - top inset) in the associated
|
||||||
|
* decorated window. So coordinates in it would be the same as java coordinates.
|
||||||
*/
|
*/
|
||||||
public class XContentWindow extends XWindow implements XConstants {
|
public final class XContentWindow extends XWindow implements XConstants {
|
||||||
private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XContentWindow");
|
private static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XContentWindow");
|
||||||
|
|
||||||
XDecoratedPeer parentFrame;
|
static XContentWindow createContent(XDecoratedPeer parentFrame) {
|
||||||
|
final WindowDimensions dims = parentFrame.getDimensions();
|
||||||
|
Rectangle rec = dims.getBounds();
|
||||||
|
// Fix for - set the location of the content window to the (-left inset, -top inset)
|
||||||
|
Insets ins = dims.getInsets();
|
||||||
|
if (ins != null) {
|
||||||
|
rec.x = -ins.left;
|
||||||
|
rec.y = -ins.top;
|
||||||
|
} else {
|
||||||
|
rec.x = 0;
|
||||||
|
rec.y = 0;
|
||||||
|
}
|
||||||
|
final XContentWindow cw = new XContentWindow(parentFrame, rec);
|
||||||
|
cw.xSetVisible(true);
|
||||||
|
return cw;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final XDecoratedPeer parentFrame;
|
||||||
|
|
||||||
// A list of expose events that come when the parentFrame is iconified
|
// A list of expose events that come when the parentFrame is iconified
|
||||||
private java.util.List<SavedExposeEvent> iconifiedExposeEvents = new java.util.ArrayList<SavedExposeEvent>();
|
private final java.util.List<SavedExposeEvent> iconifiedExposeEvents =
|
||||||
|
new java.util.ArrayList<SavedExposeEvent>();
|
||||||
|
|
||||||
XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
|
private XContentWindow(XDecoratedPeer parentFrame, Rectangle bounds) {
|
||||||
super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds);
|
super((Component)parentFrame.getTarget(), parentFrame.getShell(), bounds);
|
||||||
this.parentFrame = parentFrame;
|
this.parentFrame = parentFrame;
|
||||||
}
|
}
|
||||||
@ -63,9 +84,6 @@ public class XContentWindow extends XWindow implements XConstants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize() {
|
|
||||||
xSetVisible(true);
|
|
||||||
}
|
|
||||||
protected String getWMName() {
|
protected String getWMName() {
|
||||||
return "Content window";
|
return "Content window";
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ import java.util.logging.Logger;
|
|||||||
import sun.awt.ComponentAccessor;
|
import sun.awt.ComponentAccessor;
|
||||||
import sun.awt.SunToolkit;
|
import sun.awt.SunToolkit;
|
||||||
|
|
||||||
class XDecoratedPeer extends XWindowPeer {
|
abstract class XDecoratedPeer extends XWindowPeer {
|
||||||
private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer");
|
private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer");
|
||||||
private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
|
private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer");
|
||||||
private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
|
private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer");
|
||||||
@ -98,8 +98,7 @@ class XDecoratedPeer extends XWindowPeer {
|
|||||||
// happen after the X window is created.
|
// happen after the X window is created.
|
||||||
initResizability();
|
initResizability();
|
||||||
updateSizeHints(dimensions);
|
updateSizeHints(dimensions);
|
||||||
content = createContent(dimensions);
|
content = XContentWindow.createContent(this);
|
||||||
content.initialize();
|
|
||||||
if (warningWindow != null) {
|
if (warningWindow != null) {
|
||||||
warningWindow.toFront();
|
warningWindow.toFront();
|
||||||
}
|
}
|
||||||
@ -160,20 +159,6 @@ class XDecoratedPeer extends XWindowPeer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XContentWindow createContent(WindowDimensions dims) {
|
|
||||||
Rectangle rec = dims.getBounds();
|
|
||||||
// Fix for - set the location of the content window to the (-left inset, -top inset)
|
|
||||||
Insets ins = dims.getInsets();
|
|
||||||
if (ins != null) {
|
|
||||||
rec.x = -ins.left;
|
|
||||||
rec.y = -ins.top;
|
|
||||||
} else {
|
|
||||||
rec.x = 0;
|
|
||||||
rec.y = 0;
|
|
||||||
}
|
|
||||||
return new XContentWindow(this, rec);
|
|
||||||
}
|
|
||||||
|
|
||||||
XFocusProxyWindow createFocusProxy() {
|
XFocusProxyWindow createFocusProxy() {
|
||||||
return new XFocusProxyWindow(this);
|
return new XFocusProxyWindow(this);
|
||||||
}
|
}
|
||||||
@ -286,7 +271,7 @@ class XDecoratedPeer extends XWindowPeer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Component t = (Component)target;
|
Component t = (Component)target;
|
||||||
if (getDecorations() == winAttr.AWT_DECOR_NONE) {
|
if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
|
||||||
setReparented(true);
|
setReparented(true);
|
||||||
insets_corrected = true;
|
insets_corrected = true;
|
||||||
reshape(dimensions, SET_SIZE, false);
|
reshape(dimensions, SET_SIZE, false);
|
||||||
@ -471,6 +456,15 @@ class XDecoratedPeer extends XWindowPeer {
|
|||||||
if (insLog.isLoggable(Level.FINE)) {
|
if (insLog.isLoggable(Level.FINE)) {
|
||||||
insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape);
|
insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape);
|
||||||
}
|
}
|
||||||
|
if (userReshape) {
|
||||||
|
// We handle only userReshape == true cases. It means that
|
||||||
|
// if the window manager or any other part of the windowing
|
||||||
|
// system sets inappropriate size for this window, we can
|
||||||
|
// do nothing but accept it.
|
||||||
|
Rectangle reqBounds = newDimensions.getBounds();
|
||||||
|
Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height);
|
||||||
|
newDimensions = new WindowDimensions(newBounds, newDimensions.getInsets(), newDimensions.isClientSizeSet());
|
||||||
|
}
|
||||||
XToolkit.awtLock();
|
XToolkit.awtLock();
|
||||||
try {
|
try {
|
||||||
if (!isReparented() || !isVisible()) {
|
if (!isReparented() || !isVisible()) {
|
||||||
@ -586,6 +580,49 @@ class XDecoratedPeer extends XWindowPeer {
|
|||||||
reshape(dims, operation, userReshape);
|
reshape(dims, operation, userReshape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method gets overriden in XFramePeer & XDialogPeer.
|
||||||
|
abstract boolean isTargetUndecorated();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||||
|
// We don't restrict the setBounds() operation if the code is trusted.
|
||||||
|
if (!hasWarningWindow()) {
|
||||||
|
return new Rectangle(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's undecorated or is not currently visible,
|
||||||
|
// apply the same constraints as for the Window.
|
||||||
|
if (!isVisible() || isTargetUndecorated()) {
|
||||||
|
return super.constrainBounds(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's visible & decorated, constraint the size only
|
||||||
|
int newX = x;
|
||||||
|
int newY = y;
|
||||||
|
int newW = width;
|
||||||
|
int newH = height;
|
||||||
|
|
||||||
|
GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
|
||||||
|
Rectangle sB = gc.getBounds();
|
||||||
|
Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
|
||||||
|
|
||||||
|
Rectangle curBounds = getBounds();
|
||||||
|
|
||||||
|
int maxW = Math.max(sB.width - sIn.left - sIn.right, curBounds.width);
|
||||||
|
int maxH = Math.max(sB.height - sIn.top - sIn.bottom, curBounds.height);
|
||||||
|
|
||||||
|
// First make sure the size is withing the visible part of the screen
|
||||||
|
if (newW > maxW) {
|
||||||
|
newW = maxW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newH > maxH) {
|
||||||
|
newH = maxH;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Rectangle(newX, newY, newW, newH);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see java.awt.peer.ComponentPeer#setBounds
|
* @see java.awt.peer.ComponentPeer#setBounds
|
||||||
*/
|
*/
|
||||||
@ -651,12 +688,12 @@ class XDecoratedPeer extends XWindowPeer {
|
|||||||
}
|
}
|
||||||
if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
|
if (!isReparented() && isVisible() && runningWM != XWM.NO_WM
|
||||||
&& !XWM.isNonReparentingWM()
|
&& !XWM.isNonReparentingWM()
|
||||||
&& getDecorations() != winAttr.AWT_DECOR_NONE) {
|
&& getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
|
||||||
insLog.fine("- visible but not reparented, skipping");
|
insLog.fine("- visible but not reparented, skipping");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Last chance to correct insets
|
//Last chance to correct insets
|
||||||
if (!insets_corrected && getDecorations() != winAttr.AWT_DECOR_NONE) {
|
if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) {
|
||||||
long parent = XlibUtil.getParentWindow(window);
|
long parent = XlibUtil.getParentWindow(window);
|
||||||
Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null;
|
Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null;
|
||||||
if (insLog.isLoggable(Level.FINER)) {
|
if (insLog.isLoggable(Level.FINER)) {
|
||||||
@ -824,7 +861,7 @@ class XDecoratedPeer extends XWindowPeer {
|
|||||||
fs &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE);
|
fs &= ~(MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE);
|
||||||
}
|
}
|
||||||
winAttr.functions = fs;
|
winAttr.functions = fs;
|
||||||
XWM.setShellNotResizable(this, dimensions, dimensions.getScreenBounds(), false);
|
XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -870,7 +907,7 @@ class XDecoratedPeer extends XWindowPeer {
|
|||||||
return getSize().height;
|
return getSize().height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WindowDimensions getDimensions() {
|
final public WindowDimensions getDimensions() {
|
||||||
return dimensions;
|
return dimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,8 @@ class XDialogPeer extends XDecoratedPeer implements DialogPeer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTargetUndecorated() {
|
@Override
|
||||||
|
boolean isTargetUndecorated() {
|
||||||
if (undecorated != null) {
|
if (undecorated != null) {
|
||||||
return undecorated.booleanValue();
|
return undecorated.booleanValue();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -48,8 +48,7 @@ class XDnDConstants {
|
|||||||
static final XAtom XA_XdndStatus = XAtom.get("XdndStatus");
|
static final XAtom XA_XdndStatus = XAtom.get("XdndStatus");
|
||||||
static final XAtom XA_XdndFinished = XAtom.get("XdndFinished");
|
static final XAtom XA_XdndFinished = XAtom.get("XdndFinished");
|
||||||
|
|
||||||
static final XSelection XDnDSelection =
|
static final XSelection XDnDSelection = new XSelection(XA_XdndSelection);
|
||||||
new XSelection(XA_XdndSelection, null);
|
|
||||||
|
|
||||||
public static final int XDND_MIN_PROTOCOL_VERSION = 3;
|
public static final int XDND_MIN_PROTOCOL_VERSION = 3;
|
||||||
public static final int XDND_PROTOCOL_VERSION = 5;
|
public static final int XDND_PROTOCOL_VERSION = 5;
|
||||||
|
@ -647,12 +647,6 @@ public class XEmbedCanvasPeer extends XCanvasPeer implements WindowFocusListener
|
|||||||
}
|
}
|
||||||
if (isXEmbedActive()) {
|
if (isXEmbedActive()) {
|
||||||
switch ((int)msg.get_data(1)) {
|
switch ((int)msg.get_data(1)) {
|
||||||
case _SUN_XEMBED_START:
|
|
||||||
// Child has finished initialization and waits for notify
|
|
||||||
xembed.processXEmbedInfo();
|
|
||||||
|
|
||||||
notifyChildEmbedded();
|
|
||||||
break;
|
|
||||||
case XEMBED_REQUEST_FOCUS:
|
case XEMBED_REQUEST_FOCUS:
|
||||||
requestXEmbedFocus();
|
requestXEmbedFocus();
|
||||||
break;
|
break;
|
||||||
|
@ -74,7 +74,6 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher
|
|||||||
XToolkit.awtUnlock();
|
XToolkit.awtUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notifyReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleClientMessage(XEvent xev) {
|
void handleClientMessage(XEvent xev) {
|
||||||
@ -84,7 +83,6 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher
|
|||||||
if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Embedded message: " + msgidToString((int)msg.get_data(1)));
|
if (xembedLog.isLoggable(Level.FINE)) xembedLog.fine("Embedded message: " + msgidToString((int)msg.get_data(1)));
|
||||||
switch ((int)msg.get_data(1)) {
|
switch ((int)msg.get_data(1)) {
|
||||||
case XEMBED_EMBEDDED_NOTIFY: // Notification about embedding protocol start
|
case XEMBED_EMBEDDED_NOTIFY: // Notification about embedding protocol start
|
||||||
// NOTE: May be called two times because we send _SUN_XEMBED_START
|
|
||||||
active = true;
|
active = true;
|
||||||
server = getEmbedder(embedded, msg);
|
server = getEmbedder(embedded, msg);
|
||||||
// Check if window is reparented. If not - it was created with
|
// Check if window is reparented. If not - it was created with
|
||||||
@ -223,13 +221,4 @@ public class XEmbedClientHelper extends XEmbedHelper implements XEventDispatcher
|
|||||||
long getX11Mods(AWTKeyStroke stroke) {
|
long getX11Mods(AWTKeyStroke stroke) {
|
||||||
return XWindow.getXModifiers(stroke);
|
return XWindow.getXModifiers(stroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
void notifyReady() {
|
|
||||||
long wnd = server;
|
|
||||||
if (wnd == 0) {
|
|
||||||
// Server is still 0, get the parent
|
|
||||||
wnd = embedded.getParentWindowHandle();
|
|
||||||
}
|
|
||||||
sendMessage(wnd, _SUN_XEMBED_START);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,6 @@ public class XEmbedHelper {
|
|||||||
final static int XEMBED_REGISTER_ACCELERATOR = 12;
|
final static int XEMBED_REGISTER_ACCELERATOR = 12;
|
||||||
final static int XEMBED_UNREGISTER_ACCELERATOR= 13;
|
final static int XEMBED_UNREGISTER_ACCELERATOR= 13;
|
||||||
final static int XEMBED_ACTIVATE_ACCELERATOR = 14;
|
final static int XEMBED_ACTIVATE_ACCELERATOR = 14;
|
||||||
final static int _SUN_XEMBED_START = 1119;
|
|
||||||
|
|
||||||
final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108;
|
final static int NON_STANDARD_XEMBED_GTK_GRAB_KEY = 108;
|
||||||
final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109;
|
final static int NON_STANDARD_XEMBED_GTK_UNGRAB_KEY = 109;
|
||||||
@ -151,8 +150,6 @@ public class XEmbedHelper {
|
|||||||
return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY";
|
return "NON_STANDARD_XEMBED_GTK_UNGRAB_KEY";
|
||||||
case NON_STANDARD_XEMBED_GTK_GRAB_KEY:
|
case NON_STANDARD_XEMBED_GTK_GRAB_KEY:
|
||||||
return "NON_STANDARD_XEMBED_GTK_GRAB_KEY";
|
return "NON_STANDARD_XEMBED_GTK_GRAB_KEY";
|
||||||
case _SUN_XEMBED_START:
|
|
||||||
return "XEMBED_START";
|
|
||||||
case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK:
|
case XConstants.KeyPress | XEmbedServerTester.SYSTEM_EVENT_MASK:
|
||||||
return "KeyPress";
|
return "KeyPress";
|
||||||
case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK:
|
case XConstants.MapNotify | XEmbedServerTester.SYSTEM_EVENT_MASK:
|
||||||
|
@ -177,13 +177,6 @@ public class XEmbedServerTester implements XEventDispatcher {
|
|||||||
embedCompletely();
|
embedCompletely();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test3_2() {
|
|
||||||
embedCompletely();
|
|
||||||
int res = getEventPos();
|
|
||||||
sendMessage(XEmbedHelper._SUN_XEMBED_START);
|
|
||||||
waitEmbeddedNotify(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void test3_3() {
|
public void test3_3() {
|
||||||
reparent = true;
|
reparent = true;
|
||||||
embedCompletely();
|
embedCompletely();
|
||||||
|
@ -184,6 +184,12 @@ public class XEmbeddedFramePeer extends XFramePeer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||||
|
// We don't constrain the bounds of the EmbeddedFrames
|
||||||
|
return new Rectangle(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
// don't use getBounds() inherited from XDecoratedPeer
|
// don't use getBounds() inherited from XDecoratedPeer
|
||||||
public Rectangle getBounds() {
|
public Rectangle getBounds() {
|
||||||
return new Rectangle(x, y, width, height);
|
return new Rectangle(x, y, width, height);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,15 +24,18 @@
|
|||||||
*/
|
*/
|
||||||
package sun.awt.X11;
|
package sun.awt.X11;
|
||||||
|
|
||||||
import java.util.Vector;
|
import java.awt.Color;
|
||||||
import java.awt.*;
|
import java.awt.Dimension;
|
||||||
import java.awt.peer.*;
|
import java.awt.Font;
|
||||||
import java.awt.event.*;
|
import java.awt.FontMetrics;
|
||||||
import sun.awt.im.*;
|
import java.awt.Frame;
|
||||||
import sun.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.util.logging.*;
|
import java.awt.Insets;
|
||||||
import java.lang.reflect.Field;
|
import java.awt.MenuBar;
|
||||||
import java.util.*;
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.peer.FramePeer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
|
class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
|
||||||
private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer");
|
private static Logger log = Logger.getLogger("sun.awt.X11.XFramePeer");
|
||||||
@ -92,7 +95,8 @@ class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTargetUndecorated() {
|
@Override
|
||||||
|
boolean isTargetUndecorated() {
|
||||||
if (undecorated != null) {
|
if (undecorated != null) {
|
||||||
return undecorated.booleanValue();
|
return undecorated.booleanValue();
|
||||||
} else {
|
} else {
|
||||||
@ -285,19 +289,20 @@ class XFramePeer extends XDecoratedPeer implements FramePeer, XConstants {
|
|||||||
* Let's see if this is a window state protocol message, and
|
* Let's see if this is a window state protocol message, and
|
||||||
* if it is - decode a new state in terms of java constants.
|
* if it is - decode a new state in terms of java constants.
|
||||||
*/
|
*/
|
||||||
Integer newState = XWM.getWM().isStateChange(this, ev);
|
if (!XWM.getWM().isStateChange(this, ev)) {
|
||||||
if (newState == null) {
|
stateLog.finer("either not a state atom or state has not been changed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int changed = state ^ newState.intValue();
|
final int newState = XWM.getWM().getState(this);
|
||||||
|
int changed = state ^ newState;
|
||||||
if (changed == 0) {
|
if (changed == 0) {
|
||||||
stateLog.finer("State is the same: " + state);
|
stateLog.finer("State is the same: " + state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int old_state = state;
|
int old_state = state;
|
||||||
state = newState.intValue();
|
state = newState;
|
||||||
|
|
||||||
if ((changed & Frame.ICONIFIED) != 0) {
|
if ((changed & Frame.ICONIFIED) != 0) {
|
||||||
if ((state & Frame.ICONIFIED) != 0) {
|
if ((state & Frame.ICONIFIED) != 0) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -218,7 +218,7 @@ public class XMenuItemPeer implements MenuItemPeer {
|
|||||||
|
|
||||||
Font getTargetFont() {
|
Font getTargetFont() {
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
return XWindow.defaultFont;
|
return XWindow.getDefaultFont();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return (Font)m_getFont.invoke(target, new Object[0]);
|
return (Font)m_getFont.invoke(target, new Object[0]);
|
||||||
@ -227,7 +227,7 @@ public class XMenuItemPeer implements MenuItemPeer {
|
|||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return XWindow.defaultFont;
|
return XWindow.getDefaultFont();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTargetLabel() {
|
String getTargetLabel() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,17 +26,15 @@
|
|||||||
|
|
||||||
package sun.awt.X11;
|
package sun.awt.X11;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Frame;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.logging.LogManager;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.image.*;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol {
|
final class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol
|
||||||
final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol");
|
{
|
||||||
|
private final static Logger log = Logger.getLogger("sun.awt.X11.XNETProtocol");
|
||||||
private final static Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XNETProtocol");
|
private final static Logger iconLog = Logger.getLogger("sun.awt.X11.icon.XNETProtocol");
|
||||||
|
private static Logger stateLog = Logger.getLogger("sun.awt.X11.states.XNETProtocol");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XStateProtocol
|
* XStateProtocol
|
||||||
@ -276,6 +274,7 @@ class XNETProtocol extends XProtocol implements XStateProtocol, XLayerProtocol {
|
|||||||
|
|
||||||
boolean doStateProtocol() {
|
boolean doStateProtocol() {
|
||||||
boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE);
|
boolean res = active() && checkProtocol(XA_NET_SUPPORTED, XA_NET_WM_STATE);
|
||||||
|
stateLog.finer("doStateProtocol() returns " + res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -187,7 +187,7 @@ public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer {
|
|||||||
//Fix for 6267144: PIT: Popup menu label is not shown, XToolkit
|
//Fix for 6267144: PIT: Popup menu label is not shown, XToolkit
|
||||||
Font getTargetFont() {
|
Font getTargetFont() {
|
||||||
if (popupMenuTarget == null) {
|
if (popupMenuTarget == null) {
|
||||||
return XWindow.defaultFont;
|
return XWindow.getDefaultFont();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return (Font)m_getFont.invoke(popupMenuTarget, new Object[0]);
|
return (Font)m_getFont.invoke(popupMenuTarget, new Object[0]);
|
||||||
@ -196,7 +196,7 @@ public class XPopupMenuPeer extends XMenuWindow implements PopupMenuPeer {
|
|||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return XWindow.defaultFont;
|
return XWindow.getDefaultFont();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTargetLabel() {
|
String getTargetLabel() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -32,9 +32,6 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import sun.awt.AppContext;
|
import sun.awt.AppContext;
|
||||||
import sun.awt.SunToolkit;
|
import sun.awt.SunToolkit;
|
||||||
@ -45,7 +42,7 @@ import sun.awt.datatransfer.DataTransferer;
|
|||||||
/**
|
/**
|
||||||
* A class which interfaces with the X11 selection service.
|
* A class which interfaces with the X11 selection service.
|
||||||
*/
|
*/
|
||||||
public class XSelection {
|
public final class XSelection {
|
||||||
|
|
||||||
/* Maps atoms to XSelection instances. */
|
/* Maps atoms to XSelection instances. */
|
||||||
private static final Hashtable<XAtom, XSelection> table = new Hashtable<XAtom, XSelection>();
|
private static final Hashtable<XAtom, XSelection> table = new Hashtable<XAtom, XSelection>();
|
||||||
@ -69,8 +66,6 @@ public class XSelection {
|
|||||||
XToolkit.awtUnlock();
|
XToolkit.awtUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* The selection timeout. */
|
|
||||||
private static long SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
|
|
||||||
|
|
||||||
/* The PropertyNotify event handler for incremental data transfer. */
|
/* The PropertyNotify event handler for incremental data transfer. */
|
||||||
private static final XEventDispatcher incrementalTransferHandler =
|
private static final XEventDispatcher incrementalTransferHandler =
|
||||||
@ -84,11 +79,6 @@ public class XSelection {
|
|||||||
|
|
||||||
/* The X atom for the underlying selection. */
|
/* The X atom for the underlying selection. */
|
||||||
private final XAtom selectionAtom;
|
private final XAtom selectionAtom;
|
||||||
/*
|
|
||||||
* XClipboard.run() is to be called when we lose ownership.
|
|
||||||
* XClipbioard.checkChange() is to be called when tracking changes of flavors.
|
|
||||||
*/
|
|
||||||
private final XClipboard clipboard;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Owner-related variables - protected with synchronized (this).
|
* Owner-related variables - protected with synchronized (this).
|
||||||
@ -109,17 +99,8 @@ public class XSelection {
|
|||||||
private long ownershipTime = 0;
|
private long ownershipTime = 0;
|
||||||
// True if we are the owner of this selection.
|
// True if we are the owner of this selection.
|
||||||
private boolean isOwner;
|
private boolean isOwner;
|
||||||
// The property in which the owner should place requested targets
|
private OwnershipListener ownershipListener = null;
|
||||||
// when tracking changes of available data flavors (practically targets).
|
private final Object stateLock = new Object();
|
||||||
private volatile XAtom targetsPropertyAtom;
|
|
||||||
// A set of these property atoms.
|
|
||||||
private static volatile Set targetsPropertyAtoms;
|
|
||||||
// The flag used not to call XConvertSelection() if the previous SelectionNotify
|
|
||||||
// has not been processed by checkChange().
|
|
||||||
private volatile boolean isSelectionNotifyProcessed;
|
|
||||||
// Time of calling XConvertSelection().
|
|
||||||
private long convertSelectionTime;
|
|
||||||
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
|
XToolkit.addEventDispatcher(XWindow.getXAWTRootWindow().getWindow(),
|
||||||
@ -141,12 +122,11 @@ public class XSelection {
|
|||||||
* @param clpbrd the corresponding clipoboard
|
* @param clpbrd the corresponding clipoboard
|
||||||
* @exception NullPointerException if atom is <code>null</code>.
|
* @exception NullPointerException if atom is <code>null</code>.
|
||||||
*/
|
*/
|
||||||
public XSelection(XAtom atom, XClipboard clpbrd) {
|
public XSelection(XAtom atom) {
|
||||||
if (atom == null) {
|
if (atom == null) {
|
||||||
throw new NullPointerException("Null atom");
|
throw new NullPointerException("Null atom");
|
||||||
}
|
}
|
||||||
selectionAtom = atom;
|
selectionAtom = atom;
|
||||||
clipboard = clpbrd;
|
|
||||||
table.put(selectionAtom, this);
|
table.put(selectionAtom, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,25 +134,9 @@ public class XSelection {
|
|||||||
return selectionAtom;
|
return selectionAtom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeSelectionForTrackingChanges() {
|
|
||||||
targetsPropertyAtom = XAtom.get("XAWT_TARGETS_OF_SELECTION:" + selectionAtom.getName());
|
|
||||||
if (targetsPropertyAtoms == null) {
|
|
||||||
targetsPropertyAtoms = Collections.synchronizedSet(new HashSet(2));
|
|
||||||
}
|
|
||||||
targetsPropertyAtoms.add(Long.valueOf(targetsPropertyAtom.getAtom()));
|
|
||||||
// for XConvertSelection() to be called for the first time in getTargetsDelayed()
|
|
||||||
isSelectionNotifyProcessed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void deinitializeSelectionForTrackingChanges() {
|
|
||||||
if (targetsPropertyAtoms != null && targetsPropertyAtom != null) {
|
|
||||||
targetsPropertyAtoms.remove(Long.valueOf(targetsPropertyAtom.getAtom()));
|
|
||||||
}
|
|
||||||
isSelectionNotifyProcessed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized boolean setOwner(Transferable contents, Map formatMap,
|
public synchronized boolean setOwner(Transferable contents, Map formatMap,
|
||||||
long[] formats, long time) {
|
long[] formats, long time)
|
||||||
|
{
|
||||||
long owner = XWindow.getXAWTRootWindow().getWindow();
|
long owner = XWindow.getXAWTRootWindow().getWindow();
|
||||||
long selection = selectionAtom.getAtom();
|
long selection = selectionAtom.getAtom();
|
||||||
|
|
||||||
@ -192,15 +156,12 @@ public class XSelection {
|
|||||||
XlibWrapper.XSetSelectionOwner(XToolkit.getDisplay(),
|
XlibWrapper.XSetSelectionOwner(XToolkit.getDisplay(),
|
||||||
selection, owner, time);
|
selection, owner, time);
|
||||||
if (XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(),
|
if (XlibWrapper.XGetSelectionOwner(XToolkit.getDisplay(),
|
||||||
selection) != owner) {
|
selection) != owner)
|
||||||
|
{
|
||||||
reset();
|
reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
isOwner = true;
|
setOwnerProp(true);
|
||||||
if (clipboard != null) {
|
|
||||||
clipboard.checkChangeHere(contents);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
} finally {
|
} finally {
|
||||||
XToolkit.awtUnlock();
|
XToolkit.awtUnlock();
|
||||||
@ -217,7 +178,7 @@ public class XSelection {
|
|||||||
do {
|
do {
|
||||||
DataTransferer.getInstance().processDataConversionRequests();
|
DataTransferer.getInstance().processDataConversionRequests();
|
||||||
XToolkit.awtLockWait(250);
|
XToolkit.awtLockWait(250);
|
||||||
} while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + SELECTION_TIMEOUT);
|
} while (propertyGetter == dataGetter && System.currentTimeMillis() < startTime + UNIXToolkit.getDatatransferTimeout());
|
||||||
} finally {
|
} finally {
|
||||||
XToolkit.awtUnlock();
|
XToolkit.awtUnlock();
|
||||||
}
|
}
|
||||||
@ -232,11 +193,9 @@ public class XSelection {
|
|||||||
throw new Error("UNIMPLEMENTED");
|
throw new Error("UNIMPLEMENTED");
|
||||||
}
|
}
|
||||||
|
|
||||||
long[] formats = null;
|
long[] targets = null;
|
||||||
|
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
|
|
||||||
|
|
||||||
WindowPropertyGetter targetsGetter =
|
WindowPropertyGetter targetsGetter =
|
||||||
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
|
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
|
||||||
selectionPropertyAtom, 0, MAX_LENGTH,
|
selectionPropertyAtom, 0, MAX_LENGTH,
|
||||||
@ -267,23 +226,25 @@ public class XSelection {
|
|||||||
} finally {
|
} finally {
|
||||||
XToolkit.awtUnlock();
|
XToolkit.awtUnlock();
|
||||||
}
|
}
|
||||||
formats = getFormats(targetsGetter);
|
targets = getFormats(targetsGetter);
|
||||||
} finally {
|
} finally {
|
||||||
targetsGetter.dispose();
|
targetsGetter.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return formats;
|
return targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long[] getFormats(WindowPropertyGetter targetsGetter) {
|
static long[] getFormats(WindowPropertyGetter targetsGetter) {
|
||||||
long[] formats = null;
|
long[] formats = null;
|
||||||
|
|
||||||
if (targetsGetter.isExecuted() && !targetsGetter.isDisposed() &&
|
if (targetsGetter.isExecuted() && !targetsGetter.isDisposed() &&
|
||||||
(targetsGetter.getActualType() == XAtom.XA_ATOM ||
|
(targetsGetter.getActualType() == XAtom.XA_ATOM ||
|
||||||
targetsGetter.getActualType() == XDataTransferer.TARGETS_ATOM.getAtom()) &&
|
targetsGetter.getActualType() == XDataTransferer.TARGETS_ATOM.getAtom()) &&
|
||||||
targetsGetter.getActualFormat() == 32) {
|
targetsGetter.getActualFormat() == 32)
|
||||||
|
{
|
||||||
int count = (int)targetsGetter.getNumberOfItems();
|
// we accept property with TARGETS type to be compatible with old jdks
|
||||||
|
// see 6607163
|
||||||
|
int count = targetsGetter.getNumberOfItems();
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
long atoms = targetsGetter.getData();
|
long atoms = targetsGetter.getData();
|
||||||
formats = new long[count];
|
formats = new long[count];
|
||||||
@ -297,26 +258,6 @@ public class XSelection {
|
|||||||
return formats != null ? formats : new long[0];
|
return formats != null ? formats : new long[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkChange() will be called on SelectionNotify
|
|
||||||
void getTargetsDelayed() {
|
|
||||||
XToolkit.awtLock();
|
|
||||||
try {
|
|
||||||
long curTime = System.currentTimeMillis();
|
|
||||||
if (isSelectionNotifyProcessed || curTime >= convertSelectionTime + SELECTION_TIMEOUT) {
|
|
||||||
convertSelectionTime = curTime;
|
|
||||||
XlibWrapper.XConvertSelection(XToolkit.getDisplay(),
|
|
||||||
getSelectionAtom().getAtom(),
|
|
||||||
XDataTransferer.TARGETS_ATOM.getAtom(),
|
|
||||||
targetsPropertyAtom.getAtom(),
|
|
||||||
XWindow.getXAWTRootWindow().getWindow(),
|
|
||||||
XlibWrapper.CurrentTime);
|
|
||||||
isSelectionNotifyProcessed = false;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
XToolkit.awtUnlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Requests the selection data in the specified format and returns
|
* Requests the selection data in the specified format and returns
|
||||||
* the data provided by the owner.
|
* the data provided by the owner.
|
||||||
@ -329,8 +270,6 @@ public class XSelection {
|
|||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
|
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
SELECTION_TIMEOUT = UNIXToolkit.getDatatransferTimeout();
|
|
||||||
|
|
||||||
WindowPropertyGetter dataGetter =
|
WindowPropertyGetter dataGetter =
|
||||||
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
|
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
|
||||||
selectionPropertyAtom, 0, MAX_LENGTH,
|
selectionPropertyAtom, 0, MAX_LENGTH,
|
||||||
@ -379,7 +318,7 @@ public class XSelection {
|
|||||||
dataGetter.getActualFormat());
|
dataGetter.getActualFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = (int)dataGetter.getNumberOfItems();
|
int count = dataGetter.getNumberOfItems();
|
||||||
|
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
throw new IOException("INCR data is missed.");
|
throw new IOException("INCR data is missed.");
|
||||||
@ -455,7 +394,7 @@ public class XSelection {
|
|||||||
incrDataGetter.getActualFormat());
|
incrDataGetter.getActualFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
count = (int)incrDataGetter.getNumberOfItems();
|
count = incrDataGetter.getNumberOfItems();
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
break;
|
break;
|
||||||
@ -489,7 +428,7 @@ public class XSelection {
|
|||||||
dataGetter.getActualFormat());
|
dataGetter.getActualFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = (int)dataGetter.getNumberOfItems();
|
int count = dataGetter.getNumberOfItems();
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
data = new byte[count];
|
data = new byte[count];
|
||||||
long ptr = dataGetter.getData();
|
long ptr = dataGetter.getData();
|
||||||
@ -511,11 +450,14 @@ public class XSelection {
|
|||||||
return isOwner;
|
return isOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void lostOwnership() {
|
// To be MT-safe this method should be called under awtLock.
|
||||||
isOwner = false;
|
private void setOwnerProp(boolean f) {
|
||||||
if (clipboard != null) {
|
isOwner = f;
|
||||||
clipboard.run();
|
fireOwnershipChanges(isOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void lostOwnership() {
|
||||||
|
setOwnerProp(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void reset() {
|
public synchronized void reset() {
|
||||||
@ -595,125 +537,39 @@ public class XSelection {
|
|||||||
|
|
||||||
private void handleSelectionRequest(XSelectionRequestEvent xsre) {
|
private void handleSelectionRequest(XSelectionRequestEvent xsre) {
|
||||||
long property = xsre.get_property();
|
long property = xsre.get_property();
|
||||||
long requestor = xsre.get_requestor();
|
final long requestor = xsre.get_requestor();
|
||||||
long requestTime = xsre.get_time();
|
final long requestTime = xsre.get_time();
|
||||||
long format = xsre.get_target();
|
final long format = xsre.get_target();
|
||||||
int dataFormat = 0;
|
|
||||||
boolean conversionSucceeded = false;
|
boolean conversionSucceeded = false;
|
||||||
|
|
||||||
if (ownershipTime != 0 &&
|
if (ownershipTime != 0 &&
|
||||||
(requestTime == XlibWrapper.CurrentTime ||
|
(requestTime == XlibWrapper.CurrentTime || requestTime >= ownershipTime))
|
||||||
requestTime >= ownershipTime)) {
|
{
|
||||||
|
|
||||||
property = xsre.get_property();
|
|
||||||
|
|
||||||
// Handle MULTIPLE requests as per ICCCM.
|
// Handle MULTIPLE requests as per ICCCM.
|
||||||
if (format == XDataTransferer.MULTIPLE_ATOM.getAtom()) {
|
if (format == XDataTransferer.MULTIPLE_ATOM.getAtom()) {
|
||||||
// The property cannot be 0 for a MULTIPLE request.
|
conversionSucceeded = handleMultipleRequest(requestor, property);
|
||||||
if (property != 0) {
|
|
||||||
// First retrieve the list of requested targets.
|
|
||||||
WindowPropertyGetter wpg =
|
|
||||||
new WindowPropertyGetter(requestor, XAtom.get(property), 0,
|
|
||||||
MAX_LENGTH, false,
|
|
||||||
XlibWrapper.AnyPropertyType);
|
|
||||||
try {
|
|
||||||
wpg.execute();
|
|
||||||
|
|
||||||
if (wpg.getActualFormat() == 32 &&
|
|
||||||
(wpg.getNumberOfItems() % 2) == 0) {
|
|
||||||
long count = wpg.getNumberOfItems() / 2;
|
|
||||||
long pairsPtr = wpg.getData();
|
|
||||||
boolean writeBack = false;
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
long target = Native.getLong(pairsPtr, 2*i);
|
|
||||||
long prop = Native.getLong(pairsPtr, 2*i + 1);
|
|
||||||
|
|
||||||
if (!convertAndStore(requestor, target, prop)) {
|
|
||||||
// To report failure, we should replace the
|
|
||||||
// target atom with 0 in the MULTIPLE property.
|
|
||||||
Native.putLong(pairsPtr, 2*i, 0);
|
|
||||||
writeBack = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (writeBack) {
|
|
||||||
XToolkit.awtLock();
|
|
||||||
try {
|
|
||||||
XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
|
|
||||||
property,
|
|
||||||
wpg.getActualType(),
|
|
||||||
wpg.getActualFormat(),
|
|
||||||
XlibWrapper.PropModeReplace,
|
|
||||||
wpg.getData(),
|
|
||||||
wpg.getNumberOfItems());
|
|
||||||
} finally {
|
|
||||||
XToolkit.awtUnlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conversionSucceeded = true;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
wpg.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Support for obsolete clients as per ICCCM.
|
// Support for obsolete clients as per ICCCM.
|
||||||
if (property == 0) {
|
if (property == XlibWrapper.None) {
|
||||||
property = format;
|
property = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == XDataTransferer.TARGETS_ATOM.getAtom()) {
|
if (format == XDataTransferer.TARGETS_ATOM.getAtom()) {
|
||||||
long nativeDataPtr = 0;
|
conversionSucceeded = handleTargetsRequest(property, requestor);
|
||||||
int count = 0;
|
|
||||||
dataFormat = 32;
|
|
||||||
|
|
||||||
// Use a local copy to avoid synchronization.
|
|
||||||
long[] formatsLocal = formats;
|
|
||||||
|
|
||||||
if (formatsLocal == null) {
|
|
||||||
throw new IllegalStateException("Not an owner.");
|
|
||||||
}
|
|
||||||
|
|
||||||
count = formatsLocal.length;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (count > 0) {
|
|
||||||
nativeDataPtr = Native.allocateLongArray(count);
|
|
||||||
Native.put(nativeDataPtr, formatsLocal);
|
|
||||||
}
|
|
||||||
|
|
||||||
conversionSucceeded = true;
|
|
||||||
|
|
||||||
XToolkit.awtLock();
|
|
||||||
try {
|
|
||||||
XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
|
|
||||||
property, format, dataFormat,
|
|
||||||
XlibWrapper.PropModeReplace,
|
|
||||||
nativeDataPtr, count);
|
|
||||||
} finally {
|
|
||||||
XToolkit.awtUnlock();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (nativeDataPtr != 0) {
|
|
||||||
XlibWrapper.unsafe.freeMemory(nativeDataPtr);
|
|
||||||
nativeDataPtr = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
conversionSucceeded = convertAndStore(requestor, format,
|
conversionSucceeded = convertAndStore(requestor, format, property);
|
||||||
property);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conversionSucceeded) {
|
if (!conversionSucceeded) {
|
||||||
// Zero property indicates conversion failure.
|
// None property indicates conversion failure.
|
||||||
property = 0;
|
property = XlibWrapper.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
XSelectionEvent xse = new XSelectionEvent();
|
XSelectionEvent xse = new XSelectionEvent();
|
||||||
try {
|
try {
|
||||||
xse.set_type((int)XlibWrapper.SelectionNotify);
|
xse.set_type(XlibWrapper.SelectionNotify);
|
||||||
xse.set_send_event(true);
|
xse.set_send_event(true);
|
||||||
xse.set_requestor(requestor);
|
xse.set_requestor(requestor);
|
||||||
xse.set_selection(selectionAtom.getAtom());
|
xse.set_selection(selectionAtom.getAtom());
|
||||||
@ -733,51 +589,133 @@ public class XSelection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkChange(XSelectionEvent xse) {
|
private boolean handleMultipleRequest(final long requestor, long property) {
|
||||||
if (targetsPropertyAtoms == null || targetsPropertyAtoms.isEmpty()) {
|
if (XlibWrapper.None == property) {
|
||||||
// We are not tracking changes.
|
// The property cannot be None for a MULTIPLE request.
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
long propertyAtom = xse.get_property();
|
boolean conversionSucceeded = false;
|
||||||
long[] formats = null;
|
|
||||||
|
|
||||||
if (propertyAtom == XlibWrapper.None) {
|
// First retrieve the list of requested targets.
|
||||||
// We threat None property atom as "empty selection".
|
WindowPropertyGetter wpg =
|
||||||
formats = new long[0];
|
new WindowPropertyGetter(requestor, XAtom.get(property),
|
||||||
} else if (!targetsPropertyAtoms.contains(Long.valueOf(propertyAtom))) {
|
0, MAX_LENGTH, false,
|
||||||
return;
|
XlibWrapper.AnyPropertyType);
|
||||||
} else {
|
|
||||||
WindowPropertyGetter targetsGetter =
|
|
||||||
new WindowPropertyGetter(XWindow.getXAWTRootWindow().getWindow(),
|
|
||||||
XAtom.get(propertyAtom), 0, MAX_LENGTH,
|
|
||||||
true, XlibWrapper.AnyPropertyType);
|
|
||||||
try {
|
try {
|
||||||
targetsGetter.execute();
|
wpg.execute();
|
||||||
formats = getFormats(targetsGetter);
|
|
||||||
|
if (wpg.getActualFormat() == 32 && (wpg.getNumberOfItems() % 2) == 0) {
|
||||||
|
final long count = wpg.getNumberOfItems() / 2;
|
||||||
|
final long pairsPtr = wpg.getData();
|
||||||
|
boolean writeBack = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
long target = Native.getLong(pairsPtr, 2 * i);
|
||||||
|
long prop = Native.getLong(pairsPtr, 2 * i + 1);
|
||||||
|
|
||||||
|
if (!convertAndStore(requestor, target, prop)) {
|
||||||
|
// To report failure, we should replace the
|
||||||
|
// target atom with 0 in the MULTIPLE property.
|
||||||
|
Native.putLong(pairsPtr, 2 * i, 0);
|
||||||
|
writeBack = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (writeBack) {
|
||||||
|
XToolkit.awtLock();
|
||||||
|
try {
|
||||||
|
XlibWrapper.XChangeProperty(XToolkit.getDisplay(),
|
||||||
|
requestor,
|
||||||
|
property,
|
||||||
|
wpg.getActualType(),
|
||||||
|
wpg.getActualFormat(),
|
||||||
|
XlibWrapper.PropModeReplace,
|
||||||
|
wpg.getData(),
|
||||||
|
wpg.getNumberOfItems());
|
||||||
} finally {
|
} finally {
|
||||||
targetsGetter.dispose();
|
XToolkit.awtUnlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conversionSucceeded = true;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
wpg.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return conversionSucceeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleTargetsRequest(long property, long requestor)
|
||||||
|
throws IllegalStateException
|
||||||
|
{
|
||||||
|
boolean conversionSucceeded = false;
|
||||||
|
// Use a local copy to avoid synchronization.
|
||||||
|
long[] formatsLocal = formats;
|
||||||
|
|
||||||
|
if (formatsLocal == null) {
|
||||||
|
throw new IllegalStateException("Not an owner.");
|
||||||
|
}
|
||||||
|
|
||||||
|
long nativeDataPtr = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final int count = formatsLocal.length;
|
||||||
|
final int dataFormat = 32;
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
nativeDataPtr = Native.allocateLongArray(count);
|
||||||
|
Native.put(nativeDataPtr, formatsLocal);
|
||||||
|
}
|
||||||
|
|
||||||
|
conversionSucceeded = true;
|
||||||
|
|
||||||
|
XToolkit.awtLock();
|
||||||
|
try {
|
||||||
|
XlibWrapper.XChangeProperty(XToolkit.getDisplay(), requestor,
|
||||||
|
property, XAtom.XA_ATOM, dataFormat,
|
||||||
|
XlibWrapper.PropModeReplace,
|
||||||
|
nativeDataPtr, count);
|
||||||
|
} finally {
|
||||||
|
XToolkit.awtUnlock();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (nativeDataPtr != 0) {
|
||||||
|
XlibWrapper.unsafe.freeMemory(nativeDataPtr);
|
||||||
|
nativeDataPtr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return conversionSucceeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireOwnershipChanges(final boolean isOwner) {
|
||||||
|
OwnershipListener l = null;
|
||||||
|
synchronized (stateLock) {
|
||||||
|
l = ownershipListener;
|
||||||
|
}
|
||||||
|
if (null != l) {
|
||||||
|
l.ownershipChanged(isOwner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XAtom selectionAtom = XAtom.get(xse.get_selection());
|
void registerOwershipListener(OwnershipListener l) {
|
||||||
XSelection selection = getSelection(selectionAtom);
|
synchronized (stateLock) {
|
||||||
if (selection != null) {
|
ownershipListener = l;
|
||||||
selection.isSelectionNotifyProcessed = true;
|
|
||||||
if (selection.clipboard != null) {
|
|
||||||
selection.clipboard.checkChange(formats);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unregisterOwnershipListener() {
|
||||||
|
synchronized (stateLock) {
|
||||||
|
ownershipListener = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SelectionEventHandler implements XEventDispatcher {
|
private static class SelectionEventHandler implements XEventDispatcher {
|
||||||
public void dispatchEvent(XEvent ev) {
|
public void dispatchEvent(XEvent ev) {
|
||||||
switch (ev.get_type()) {
|
switch (ev.get_type()) {
|
||||||
case XlibWrapper.SelectionNotify: {
|
case XlibWrapper.SelectionNotify: {
|
||||||
XSelectionEvent xse = ev.get_xselection();
|
|
||||||
checkChange(xse);
|
|
||||||
XToolkit.awtLock();
|
XToolkit.awtLock();
|
||||||
try {
|
try {
|
||||||
|
XSelectionEvent xse = ev.get_xselection();
|
||||||
// Ignore the SelectionNotify event if it is not the response to our last request.
|
// Ignore the SelectionNotify event if it is not the response to our last request.
|
||||||
if (propertyGetter != null && xse.get_time() == lastRequestServerTime) {
|
if (propertyGetter != null && xse.get_time() == lastRequestServerTime) {
|
||||||
// The property will be None in case of convertion failure.
|
// The property will be None in case of convertion failure.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,11 +25,9 @@
|
|||||||
package sun.awt.X11;
|
package sun.awt.X11;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.*;
|
import java.awt.event.InputEvent;
|
||||||
import java.awt.peer.*;
|
import java.awt.event.MouseEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.awt.datatransfer.Clipboard;
|
||||||
import sun.awt.*;
|
|
||||||
import java.util.*;
|
|
||||||
import java.awt.dnd.DragSource;
|
import java.awt.dnd.DragSource;
|
||||||
import java.awt.dnd.DragGestureListener;
|
import java.awt.dnd.DragGestureListener;
|
||||||
import java.awt.dnd.DragGestureEvent;
|
import java.awt.dnd.DragGestureEvent;
|
||||||
@ -37,20 +35,27 @@ import java.awt.dnd.DragGestureRecognizer;
|
|||||||
import java.awt.dnd.MouseDragGestureRecognizer;
|
import java.awt.dnd.MouseDragGestureRecognizer;
|
||||||
import java.awt.dnd.InvalidDnDOperationException;
|
import java.awt.dnd.InvalidDnDOperationException;
|
||||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||||
import java.awt.image.*;
|
|
||||||
import java.security.*;
|
|
||||||
import java.awt.im.InputMethodHighlight;
|
import java.awt.im.InputMethodHighlight;
|
||||||
import java.awt.im.spi.InputMethodDescriptor;
|
import java.awt.im.spi.InputMethodDescriptor;
|
||||||
import java.awt.datatransfer.Clipboard;
|
import java.awt.image.ColorModel;
|
||||||
|
import java.awt.peer.*;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.UIDefaults;
|
import javax.swing.UIDefaults;
|
||||||
import java.util.logging.*;
|
import sun.awt.*;
|
||||||
import sun.font.FontManager;
|
import sun.font.FontManager;
|
||||||
import sun.misc.PerformanceLogger;
|
import sun.misc.PerformanceLogger;
|
||||||
import sun.print.PrintJob2D;
|
import sun.print.PrintJob2D;
|
||||||
import java.lang.reflect.*;
|
|
||||||
|
|
||||||
public class XToolkit extends UNIXToolkit implements Runnable, XConstants {
|
public final class XToolkit extends UNIXToolkit implements Runnable, XConstants
|
||||||
|
{
|
||||||
private static Logger log = Logger.getLogger("sun.awt.X11.XToolkit");
|
private static Logger log = Logger.getLogger("sun.awt.X11.XToolkit");
|
||||||
private static Logger eventLog = Logger.getLogger("sun.awt.X11.event.XToolkit");
|
private static Logger eventLog = Logger.getLogger("sun.awt.X11.event.XToolkit");
|
||||||
private static final Logger timeoutTaskLog = Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit");
|
private static final Logger timeoutTaskLog = Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit");
|
||||||
@ -1871,9 +1876,7 @@ public class XToolkit extends UNIXToolkit implements Runnable, XConstants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAlwaysOnTopSupported() {
|
public boolean isAlwaysOnTopSupported() {
|
||||||
Iterator iter = XWM.getWM().getProtocols(XLayerProtocol.class).iterator();
|
for (XLayerProtocol proto : XWM.getWM().getProtocols(XLayerProtocol.class)) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
XLayerProtocol proto = (XLayerProtocol)iter.next();
|
|
||||||
if (proto.supportsLayer(XLayerProtocol.LAYER_ALWAYS_ON_TOP)) {
|
if (proto.supportsLayer(XLayerProtocol.LAYER_ALWAYS_ON_TOP)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,11 +31,8 @@ import java.awt.peer.TrayIconPeer;
|
|||||||
import sun.awt.*;
|
import sun.awt.*;
|
||||||
import java.awt.image.*;
|
import java.awt.image.*;
|
||||||
import java.text.BreakIterator;
|
import java.text.BreakIterator;
|
||||||
import java.util.Vector;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.AbstractQueue;
|
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
@ -629,7 +626,7 @@ public class XTrayIconPeer implements TrayIconPeer {
|
|||||||
final static int TOOLTIP_MAX_LENGTH = 64;
|
final static int TOOLTIP_MAX_LENGTH = 64;
|
||||||
final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5;
|
final static int TOOLTIP_MOUSE_CURSOR_INDENT = 5;
|
||||||
final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220);
|
final static Color TOOLTIP_BACKGROUND_COLOR = new Color(255, 255, 220);
|
||||||
final static Font TOOLTIP_TEXT_FONT = XWindow.defaultFont;
|
final static Font TOOLTIP_TEXT_FONT = XWindow.getDefaultFont();
|
||||||
|
|
||||||
Tooltip(XTrayIconPeer xtiPeer, Frame parent) {
|
Tooltip(XTrayIconPeer xtiPeer, Frame parent) {
|
||||||
super(parent, Color.black);
|
super(parent, Color.black);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,20 +31,23 @@
|
|||||||
package sun.awt.X11;
|
package sun.awt.X11;
|
||||||
|
|
||||||
import sun.misc.Unsafe;
|
import sun.misc.Unsafe;
|
||||||
import java.util.regex.*;
|
import java.awt.Insets;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.LogManager;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.awt.Insets;
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class incapsulating knowledge about window managers in general
|
* Class incapsulating knowledge about window managers in general
|
||||||
* Descendants should provide some information about specific window manager.
|
* Descendants should provide some information about specific window manager.
|
||||||
*/
|
*/
|
||||||
class XWM implements MWMConstants, XUtilConstants {
|
final class XWM implements MWMConstants, XUtilConstants
|
||||||
|
{
|
||||||
|
|
||||||
private final static Logger log = Logger.getLogger("sun.awt.X11.XWM");
|
private final static Logger log = Logger.getLogger("sun.awt.X11.XWM");
|
||||||
private final static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWM");
|
private final static Logger insLog = Logger.getLogger("sun.awt.X11.insets.XWM");
|
||||||
@ -1026,21 +1029,21 @@ class XWM implements MWMConstants, XUtilConstants {
|
|||||||
/*****************************************************************************\
|
/*****************************************************************************\
|
||||||
* Protocols support
|
* Protocols support
|
||||||
*/
|
*/
|
||||||
HashMap<Class<?>, Collection<XProtocol>> protocolsMap = new HashMap<Class<?>, Collection<XProtocol>>();
|
private HashMap<Class<?>, Collection<?>> protocolsMap = new HashMap<Class<?>, Collection<?>>();
|
||||||
/**
|
/**
|
||||||
* Returns all protocols supporting given protocol interface
|
* Returns all protocols supporting given protocol interface
|
||||||
*/
|
*/
|
||||||
Collection<XProtocol> getProtocols(Class protocolInterface) {
|
<T> Collection<T> getProtocols(Class<T> protocolInterface) {
|
||||||
Collection<XProtocol> res = protocolsMap.get(protocolInterface);
|
Collection<T> res = (Collection<T>) protocolsMap.get(protocolInterface);
|
||||||
if (res != null) {
|
if (res != null) {
|
||||||
return (Collection<XProtocol>)res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
return new LinkedList<XProtocol>();
|
return new LinkedList<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addProtocol(Class protocolInterface, XProtocol protocol) {
|
private <T> void addProtocol(Class<T> protocolInterface, T protocol) {
|
||||||
Collection<XProtocol> protocols = getProtocols(protocolInterface);
|
Collection<T> protocols = getProtocols(protocolInterface);
|
||||||
protocols.add(protocol);
|
protocols.add(protocol);
|
||||||
protocolsMap.put(protocolInterface, protocols);
|
protocolsMap.put(protocolInterface, protocols);
|
||||||
}
|
}
|
||||||
@ -1085,9 +1088,7 @@ class XWM implements MWMConstants, XUtilConstants {
|
|||||||
}
|
}
|
||||||
/* FALLTROUGH */
|
/* FALLTROUGH */
|
||||||
case Frame.MAXIMIZED_BOTH:
|
case Frame.MAXIMIZED_BOTH:
|
||||||
Iterator iter = getProtocols(XStateProtocol.class).iterator();
|
for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
XStateProtocol proto = (XStateProtocol)iter.next();
|
|
||||||
if (proto.supportsState(state)) {
|
if (proto.supportsState(state)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1105,10 +1106,8 @@ class XWM implements MWMConstants, XUtilConstants {
|
|||||||
|
|
||||||
|
|
||||||
int getExtendedState(XWindowPeer window) {
|
int getExtendedState(XWindowPeer window) {
|
||||||
Iterator iter = getProtocols(XStateProtocol.class).iterator();
|
|
||||||
int state = 0;
|
int state = 0;
|
||||||
while (iter.hasNext()) {
|
for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
|
||||||
XStateProtocol proto = (XStateProtocol)iter.next();
|
|
||||||
state |= proto.getState(window);
|
state |= proto.getState(window);
|
||||||
}
|
}
|
||||||
if (state != 0) {
|
if (state != 0) {
|
||||||
@ -1127,18 +1126,17 @@ class XWM implements MWMConstants, XUtilConstants {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if property change is a window state protocol message.
|
* Check if property change is a window state protocol message.
|
||||||
* If it is - return the new state as Integer, otherwise return null
|
|
||||||
*/
|
*/
|
||||||
Integer isStateChange(XDecoratedPeer window, XPropertyEvent e) {
|
boolean isStateChange(XDecoratedPeer window, XPropertyEvent e) {
|
||||||
if (!window.isShowing()) {
|
if (!window.isShowing()) {
|
||||||
stateLog.finer("Window is not showing");
|
stateLog.finer("Window is not showing");
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wm_state = window.getWMState();
|
int wm_state = window.getWMState();
|
||||||
if (wm_state == XlibWrapper.WithdrawnState) {
|
if (wm_state == XlibWrapper.WithdrawnState) {
|
||||||
stateLog.finer("WithdrawnState");
|
stateLog.finer("WithdrawnState");
|
||||||
return null;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
stateLog.finer("Window WM_STATE is " + wm_state);
|
stateLog.finer("Window WM_STATE is " + wm_state);
|
||||||
}
|
}
|
||||||
@ -1147,26 +1145,26 @@ class XWM implements MWMConstants, XUtilConstants {
|
|||||||
is_state_change = true;
|
is_state_change = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator iter = getProtocols(XStateProtocol.class).iterator();
|
for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
XStateProtocol proto = (XStateProtocol)iter.next();
|
|
||||||
is_state_change |= proto.isStateChange(e);
|
is_state_change |= proto.isStateChange(e);
|
||||||
|
stateLog.finest(proto + ": is state changed = " + is_state_change);
|
||||||
|
}
|
||||||
|
return is_state_change;
|
||||||
}
|
}
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
if (is_state_change) {
|
/*
|
||||||
|
* Returns current state (including extended) of a given window.
|
||||||
|
*/
|
||||||
|
int getState(XDecoratedPeer window) {
|
||||||
|
int res = 0;
|
||||||
|
final int wm_state = window.getWMState();
|
||||||
if (wm_state == XlibWrapper.IconicState) {
|
if (wm_state == XlibWrapper.IconicState) {
|
||||||
res = Frame.ICONIFIED;
|
res = Frame.ICONIFIED;
|
||||||
} else {
|
} else {
|
||||||
res = Frame.NORMAL;
|
res = Frame.NORMAL;
|
||||||
}
|
}
|
||||||
res |= getExtendedState(window);
|
res |= getExtendedState(window);
|
||||||
}
|
return res;
|
||||||
if (is_state_change) {
|
|
||||||
return Integer.valueOf(res);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************\
|
/*****************************************************************************\
|
||||||
@ -1180,9 +1178,7 @@ class XWM implements MWMConstants, XUtilConstants {
|
|||||||
* in XLayerProtocol
|
* in XLayerProtocol
|
||||||
*/
|
*/
|
||||||
void setLayer(XWindowPeer window, int layer) {
|
void setLayer(XWindowPeer window, int layer) {
|
||||||
Iterator iter = getProtocols(XLayerProtocol.class).iterator();
|
for (XLayerProtocol proto : getProtocols(XLayerProtocol.class)) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
XLayerProtocol proto = (XLayerProtocol)iter.next();
|
|
||||||
if (proto.supportsLayer(layer)) {
|
if (proto.supportsLayer(layer)) {
|
||||||
proto.setLayer(window, layer);
|
proto.setLayer(window, layer);
|
||||||
}
|
}
|
||||||
@ -1191,9 +1187,7 @@ class XWM implements MWMConstants, XUtilConstants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setExtendedState(XWindowPeer window, int state) {
|
void setExtendedState(XWindowPeer window, int state) {
|
||||||
Iterator iter = getProtocols(XStateProtocol.class).iterator();
|
for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
XStateProtocol proto = (XStateProtocol)iter.next();
|
|
||||||
if (proto.supportsState(state)) {
|
if (proto.supportsState(state)) {
|
||||||
proto.setState(window, state);
|
proto.setState(window, state);
|
||||||
break;
|
break;
|
||||||
@ -1239,9 +1233,7 @@ class XWM implements MWMConstants, XUtilConstants {
|
|||||||
void unshadeKludge(XDecoratedPeer window) {
|
void unshadeKludge(XDecoratedPeer window) {
|
||||||
assert(window.isShowing());
|
assert(window.isShowing());
|
||||||
|
|
||||||
Iterator iter = getProtocols(XStateProtocol.class).iterator();
|
for (XStateProtocol proto : getProtocols(XStateProtocol.class)) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
XStateProtocol proto = (XStateProtocol)iter.next();
|
|
||||||
proto.unshadeKludge(window);
|
proto.unshadeKludge(window);
|
||||||
}
|
}
|
||||||
XToolkit.XSync();
|
XToolkit.XSync();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -92,8 +92,16 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
|||||||
SurfaceData surfaceData;
|
SurfaceData surfaceData;
|
||||||
|
|
||||||
XRepaintArea paintArea;
|
XRepaintArea paintArea;
|
||||||
|
|
||||||
// fallback default font object
|
// fallback default font object
|
||||||
final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
|
private static Font defaultFont;
|
||||||
|
|
||||||
|
static synchronized Font getDefaultFont() {
|
||||||
|
if (null == defaultFont) {
|
||||||
|
defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
|
||||||
|
}
|
||||||
|
return defaultFont;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keeps all buttons which were pressed at the time of the last mouse
|
* Keeps all buttons which were pressed at the time of the last mouse
|
||||||
@ -333,7 +341,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
|||||||
}
|
}
|
||||||
Font font = afont;
|
Font font = afont;
|
||||||
if (font == null) {
|
if (font == null) {
|
||||||
font = defaultFont;
|
font = XWindow.getDefaultFont();
|
||||||
}
|
}
|
||||||
return new SunGraphics2D(surfData, fgColor, bgColor, font);
|
return new SunGraphics2D(surfData, fgColor, bgColor, font);
|
||||||
}
|
}
|
||||||
@ -902,13 +910,11 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
|||||||
|
|
||||||
super.handleConfigureNotifyEvent(xev);
|
super.handleConfigureNotifyEvent(xev);
|
||||||
insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}",
|
insLog.log(Level.FINER, "Configure, {0}, event disabled: {1}",
|
||||||
new Object[] {xev, isEventDisabled(xev)});
|
new Object[] {xev.get_xconfigure(), isEventDisabled(xev)});
|
||||||
if (isEventDisabled(xev)) {
|
if (isEventDisabled(xev)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long eventWindow = xev.get_xany().get_window();
|
|
||||||
|
|
||||||
// if ( Check if it's a resize, a move, or a stacking order change )
|
// if ( Check if it's a resize, a move, or a stacking order change )
|
||||||
// {
|
// {
|
||||||
Rectangle bounds = getBounds();
|
Rectangle bounds = getBounds();
|
||||||
@ -982,7 +988,6 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
|||||||
// called directly from this package, unlike handleKeyRelease.
|
// called directly from this package, unlike handleKeyRelease.
|
||||||
// un-final it if you need to override it in a subclass.
|
// un-final it if you need to override it in a subclass.
|
||||||
final void handleKeyPress(XKeyEvent ev) {
|
final void handleKeyPress(XKeyEvent ev) {
|
||||||
int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
|
|
||||||
long keysym[] = new long[2];
|
long keysym[] = new long[2];
|
||||||
char unicodeKey = 0;
|
char unicodeKey = 0;
|
||||||
keysym[0] = NoSymbol;
|
keysym[0] = NoSymbol;
|
||||||
@ -1066,7 +1071,6 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
|
|||||||
}
|
}
|
||||||
// un-private it if you need to call it from elsewhere
|
// un-private it if you need to call it from elsewhere
|
||||||
private void handleKeyRelease(XKeyEvent ev) {
|
private void handleKeyRelease(XKeyEvent ev) {
|
||||||
int keycode = java.awt.event.KeyEvent.VK_UNDEFINED;
|
|
||||||
long keysym[] = new long[2];
|
long keysym[] = new long[2];
|
||||||
char unicodeKey = 0;
|
char unicodeKey = 0;
|
||||||
keysym[0] = NoSymbol;
|
keysym[0] = NoSymbol;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -112,9 +112,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
|||||||
PARENT_WINDOW, Long.valueOf(0)}));
|
PARENT_WINDOW, Long.valueOf(0)}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// fallback default font object
|
|
||||||
static Font defaultFont;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This constant defines icon size recommended for using.
|
* This constant defines icon size recommended for using.
|
||||||
* Apparently, we should use XGetIconSizes which should
|
* Apparently, we should use XGetIconSizes which should
|
||||||
@ -162,10 +159,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
|||||||
|
|
||||||
Font f = target.getFont();
|
Font f = target.getFont();
|
||||||
if (f == null) {
|
if (f == null) {
|
||||||
if (defaultFont == null) {
|
f = XWindow.getDefaultFont();
|
||||||
defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
|
|
||||||
}
|
|
||||||
f = defaultFont;
|
|
||||||
target.setFont(f);
|
target.setFont(f);
|
||||||
// we should not call setFont because it will call a repaint
|
// we should not call setFont because it will call a repaint
|
||||||
// which the peer may not be ready to do yet.
|
// which the peer may not be ready to do yet.
|
||||||
@ -188,6 +182,9 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
|||||||
|
|
||||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
GraphicsConfiguration gc = getGraphicsConfiguration();
|
||||||
((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
|
((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
|
||||||
|
|
||||||
|
Rectangle bounds = (Rectangle)(params.get(BOUNDS));
|
||||||
|
params.put(BOUNDS, constrainBounds(bounds.x, bounds.y, bounds.width, bounds.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initWMProtocols() {
|
private void initWMProtocols() {
|
||||||
@ -437,6 +434,56 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
|||||||
return ownerPeer;
|
return ownerPeer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method is overriden at the XDecoratedPeer to handle
|
||||||
|
// decorated windows a bit differently.
|
||||||
|
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||||
|
// We don't restrict the setBounds() operation if the code is trusted.
|
||||||
|
if (!hasWarningWindow()) {
|
||||||
|
return new Rectangle(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The window bounds should be within the visible part of the screen
|
||||||
|
int newX = x;
|
||||||
|
int newY = y;
|
||||||
|
int newW = width;
|
||||||
|
int newH = height;
|
||||||
|
|
||||||
|
// Now check each point is within the visible part of the screen
|
||||||
|
GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
|
||||||
|
Rectangle sB = gc.getBounds();
|
||||||
|
Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
|
||||||
|
|
||||||
|
int screenX = sB.x + sIn.left;
|
||||||
|
int screenY = sB.y + sIn.top;
|
||||||
|
int screenW = sB.width - sIn.left - sIn.right;
|
||||||
|
int screenH = sB.height - sIn.top - sIn.bottom;
|
||||||
|
|
||||||
|
|
||||||
|
// First make sure the size is withing the visible part of the screen
|
||||||
|
if (newW > screenW) {
|
||||||
|
newW = screenW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newH > screenH) {
|
||||||
|
newH = screenH;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tweak the location if needed
|
||||||
|
if (newX < screenX) {
|
||||||
|
newX = screenX;
|
||||||
|
} else if (newX + newW > screenX + screenW) {
|
||||||
|
newX = screenX + screenW - newW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newY < screenY) {
|
||||||
|
newY = screenY;
|
||||||
|
} else if (newY + newH > screenY + screenH) {
|
||||||
|
newY = screenY + screenH - newH;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Rectangle(newX, newY, newW, newH);
|
||||||
|
}
|
||||||
|
|
||||||
//Fix for 6318144: PIT:Setting Min Size bigger than current size enlarges
|
//Fix for 6318144: PIT:Setting Min Size bigger than current size enlarges
|
||||||
//the window but fails to revalidate, Sol-CDE
|
//the window but fails to revalidate, Sol-CDE
|
||||||
//This bug is regression for
|
//This bug is regression for
|
||||||
@ -445,10 +492,14 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
|||||||
//Note that this function is overriden in XDecoratedPeer so event
|
//Note that this function is overriden in XDecoratedPeer so event
|
||||||
//posting is not changing for decorated peers
|
//posting is not changing for decorated peers
|
||||||
public void setBounds(int x, int y, int width, int height, int op) {
|
public void setBounds(int x, int y, int width, int height, int op) {
|
||||||
|
Rectangle newBounds = constrainBounds(x, y, width, height);
|
||||||
|
|
||||||
XToolkit.awtLock();
|
XToolkit.awtLock();
|
||||||
try {
|
try {
|
||||||
Rectangle oldBounds = getBounds();
|
Rectangle oldBounds = getBounds();
|
||||||
super.setBounds(x, y, width, height, op);
|
|
||||||
|
super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
|
||||||
|
|
||||||
Rectangle bounds = getBounds();
|
Rectangle bounds = getBounds();
|
||||||
|
|
||||||
XSizeHints hints = getHints();
|
XSizeHints hints = getHints();
|
||||||
@ -1035,7 +1086,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
|
|||||||
return !(target instanceof Frame || target instanceof Dialog);
|
return !(target instanceof Frame || target instanceof Dialog);
|
||||||
}
|
}
|
||||||
boolean hasWarningWindow() {
|
boolean hasWarningWindow() {
|
||||||
return warningWindow != null;
|
return ((Window)target).getWarningString() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The height of menu bar window
|
// The height of menu bar window
|
||||||
|
@ -102,4 +102,9 @@ class MDialogPeer extends MWindowPeer implements DialogPeer, MInputMethodControl
|
|||||||
public void blockWindows(java.util.List<Window> toBlock) {
|
public void blockWindows(java.util.List<Window> toBlock) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
final boolean isTargetUndecorated() {
|
||||||
|
return ((Dialog)target).isUndecorated();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,4 +204,10 @@ public class MEmbeddedFramePeer extends MFramePeer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public native Rectangle getBoundsPrivate();
|
public native Rectangle getBoundsPrivate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||||
|
// We don't constrain the bounds of the EmbeddedFrames
|
||||||
|
return new Rectangle(x, y, width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -503,4 +503,9 @@ class MFramePeer extends MWindowPeer implements FramePeer, MInputMethodControl {
|
|||||||
public Rectangle getBoundsPrivate() {
|
public Rectangle getBoundsPrivate() {
|
||||||
return getBounds();
|
return getBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
final boolean isTargetUndecorated() {
|
||||||
|
return ((Frame)target).isUndecorated();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,12 @@ DisplayChangedListener {
|
|||||||
insets.right = getInset("awt.frame.rightInset", -1);
|
insets.right = getInset("awt.frame.rightInset", -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle bounds = target.getBounds();
|
||||||
|
sysX = bounds.x;
|
||||||
|
sysY = bounds.y;
|
||||||
|
sysW = bounds.width;
|
||||||
|
sysH = bounds.height;
|
||||||
|
|
||||||
super.init(target);
|
super.init(target);
|
||||||
InputMethodManager imm = InputMethodManager.getInstance();
|
InputMethodManager imm = InputMethodManager.getInstance();
|
||||||
String menuString = imm.getTriggerMenuString();
|
String menuString = imm.getTriggerMenuString();
|
||||||
@ -150,6 +156,7 @@ DisplayChangedListener {
|
|||||||
|
|
||||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
GraphicsConfiguration gc = getGraphicsConfiguration();
|
||||||
((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
|
((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Support for multiple icons is not implemented in MAWT */
|
/* Support for multiple icons is not implemented in MAWT */
|
||||||
@ -246,6 +253,8 @@ DisplayChangedListener {
|
|||||||
// NOTE: This method may be called by privileged threads.
|
// NOTE: This method may be called by privileged threads.
|
||||||
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||||
public void handleResize(int width, int height) {
|
public void handleResize(int width, int height) {
|
||||||
|
sysW = width;
|
||||||
|
sysH = height;
|
||||||
|
|
||||||
// REMIND: Is this secure? Can client code subclass input method?
|
// REMIND: Is this secure? Can client code subclass input method?
|
||||||
if (!tcList.isEmpty() &&
|
if (!tcList.isEmpty() &&
|
||||||
@ -268,6 +277,8 @@ DisplayChangedListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void handleMoved(int x, int y) {
|
public void handleMoved(int x, int y) {
|
||||||
|
sysX = x;
|
||||||
|
sysY = y;
|
||||||
postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
|
postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,4 +516,87 @@ DisplayChangedListener {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final boolean hasWarningWindow() {
|
||||||
|
return ((Window)target).getWarningString() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is overriden at Dialog and Frame peers.
|
||||||
|
boolean isTargetUndecorated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private volatile int sysX = 0;
|
||||||
|
private volatile int sysY = 0;
|
||||||
|
private volatile int sysW = 0;
|
||||||
|
private volatile int sysH = 0;
|
||||||
|
|
||||||
|
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||||
|
// We don't restrict the setBounds() operation if the code is trusted.
|
||||||
|
if (!hasWarningWindow()) {
|
||||||
|
return new Rectangle(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
int newX = x;
|
||||||
|
int newY = y;
|
||||||
|
int newW = width;
|
||||||
|
int newH = height;
|
||||||
|
|
||||||
|
GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
|
||||||
|
Rectangle sB = gc.getBounds();
|
||||||
|
Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
|
||||||
|
|
||||||
|
int screenW = sB.width - sIn.left - sIn.right;
|
||||||
|
int screenH = sB.height - sIn.top - sIn.bottom;
|
||||||
|
|
||||||
|
// If it's undecorated or is not currently visible,
|
||||||
|
// then check each point is within the visible part of the screen
|
||||||
|
if (!target.isVisible() || isTargetUndecorated()) {
|
||||||
|
int screenX = sB.x + sIn.left;
|
||||||
|
int screenY = sB.y + sIn.top;
|
||||||
|
|
||||||
|
// First make sure the size is withing the visible part of the screen
|
||||||
|
if (newW > screenW) {
|
||||||
|
newW = screenW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newH > screenH) {
|
||||||
|
newH = screenH;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tweak the location if needed
|
||||||
|
if (newX < screenX) {
|
||||||
|
newX = screenX;
|
||||||
|
} else if (newX + newW > screenX + screenW) {
|
||||||
|
newX = screenX + screenW - newW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newY < screenY) {
|
||||||
|
newY = screenY;
|
||||||
|
} else if (newY + newH > screenY + screenH) {
|
||||||
|
newY = screenY + screenH - newH;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int maxW = Math.max(screenW, sysW);
|
||||||
|
int maxH = Math.max(screenH, sysH);
|
||||||
|
|
||||||
|
// Make sure the size is withing the visible part of the screen
|
||||||
|
// OR is less that the current size of the window.
|
||||||
|
if (newW > maxW) {
|
||||||
|
newW = maxW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newH > maxH) {
|
||||||
|
newH = maxH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Rectangle(newX, newY, newW, newH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBounds(int x, int y, int width, int height, int op) {
|
||||||
|
Rectangle newBounds = constrainBounds(x, y, width, height);
|
||||||
|
super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -108,11 +108,18 @@ class WDialogPeer extends WWindowPeer implements DialogPeer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isTargetUndecorated() {
|
||||||
|
return ((Dialog)target).isUndecorated();
|
||||||
|
}
|
||||||
|
|
||||||
public void reshape(int x, int y, int width, int height) {
|
public void reshape(int x, int y, int width, int height) {
|
||||||
|
Rectangle newBounds = constrainBounds(x, y, width, height);
|
||||||
|
|
||||||
if (((Dialog)target).isUndecorated()) {
|
if (((Dialog)target).isUndecorated()) {
|
||||||
super.reshape(x,y,width,height);
|
super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
|
||||||
} else {
|
} else {
|
||||||
reshapeFrame(x,y,width,height);
|
reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,4 +65,10 @@ public class WEmbeddedFramePeer extends WFramePeer {
|
|||||||
public native Rectangle getBoundsPrivate();
|
public native Rectangle getBoundsPrivate();
|
||||||
|
|
||||||
public native void synthesizeWmActivate(boolean doActivate);
|
public native void synthesizeWmActivate(boolean doActivate);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||||
|
// We don't constrain the bounds of the EmbeddedFrames
|
||||||
|
return new Rectangle(x, y, width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,11 +64,18 @@ class WFramePeer extends WWindowPeer implements FramePeer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isTargetUndecorated() {
|
||||||
|
return ((Frame)target).isUndecorated();
|
||||||
|
}
|
||||||
|
|
||||||
public void reshape(int x, int y, int width, int height) {
|
public void reshape(int x, int y, int width, int height) {
|
||||||
|
Rectangle newBounds = constrainBounds(x, y, width, height);
|
||||||
|
|
||||||
if (((Frame)target).isUndecorated()) {
|
if (((Frame)target).isUndecorated()) {
|
||||||
super.reshape(x,y,width,height);
|
super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
|
||||||
} else {
|
} else {
|
||||||
reshapeFrame(x,y,width,height);
|
reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -30,8 +30,12 @@ abstract class WObjectPeer {
|
|||||||
initIDs();
|
initIDs();
|
||||||
}
|
}
|
||||||
|
|
||||||
long pData; // The Windows handle for the native widget.
|
// The Windows handle for the native widget.
|
||||||
Object target; // The associated AWT object.
|
long pData;
|
||||||
|
// if the native peer has been destroyed
|
||||||
|
boolean destroyed = false;
|
||||||
|
// The associated AWT object.
|
||||||
|
Object target;
|
||||||
|
|
||||||
private volatile boolean disposed;
|
private volatile boolean disposed;
|
||||||
|
|
||||||
|
@ -434,6 +434,97 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer {
|
|||||||
private native void nativeGrab();
|
private native void nativeGrab();
|
||||||
private native void nativeUngrab();
|
private native void nativeUngrab();
|
||||||
|
|
||||||
|
private final boolean hasWarningWindow() {
|
||||||
|
return ((Window)target).getWarningString() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isTargetUndecorated() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are the peer bounds. They get updated at:
|
||||||
|
// 1. the WWindowPeer.setBounds() method.
|
||||||
|
// 2. the native code (on WM_SIZE/WM_MOVE)
|
||||||
|
private volatile int sysX = 0;
|
||||||
|
private volatile int sysY = 0;
|
||||||
|
private volatile int sysW = 0;
|
||||||
|
private volatile int sysH = 0;
|
||||||
|
|
||||||
|
Rectangle constrainBounds(int x, int y, int width, int height) {
|
||||||
|
// We don't restrict the setBounds() operation if the code is trusted.
|
||||||
|
if (!hasWarningWindow()) {
|
||||||
|
return new Rectangle(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
int newX = x;
|
||||||
|
int newY = y;
|
||||||
|
int newW = width;
|
||||||
|
int newH = height;
|
||||||
|
|
||||||
|
GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration();
|
||||||
|
Rectangle sB = gc.getBounds();
|
||||||
|
Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc);
|
||||||
|
|
||||||
|
int screenW = sB.width - sIn.left - sIn.right;
|
||||||
|
int screenH = sB.height - sIn.top - sIn.bottom;
|
||||||
|
|
||||||
|
// If it's undecorated or is not currently visible
|
||||||
|
if (!((Window)target).isVisible() || isTargetUndecorated()) {
|
||||||
|
// Now check each point is within the visible part of the screen
|
||||||
|
int screenX = sB.x + sIn.left;
|
||||||
|
int screenY = sB.y + sIn.top;
|
||||||
|
|
||||||
|
// First make sure the size is withing the visible part of the screen
|
||||||
|
if (newW > screenW) {
|
||||||
|
newW = screenW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newH > screenH) {
|
||||||
|
newH = screenH;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tweak the location if needed
|
||||||
|
if (newX < screenX) {
|
||||||
|
newX = screenX;
|
||||||
|
} else if (newX + newW > screenX + screenW) {
|
||||||
|
newX = screenX + screenW - newW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newY < screenY) {
|
||||||
|
newY = screenY;
|
||||||
|
} else if (newY + newH > screenY + screenH) {
|
||||||
|
newY = screenY + screenH - newH;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int maxW = Math.max(screenW, sysW);
|
||||||
|
int maxH = Math.max(screenH, sysH);
|
||||||
|
|
||||||
|
// Make sure the size is withing the visible part of the screen
|
||||||
|
// OR less that the current size of the window.
|
||||||
|
if (newW > maxW) {
|
||||||
|
newW = maxW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newH > maxH) {
|
||||||
|
newH = maxH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Rectangle(newX, newY, newW, newH);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBounds(int x, int y, int width, int height, int op) {
|
||||||
|
Rectangle newBounds = constrainBounds(x, y, width, height);
|
||||||
|
|
||||||
|
sysX = newBounds.x;
|
||||||
|
sysY = newBounds.y;
|
||||||
|
sysW = newBounds.width;
|
||||||
|
sysH = newBounds.height;
|
||||||
|
|
||||||
|
super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The method maps the list of the active windows to the window's AppContext,
|
* The method maps the list of the active windows to the window's AppContext,
|
||||||
* then the method registers ActiveWindowListener, GuiDisposedListener listeners;
|
* then the method registers ActiveWindowListener, GuiDisposedListener listeners;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -47,7 +47,7 @@ typedef AwtObject* PDATA;
|
|||||||
JNI_CHECK_NULL_GOTO(peer, "peer", where); \
|
JNI_CHECK_NULL_GOTO(peer, "peer", where); \
|
||||||
pData = JNI_GET_PDATA(peer); \
|
pData = JNI_GET_PDATA(peer); \
|
||||||
if (pData == NULL) { \
|
if (pData == NULL) { \
|
||||||
JNU_ThrowNullPointerException(env, "null pData"); \
|
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
|
||||||
goto where; \
|
goto where; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ typedef AwtObject* PDATA;
|
|||||||
JNI_CHECK_NULL_RETURN(peer, "peer"); \
|
JNI_CHECK_NULL_RETURN(peer, "peer"); \
|
||||||
pData = JNI_GET_PDATA(peer); \
|
pData = JNI_GET_PDATA(peer); \
|
||||||
if (pData == NULL) { \
|
if (pData == NULL) { \
|
||||||
JNU_ThrowNullPointerException(env, "null pData"); \
|
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ typedef AwtObject* PDATA;
|
|||||||
JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \
|
JNI_CHECK_NULL_RETURN_NULL(peer, "peer"); \
|
||||||
pData = JNI_GET_PDATA(peer); \
|
pData = JNI_GET_PDATA(peer); \
|
||||||
if (pData == NULL) { \
|
if (pData == NULL) { \
|
||||||
JNU_ThrowNullPointerException(env, "null pData"); \
|
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@ -105,16 +105,27 @@ typedef AwtObject* PDATA;
|
|||||||
JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \
|
JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val); \
|
||||||
pData = JNI_GET_PDATA(peer); \
|
pData = JNI_GET_PDATA(peer); \
|
||||||
if (pData == NULL) { \
|
if (pData == NULL) { \
|
||||||
JNU_ThrowNullPointerException(env, "null pData"); \
|
THROW_NULL_PDATA_IF_NOT_DESTROYED(peer); \
|
||||||
return val; \
|
return val; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define THROW_NULL_PDATA_IF_NOT_DESTROYED(peer) { \
|
||||||
|
jboolean destroyed = JNI_GET_DESTROYED(peer); \
|
||||||
|
if (destroyed != JNI_TRUE) { \
|
||||||
|
JNU_ThrowNullPointerException(env, "null pData"); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID)
|
#define JNI_GET_PDATA(peer) (PDATA) env->GetLongField(peer, AwtObject::pDataID)
|
||||||
|
#define JNI_GET_DESTROYED(peer) env->GetBooleanField(peer, AwtObject::destroyedID)
|
||||||
|
|
||||||
#define JNI_SET_PDATA(peer, data) env->SetLongField(peer, \
|
#define JNI_SET_PDATA(peer, data) env->SetLongField(peer, \
|
||||||
AwtObject::pDataID, \
|
AwtObject::pDataID, \
|
||||||
(jlong)data)
|
(jlong)data)
|
||||||
|
#define JNI_SET_DESTROYED(peer) env->SetBooleanField(peer, \
|
||||||
|
AwtObject::destroyedID, \
|
||||||
|
JNI_TRUE)
|
||||||
/* /NEW JNI */
|
/* /NEW JNI */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -226,6 +226,8 @@ BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE;
|
|||||||
CriticalSection windowMoveLock;
|
CriticalSection windowMoveLock;
|
||||||
BOOL windowMoveLockHeld = FALSE;
|
BOOL windowMoveLockHeld = FALSE;
|
||||||
|
|
||||||
|
int AwtComponent::sm_wheelRotationAmount = 0;
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* AwtComponent methods
|
* AwtComponent methods
|
||||||
*/
|
*/
|
||||||
@ -2074,6 +2076,8 @@ MsgRouting AwtComponent::WmSetFocus(HWND hWndLostFocus)
|
|||||||
sm_realFocusOpposite = NULL;
|
sm_realFocusOpposite = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sm_wheelRotationAmount = 0;
|
||||||
|
|
||||||
SendFocusEvent(java_awt_event_FocusEvent_FOCUS_GAINED, hWndLostFocus);
|
SendFocusEvent(java_awt_event_FocusEvent_FOCUS_GAINED, hWndLostFocus);
|
||||||
|
|
||||||
return mrDoDefault;
|
return mrDoDefault;
|
||||||
@ -2105,6 +2109,7 @@ MsgRouting AwtComponent::WmKillFocus(HWND hWndGotFocus)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sm_focusOwner = NULL;
|
sm_focusOwner = NULL;
|
||||||
|
sm_wheelRotationAmount = 0;
|
||||||
|
|
||||||
SendFocusEvent(java_awt_event_FocusEvent_FOCUS_LOST, hWndGotFocus);
|
SendFocusEvent(java_awt_event_FocusEvent_FOCUS_LOST, hWndGotFocus);
|
||||||
return mrDoDefault;
|
return mrDoDefault;
|
||||||
@ -2190,8 +2195,11 @@ AwtComponent::AwtSetFocus()
|
|||||||
DWORD fgProcessID;
|
DWORD fgProcessID;
|
||||||
::GetWindowThreadProcessId(fgWindow, &fgProcessID);
|
::GetWindowThreadProcessId(fgWindow, &fgProcessID);
|
||||||
|
|
||||||
if (fgProcessID != ::GetCurrentProcessId()) {
|
if (fgProcessID != ::GetCurrentProcessId()
|
||||||
// fix for 6458497. we shouldn't request focus if it is out of our application.
|
&& !AwtToolkit::GetInstance().IsEmbedderProcessId(fgProcessID))
|
||||||
|
{
|
||||||
|
// fix for 6458497. we shouldn't request focus if it is out of both
|
||||||
|
// our and embedder process.
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2619,9 +2627,13 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y,
|
|||||||
BOOL result;
|
BOOL result;
|
||||||
UINT platformLines;
|
UINT platformLines;
|
||||||
|
|
||||||
|
sm_wheelRotationAmount += wheelRotation;
|
||||||
|
|
||||||
// AWT interprets wheel rotation differently than win32, so we need to
|
// AWT interprets wheel rotation differently than win32, so we need to
|
||||||
// decode wheel amount.
|
// decode wheel amount.
|
||||||
jint newWheelRotation = wheelRotation / (-1 * WHEEL_DELTA);
|
jint roundedWheelRotation = sm_wheelRotationAmount / (-1 * WHEEL_DELTA);
|
||||||
|
jdouble preciseWheelRotation = (jdouble) wheelRotation / (-1 * WHEEL_DELTA);
|
||||||
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|
||||||
if (IS_WIN95 && !IS_WIN98) {
|
if (IS_WIN95 && !IS_WIN98) {
|
||||||
@ -2654,7 +2666,9 @@ MsgRouting AwtComponent::WmMouseWheel(UINT flags, int x, int y,
|
|||||||
|
|
||||||
SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(),
|
SendMouseWheelEvent(java_awt_event_MouseEvent_MOUSE_WHEEL, TimeHelper::getMessageTimeUTC(),
|
||||||
eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType,
|
eventPt.x, eventPt.y, GetJavaModifiers(), 0, 0, scrollType,
|
||||||
scrollLines, newWheelRotation, &msg);
|
scrollLines, roundedWheelRotation, preciseWheelRotation, &msg);
|
||||||
|
|
||||||
|
sm_wheelRotationAmount %= WHEEL_DELTA;
|
||||||
return mrConsume;
|
return mrConsume;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4986,8 +5000,8 @@ void
|
|||||||
AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
|
AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
|
||||||
jint modifiers, jint clickCount,
|
jint modifiers, jint clickCount,
|
||||||
jboolean popupTrigger, jint scrollType,
|
jboolean popupTrigger, jint scrollType,
|
||||||
jint scrollAmount, jint wheelRotation,
|
jint scrollAmount, jint roundedWheelRotation,
|
||||||
MSG *pMsg)
|
jdouble preciseWheelRotation, MSG *pMsg)
|
||||||
{
|
{
|
||||||
/* Code based not so loosely on AwtComponent::SendMouseEvent */
|
/* Code based not so loosely on AwtComponent::SendMouseEvent */
|
||||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||||
@ -5015,7 +5029,7 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
|
|||||||
if (mouseWheelEventConst == NULL) {
|
if (mouseWheelEventConst == NULL) {
|
||||||
mouseWheelEventConst =
|
mouseWheelEventConst =
|
||||||
env->GetMethodID(mouseWheelEventCls, "<init>",
|
env->GetMethodID(mouseWheelEventCls, "<init>",
|
||||||
"(Ljava/awt/Component;IJIIIIZIII)V");
|
"(Ljava/awt/Component;IJIIIIIIZIIID)V");
|
||||||
DASSERT(mouseWheelEventConst);
|
DASSERT(mouseWheelEventConst);
|
||||||
}
|
}
|
||||||
if (env->EnsureLocalCapacity(2) < 0) {
|
if (env->EnsureLocalCapacity(2) < 0) {
|
||||||
@ -5023,14 +5037,16 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
|
|||||||
}
|
}
|
||||||
jobject target = GetTarget(env);
|
jobject target = GetTarget(env);
|
||||||
DTRACE_PRINTLN("creating MWE in JNI");
|
DTRACE_PRINTLN("creating MWE in JNI");
|
||||||
|
|
||||||
jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls,
|
jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls,
|
||||||
mouseWheelEventConst,
|
mouseWheelEventConst,
|
||||||
target,
|
target,
|
||||||
id, when, modifiers,
|
id, when, modifiers,
|
||||||
x+insets.left, y+insets.top,
|
x+insets.left, y+insets.top,
|
||||||
|
0, 0,
|
||||||
clickCount, popupTrigger,
|
clickCount, popupTrigger,
|
||||||
scrollType, scrollAmount,
|
scrollType, scrollAmount,
|
||||||
wheelRotation);
|
roundedWheelRotation, preciseWheelRotation);
|
||||||
if (safe_ExceptionOccurred(env)) {
|
if (safe_ExceptionOccurred(env)) {
|
||||||
env->ExceptionDescribe();
|
env->ExceptionDescribe();
|
||||||
env->ExceptionClear();
|
env->ExceptionClear();
|
||||||
@ -5400,6 +5416,7 @@ void AwtComponent::UnlinkObjects()
|
|||||||
if (m_peerObject) {
|
if (m_peerObject) {
|
||||||
env->SetLongField(m_peerObject, AwtComponent::hwndID, 0);
|
env->SetLongField(m_peerObject, AwtComponent::hwndID, 0);
|
||||||
JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));
|
JNI_SET_PDATA(m_peerObject, static_cast<PDATA>(NULL));
|
||||||
|
JNI_SET_DESTROYED(m_peerObject);
|
||||||
env->DeleteGlobalRef(m_peerObject);
|
env->DeleteGlobalRef(m_peerObject);
|
||||||
m_peerObject = NULL;
|
m_peerObject = NULL;
|
||||||
}
|
}
|
||||||
@ -5408,7 +5425,13 @@ void AwtComponent::UnlinkObjects()
|
|||||||
void AwtComponent::Enable(BOOL bEnable)
|
void AwtComponent::Enable(BOOL bEnable)
|
||||||
{
|
{
|
||||||
sm_suppressFocusAndActivation = TRUE;
|
sm_suppressFocusAndActivation = TRUE;
|
||||||
|
|
||||||
|
if (bEnable && IsTopLevel()) {
|
||||||
|
// we should not enable blocked toplevels
|
||||||
|
bEnable = !::IsWindow(AwtWindow::GetModalBlocker(GetHWnd()));
|
||||||
|
}
|
||||||
::EnableWindow(GetHWnd(), bEnable);
|
::EnableWindow(GetHWnd(), bEnable);
|
||||||
|
|
||||||
sm_suppressFocusAndActivation = FALSE;
|
sm_suppressFocusAndActivation = FALSE;
|
||||||
CriticalSection::Lock l(GetLock());
|
CriticalSection::Lock l(GetLock());
|
||||||
VerifyState();
|
VerifyState();
|
||||||
|
@ -392,7 +392,7 @@ public:
|
|||||||
jint modifiers, jint clickCount,
|
jint modifiers, jint clickCount,
|
||||||
jboolean popupTrigger, jint scrollType,
|
jboolean popupTrigger, jint scrollType,
|
||||||
jint scrollAmount, jint wheelRotation,
|
jint scrollAmount, jint wheelRotation,
|
||||||
MSG *msg = NULL);
|
jdouble preciseWheelRotation, MSG *msg = NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate and initialize a new java.awt.event.FocusEvent, and
|
* Allocate and initialize a new java.awt.event.FocusEvent, and
|
||||||
@ -785,7 +785,9 @@ private:
|
|||||||
int windowMoveLockPosCX;
|
int windowMoveLockPosCX;
|
||||||
int windowMoveLockPosCY;
|
int windowMoveLockPosCY;
|
||||||
|
|
||||||
private:
|
// 6524352: support finer-resolution
|
||||||
|
static int sm_wheelRotationAmount;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The association list of children's IDs and corresponding components.
|
* The association list of children's IDs and corresponding components.
|
||||||
* Some components like Choice or List are required their sizes while
|
* Some components like Choice or List are required their sizes while
|
||||||
|
@ -273,6 +273,10 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode,
|
|||||||
{
|
{
|
||||||
HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
|
HWND blocker = AwtWindow::GetModalBlocker(AwtComponent::GetTopLevelParentForWindow(hWnd));
|
||||||
HWND topMostBlocker = blocker;
|
HWND topMostBlocker = blocker;
|
||||||
|
HWND prevForegroundWindow = ::GetForegroundWindow();
|
||||||
|
if (::IsWindow(blocker)) {
|
||||||
|
::BringWindowToTop(hWnd);
|
||||||
|
}
|
||||||
while (::IsWindow(blocker)) {
|
while (::IsWindow(blocker)) {
|
||||||
topMostBlocker = blocker;
|
topMostBlocker = blocker;
|
||||||
::BringWindowToTop(blocker);
|
::BringWindowToTop(blocker);
|
||||||
@ -282,7 +286,7 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode,
|
|||||||
// no beep/flash if the mouse was clicked in the taskbar menu
|
// no beep/flash if the mouse was clicked in the taskbar menu
|
||||||
// or the dialog is currently inactive
|
// or the dialog is currently inactive
|
||||||
if ((::WindowFromPoint(mhs->pt) == hWnd) &&
|
if ((::WindowFromPoint(mhs->pt) == hWnd) &&
|
||||||
(::GetForegroundWindow() == topMostBlocker))
|
(prevForegroundWindow == topMostBlocker))
|
||||||
{
|
{
|
||||||
::MessageBeep(MB_OK);
|
::MessageBeep(MB_OK);
|
||||||
// some heuristics: 3 times x 64 milliseconds
|
// some heuristics: 3 times x 64 milliseconds
|
||||||
@ -292,6 +296,7 @@ LRESULT CALLBACK AwtDialog::MouseHookProc(int nCode,
|
|||||||
::BringWindowToTop(topMostBlocker);
|
::BringWindowToTop(topMostBlocker);
|
||||||
::SetForegroundWindow(topMostBlocker);
|
::SetForegroundWindow(topMostBlocker);
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -221,8 +221,7 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent)
|
|||||||
|
|
||||||
// Update target's dimensions to reflect this embedded window.
|
// Update target's dimensions to reflect this embedded window.
|
||||||
::GetClientRect(frame->m_hwnd, &rect);
|
::GetClientRect(frame->m_hwnd, &rect);
|
||||||
::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect,
|
::MapWindowPoints(frame->m_hwnd, hwndParent, (LPPOINT)&rect, 2);
|
||||||
2);
|
|
||||||
|
|
||||||
env->SetIntField(target, AwtComponent::xID, rect.left);
|
env->SetIntField(target, AwtComponent::xID, rect.left);
|
||||||
env->SetIntField(target, AwtComponent::yID, rect.top);
|
env->SetIntField(target, AwtComponent::yID, rect.top);
|
||||||
@ -231,6 +230,7 @@ AwtFrame* AwtFrame::Create(jobject self, jobject parent)
|
|||||||
env->SetIntField(target, AwtComponent::heightID,
|
env->SetIntField(target, AwtComponent::heightID,
|
||||||
rect.bottom-rect.top);
|
rect.bottom-rect.top);
|
||||||
frame->InitPeerGraphicsConfig(env, self);
|
frame->InitPeerGraphicsConfig(env, self);
|
||||||
|
AwtToolkit::GetInstance().RegisterEmbedderProcessId(hwndParent);
|
||||||
} else {
|
} else {
|
||||||
jint state = env->GetIntField(target, AwtFrame::stateID);
|
jint state = env->GetIntField(target, AwtFrame::stateID);
|
||||||
DWORD exStyle;
|
DWORD exStyle;
|
||||||
@ -408,8 +408,9 @@ MsgRouting AwtFrame::WmShowWindow(BOOL show, UINT status)
|
|||||||
* message. This breaks Java focus. To workaround the problem we
|
* message. This breaks Java focus. To workaround the problem we
|
||||||
* set the toplevel being shown foreground programmatically.
|
* set the toplevel being shown foreground programmatically.
|
||||||
* The fix is localized to non-foreground process case only.
|
* The fix is localized to non-foreground process case only.
|
||||||
|
* (See also: 6599270)
|
||||||
*/
|
*/
|
||||||
if (show == TRUE && status == 0) {
|
if (!IsEmbeddedFrame() && show == TRUE && status == 0) {
|
||||||
HWND fgHWnd = ::GetForegroundWindow();
|
HWND fgHWnd = ::GetForegroundWindow();
|
||||||
if (fgHWnd != NULL) {
|
if (fgHWnd != NULL) {
|
||||||
DWORD fgProcessID;
|
DWORD fgProcessID;
|
||||||
@ -495,7 +496,7 @@ MsgRouting AwtFrame::WmMouseMove(UINT flags, int x, int y) {
|
|||||||
|
|
||||||
::SetWindowPos(GetHWnd(), NULL, r.left, r.top,
|
::SetWindowPos(GetHWnd(), NULL, r.left, r.top,
|
||||||
r.right-r.left, r.bottom-r.top,
|
r.right-r.left, r.bottom-r.top,
|
||||||
SWP_NOACTIVATE | SWP_NOSENDCHANGING | SWP_NOZORDER |
|
SWP_NOACTIVATE | SWP_NOZORDER |
|
||||||
SWP_NOCOPYBITS | SWP_DEFERERASE);
|
SWP_NOCOPYBITS | SWP_DEFERERASE);
|
||||||
}
|
}
|
||||||
return mrConsume;
|
return mrConsume;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -39,6 +39,7 @@ static BOOL reportEvents = FALSE;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
jfieldID AwtObject::pDataID;
|
jfieldID AwtObject::pDataID;
|
||||||
|
jfieldID AwtObject::destroyedID;
|
||||||
jfieldID AwtObject::targetID;
|
jfieldID AwtObject::targetID;
|
||||||
jclass AwtObject::wObjectPeerClass;
|
jclass AwtObject::wObjectPeerClass;
|
||||||
jmethodID AwtObject::getPeerForTargetMID;
|
jmethodID AwtObject::getPeerForTargetMID;
|
||||||
@ -223,6 +224,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) {
|
|||||||
|
|
||||||
AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls);
|
AwtObject::wObjectPeerClass = (jclass)env->NewGlobalRef(cls);
|
||||||
AwtObject::pDataID = env->GetFieldID(cls, "pData", "J");
|
AwtObject::pDataID = env->GetFieldID(cls, "pData", "J");
|
||||||
|
AwtObject::destroyedID = env->GetFieldID(cls, "destroyed", "Z");
|
||||||
AwtObject::targetID = env->GetFieldID(cls, "target",
|
AwtObject::targetID = env->GetFieldID(cls, "target",
|
||||||
"Ljava/lang/Object;");
|
"Ljava/lang/Object;");
|
||||||
|
|
||||||
@ -233,6 +235,7 @@ Java_sun_awt_windows_WObjectPeer_initIDs(JNIEnv *env, jclass cls) {
|
|||||||
AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;");
|
AwtObject::createErrorID = env->GetFieldID(cls, "createError", "Ljava/lang/Error;");
|
||||||
|
|
||||||
DASSERT(AwtObject::pDataID != NULL);
|
DASSERT(AwtObject::pDataID != NULL);
|
||||||
|
DASSERT(AwtObject::destroyedID != NULL);
|
||||||
DASSERT(AwtObject::targetID != NULL);
|
DASSERT(AwtObject::targetID != NULL);
|
||||||
DASSERT(AwtObject::getPeerForTargetMID != NULL);
|
DASSERT(AwtObject::getPeerForTargetMID != NULL);
|
||||||
DASSERT(AwtObject::createErrorID != NULL);
|
DASSERT(AwtObject::createErrorID != NULL);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -51,6 +51,7 @@ public:
|
|||||||
|
|
||||||
/* sun.awt.windows.WObjectPeer field and method ids */
|
/* sun.awt.windows.WObjectPeer field and method ids */
|
||||||
static jfieldID pDataID;
|
static jfieldID pDataID;
|
||||||
|
static jfieldID destroyedID;
|
||||||
static jfieldID targetID;
|
static jfieldID targetID;
|
||||||
|
|
||||||
static jmethodID getPeerForTargetMID;
|
static jmethodID getPeerForTargetMID;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -354,6 +354,7 @@ AwtToolkit::AwtToolkit() {
|
|||||||
m_dllHandle = NULL;
|
m_dllHandle = NULL;
|
||||||
|
|
||||||
m_displayChanged = FALSE;
|
m_displayChanged = FALSE;
|
||||||
|
m_embedderProcessID = 0;
|
||||||
|
|
||||||
// XXX: keyboard mapping should really be moved out of AwtComponent
|
// XXX: keyboard mapping should really be moved out of AwtComponent
|
||||||
AwtComponent::InitDynamicKeyMapTable();
|
AwtComponent::InitDynamicKeyMapTable();
|
||||||
@ -1442,49 +1443,17 @@ void hang_if_shutdown(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// for now we support only one embedder, but should be ready for future
|
||||||
* Returns a reference to the class java.awt.Component.
|
void AwtToolkit::RegisterEmbedderProcessId(HWND embedder)
|
||||||
*/
|
|
||||||
jclass
|
|
||||||
getComponentClass(JNIEnv *env)
|
|
||||||
{
|
{
|
||||||
static jclass componentCls = NULL;
|
if (m_embedderProcessID) {
|
||||||
|
// we already set embedder process and do not expect
|
||||||
// get global reference of java/awt/Component class (run only once)
|
// two different processes to embed the same AwtToolkit
|
||||||
if (componentCls == NULL) {
|
return;
|
||||||
jclass componentClsLocal = env->FindClass("java/awt/Component");
|
|
||||||
DASSERT(componentClsLocal != NULL);
|
|
||||||
if (componentClsLocal == NULL) {
|
|
||||||
/* exception already thrown */
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
componentCls = (jclass)env->NewGlobalRef(componentClsLocal);
|
|
||||||
env->DeleteLocalRef(componentClsLocal);
|
|
||||||
}
|
|
||||||
return componentCls;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
embedder = ::GetAncestor(embedder, GA_ROOT);
|
||||||
/*
|
::GetWindowThreadProcessId(embedder, &m_embedderProcessID);
|
||||||
* Returns a reference to the class java.awt.MenuComponent.
|
|
||||||
*/
|
|
||||||
jclass
|
|
||||||
getMenuComponentClass(JNIEnv *env)
|
|
||||||
{
|
|
||||||
static jclass menuComponentCls = NULL;
|
|
||||||
|
|
||||||
// get global reference of java/awt/MenuComponent class (run only once)
|
|
||||||
if (menuComponentCls == NULL) {
|
|
||||||
jclass menuComponentClsLocal = env->FindClass("java/awt/MenuComponent");
|
|
||||||
DASSERT(menuComponentClsLocal != NULL);
|
|
||||||
if (menuComponentClsLocal == NULL) {
|
|
||||||
/* exception already thrown */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
menuComponentCls = (jclass)env->NewGlobalRef(menuComponentClsLocal);
|
|
||||||
env->DeleteLocalRef(menuComponentClsLocal);
|
|
||||||
}
|
|
||||||
return menuComponentCls;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEnv* AwtToolkit::m_env;
|
JNIEnv* AwtToolkit::m_env;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -426,10 +426,17 @@ private:
|
|||||||
*/
|
*/
|
||||||
private:
|
private:
|
||||||
BOOL m_displayChanged; /* Tracks displayChanged events */
|
BOOL m_displayChanged; /* Tracks displayChanged events */
|
||||||
|
// 0 means we are not embedded.
|
||||||
|
DWORD m_embedderProcessID;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BOOL HasDisplayChanged() { return m_displayChanged; }
|
BOOL HasDisplayChanged() { return m_displayChanged; }
|
||||||
void ResetDisplayChanged() { m_displayChanged = FALSE; }
|
void ResetDisplayChanged() { m_displayChanged = FALSE; }
|
||||||
|
void RegisterEmbedderProcessId(HWND);
|
||||||
|
BOOL IsEmbedderProcessId(const DWORD processID) const
|
||||||
|
{
|
||||||
|
return m_embedderProcessID && (processID == m_embedderProcessID);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static JNIEnv *m_env;
|
static JNIEnv *m_env;
|
||||||
|
@ -125,6 +125,11 @@ jfieldID AwtWindow::autoRequestFocusID;
|
|||||||
jclass AwtWindow::wwindowPeerCls;
|
jclass AwtWindow::wwindowPeerCls;
|
||||||
jmethodID AwtWindow::getActiveWindowsMID;
|
jmethodID AwtWindow::getActiveWindowsMID;
|
||||||
|
|
||||||
|
jfieldID AwtWindow::sysXID;
|
||||||
|
jfieldID AwtWindow::sysYID;
|
||||||
|
jfieldID AwtWindow::sysWID;
|
||||||
|
jfieldID AwtWindow::sysHID;
|
||||||
|
|
||||||
int AwtWindow::ms_instanceCounter = 0;
|
int AwtWindow::ms_instanceCounter = 0;
|
||||||
HHOOK AwtWindow::ms_hCBTFilter;
|
HHOOK AwtWindow::ms_hCBTFilter;
|
||||||
AwtWindow * AwtWindow::m_grabbedWindow = NULL;
|
AwtWindow * AwtWindow::m_grabbedWindow = NULL;
|
||||||
@ -180,7 +185,6 @@ void AwtWindow::Dispose()
|
|||||||
}
|
}
|
||||||
|
|
||||||
::RemoveProp(GetHWnd(), ModalBlockerProp);
|
::RemoveProp(GetHWnd(), ModalBlockerProp);
|
||||||
::RemoveProp(GetHWnd(), ModalSaveWSEXProp);
|
|
||||||
|
|
||||||
if (m_grabbedWindow == this) {
|
if (m_grabbedWindow == this) {
|
||||||
Ungrab();
|
Ungrab();
|
||||||
@ -330,10 +334,13 @@ LRESULT CALLBACK AwtWindow::CBTFilter(int nCode, WPARAM wParam, LPARAM lParam)
|
|||||||
if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) {
|
if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) {
|
||||||
AwtComponent *comp = AwtComponent::GetComponent((HWND)wParam);
|
AwtComponent *comp = AwtComponent::GetComponent((HWND)wParam);
|
||||||
|
|
||||||
if (comp != NULL && comp->IsTopLevel() && !((AwtWindow*)comp)->IsFocusableWindow()) {
|
if (comp != NULL && comp->IsTopLevel()) {
|
||||||
|
AwtWindow* win = (AwtWindow*)comp;
|
||||||
|
if (!win->IsFocusableWindow() || win->m_filterFocusAndActivation) {
|
||||||
return 1; // Don't change focus/activation.
|
return 1; // Don't change focus/activation.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam);
|
return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1053,6 +1060,8 @@ MsgRouting AwtWindow::WmMove(int x, int y)
|
|||||||
|
|
||||||
(env)->SetIntField(target, AwtComponent::xID, rect.left);
|
(env)->SetIntField(target, AwtComponent::xID, rect.left);
|
||||||
(env)->SetIntField(target, AwtComponent::yID, rect.top);
|
(env)->SetIntField(target, AwtComponent::yID, rect.top);
|
||||||
|
(env)->SetIntField(peer, AwtWindow::sysXID, rect.left);
|
||||||
|
(env)->SetIntField(peer, AwtWindow::sysYID, rect.top);
|
||||||
SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
|
SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED);
|
||||||
|
|
||||||
env->DeleteLocalRef(target);
|
env->DeleteLocalRef(target);
|
||||||
@ -1116,6 +1125,11 @@ MsgRouting AwtWindow::WmSize(UINT type, int w, int h)
|
|||||||
|
|
||||||
(env)->SetIntField(target, AwtComponent::widthID, newWidth);
|
(env)->SetIntField(target, AwtComponent::widthID, newWidth);
|
||||||
(env)->SetIntField(target, AwtComponent::heightID, newHeight);
|
(env)->SetIntField(target, AwtComponent::heightID, newHeight);
|
||||||
|
|
||||||
|
jobject peer = GetPeer(env);
|
||||||
|
(env)->SetIntField(peer, AwtWindow::sysWID, newWidth);
|
||||||
|
(env)->SetIntField(peer, AwtWindow::sysHID, newHeight);
|
||||||
|
|
||||||
if (!AwtWindow::IsResizing()) {
|
if (!AwtWindow::IsResizing()) {
|
||||||
WindowResized();
|
WindowResized();
|
||||||
}
|
}
|
||||||
@ -1455,20 +1469,17 @@ void AwtWindow::SetModalBlocker(HWND window, HWND blocker) {
|
|||||||
if (!::IsWindow(window)) {
|
if (!::IsWindow(window)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DWORD exStyle = ::GetWindowLong(window, GWL_EXSTYLE);
|
|
||||||
if (::IsWindow(blocker)) {
|
if (::IsWindow(blocker)) {
|
||||||
// save WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
|
|
||||||
DWORD saveStyle = exStyle & (AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW);
|
|
||||||
::SetProp(window, ModalSaveWSEXProp, reinterpret_cast<HANDLE>(saveStyle));
|
|
||||||
::SetWindowLong(window, GWL_EXSTYLE, (exStyle | AWT_WS_EX_NOACTIVATE) & ~WS_EX_APPWINDOW);
|
|
||||||
::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker));
|
::SetProp(window, ModalBlockerProp, reinterpret_cast<HANDLE>(blocker));
|
||||||
|
::EnableWindow(window, FALSE);
|
||||||
} else {
|
} else {
|
||||||
// restore WS_EX_NOACTIVATE and WS_EX_APPWINDOW styles
|
|
||||||
DWORD saveStyle = reinterpret_cast<DWORD>(::GetProp(window, ModalSaveWSEXProp));
|
|
||||||
::SetWindowLong(window, GWL_EXSTYLE,
|
|
||||||
(exStyle & ~(AWT_WS_EX_NOACTIVATE | WS_EX_APPWINDOW)) | saveStyle);
|
|
||||||
::RemoveProp(window, ModalSaveWSEXProp);
|
|
||||||
::RemoveProp(window, ModalBlockerProp);
|
::RemoveProp(window, ModalBlockerProp);
|
||||||
|
AwtComponent *comp = AwtComponent::GetComponent(window);
|
||||||
|
// we don't expect to be called with non-java HWNDs
|
||||||
|
DASSERT(comp && comp->IsTopLevel());
|
||||||
|
// we should not unblock disabled toplevels
|
||||||
|
::EnableWindow(window, comp->isEnabled());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1754,17 +1765,22 @@ void AwtWindow::_ReshapeFrame(void *param)
|
|||||||
// Fix for 4459064 : do not enforce thresholds for embedded frames
|
// Fix for 4459064 : do not enforce thresholds for embedded frames
|
||||||
if (!p->IsEmbeddedFrame())
|
if (!p->IsEmbeddedFrame())
|
||||||
{
|
{
|
||||||
|
jobject peer = p->GetPeer(env);
|
||||||
int minWidth = ::GetSystemMetrics(SM_CXMIN);
|
int minWidth = ::GetSystemMetrics(SM_CXMIN);
|
||||||
int minHeight = ::GetSystemMetrics(SM_CYMIN);
|
int minHeight = ::GetSystemMetrics(SM_CYMIN);
|
||||||
if (w < minWidth)
|
if (w < minWidth)
|
||||||
{
|
{
|
||||||
env->SetIntField(target, AwtComponent::widthID,
|
env->SetIntField(target, AwtComponent::widthID,
|
||||||
w = minWidth);
|
w = minWidth);
|
||||||
|
env->SetIntField(peer, AwtWindow::sysWID,
|
||||||
|
w);
|
||||||
}
|
}
|
||||||
if (h < minHeight)
|
if (h < minHeight)
|
||||||
{
|
{
|
||||||
env->SetIntField(target, AwtComponent::heightID,
|
env->SetIntField(target, AwtComponent::heightID,
|
||||||
h = minHeight);
|
h = minHeight);
|
||||||
|
env->SetIntField(peer, AwtWindow::sysHID,
|
||||||
|
h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
env->DeleteLocalRef(target);
|
env->DeleteLocalRef(target);
|
||||||
@ -2148,6 +2164,11 @@ Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv *env, jclass cls)
|
|||||||
env->GetStaticMethodID(cls, "getActiveWindowHandles", "()[J");
|
env->GetStaticMethodID(cls, "getActiveWindowHandles", "()[J");
|
||||||
DASSERT(AwtWindow::getActiveWindowsMID != NULL);
|
DASSERT(AwtWindow::getActiveWindowsMID != NULL);
|
||||||
|
|
||||||
|
AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I");
|
||||||
|
AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I");
|
||||||
|
AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I");
|
||||||
|
AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I");
|
||||||
|
|
||||||
CATCH_BAD_ALLOC;
|
CATCH_BAD_ALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
// property name tagging windows disabled by modality
|
// property name tagging windows disabled by modality
|
||||||
static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp");
|
static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp");
|
||||||
static LPCTSTR ModalSaveWSEXProp = TEXT("SunAwtModalSaveWSEXProp");
|
|
||||||
static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp");
|
static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp");
|
||||||
|
|
||||||
#ifndef WH_MOUSE_LL
|
#ifndef WH_MOUSE_LL
|
||||||
@ -63,6 +62,12 @@ public:
|
|||||||
/* long[] getActiveWindowHandles() method in WWindowPeer */
|
/* long[] getActiveWindowHandles() method in WWindowPeer */
|
||||||
static jmethodID getActiveWindowsMID;
|
static jmethodID getActiveWindowsMID;
|
||||||
|
|
||||||
|
// The coordinates at the peer.
|
||||||
|
static jfieldID sysXID;
|
||||||
|
static jfieldID sysYID;
|
||||||
|
static jfieldID sysWID;
|
||||||
|
static jfieldID sysHID;
|
||||||
|
|
||||||
AwtWindow();
|
AwtWindow();
|
||||||
virtual ~AwtWindow();
|
virtual ~AwtWindow();
|
||||||
|
|
||||||
|
@ -0,0 +1,413 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@test
|
||||||
|
@bug 6581927
|
||||||
|
@summary Non-focusable frame should honor the size of the frame buttons/decorations when resizing
|
||||||
|
@library ../../regtesthelpers
|
||||||
|
@build Util
|
||||||
|
@author anthony.petrov@...: area=awt.toplevel
|
||||||
|
@run main NonFocusableResizableTooSmall
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NonFocusableResizableTooSmall.java
|
||||||
|
*
|
||||||
|
* summary: Non-focusable frame should honor the size of the frame buttons/decorations when resizing
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import test.java.awt.regtesthelpers.Util;
|
||||||
|
|
||||||
|
public class NonFocusableResizableTooSmall
|
||||||
|
{
|
||||||
|
|
||||||
|
//*** test-writer defined static variables go here ***
|
||||||
|
|
||||||
|
|
||||||
|
private static void init()
|
||||||
|
{
|
||||||
|
//*** Create instructions for the user here ***
|
||||||
|
|
||||||
|
String[] instructions =
|
||||||
|
{
|
||||||
|
"This is an AUTOMATIC test, simply wait until it is done.",
|
||||||
|
"The result (passed or failed) will be shown in the",
|
||||||
|
"message window below."
|
||||||
|
};
|
||||||
|
Sysout.createDialog( );
|
||||||
|
Sysout.printInstructions( instructions );
|
||||||
|
|
||||||
|
final Frame frame = new Frame();
|
||||||
|
frame.setFocusableWindowState(false);
|
||||||
|
frame.setSize(200, 100);
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
final Robot robot = Util.createRobot();
|
||||||
|
robot.setAutoDelay(20);
|
||||||
|
|
||||||
|
// To be sure the window is shown and packed
|
||||||
|
Util.waitForIdle(robot);
|
||||||
|
|
||||||
|
final Insets insets = frame.getInsets();
|
||||||
|
System.out.println("The insets of the frame: " + insets);
|
||||||
|
if (insets.right == 0 || insets.bottom == 0) {
|
||||||
|
System.out.println("The test environment must have non-zero right & bottom insets!");
|
||||||
|
pass();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's move the mouse pointer to the bottom-right coner of the frame (the "size-grip")
|
||||||
|
final Rectangle bounds1 = frame.getBounds();
|
||||||
|
System.out.println("The bounds before resizing: " + bounds1);
|
||||||
|
|
||||||
|
robot.mouseMove(bounds1.x + bounds1.width - 1, bounds1.y + bounds1.height - 1);
|
||||||
|
|
||||||
|
// ... and start resizing to some very small
|
||||||
|
robot.mousePress( InputEvent.BUTTON1_MASK );
|
||||||
|
|
||||||
|
// Now resize the frame so that the width is smaller
|
||||||
|
// than the widths of the left and the right borders.
|
||||||
|
// The sum of widths of the icon of the frame + the control-buttons
|
||||||
|
// (close, minimize, etc.) should be definitely larger!
|
||||||
|
robot.mouseMove(bounds1.x + insets.left + insets.right - 5, bounds1.y + bounds1.height - 1);
|
||||||
|
Util.waitForIdle(robot);
|
||||||
|
|
||||||
|
robot.mouseRelease( InputEvent.BUTTON1_MASK );
|
||||||
|
|
||||||
|
Util.waitForIdle(robot);
|
||||||
|
|
||||||
|
// Check the current bounds of the frame
|
||||||
|
final Rectangle bounds2 = frame.getBounds();
|
||||||
|
System.out.println("The bounds after resizing: " + bounds2);
|
||||||
|
|
||||||
|
if (bounds2.width <= (insets.left + insets.right)) {
|
||||||
|
fail("The frame has been resized to very small.");
|
||||||
|
}
|
||||||
|
pass();
|
||||||
|
}//End init()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************
|
||||||
|
* Standard Test Machinery Section
|
||||||
|
* DO NOT modify anything in this section -- it's a
|
||||||
|
* standard chunk of code which has all of the
|
||||||
|
* synchronisation necessary for the test harness.
|
||||||
|
* By keeping it the same in all tests, it is easier
|
||||||
|
* to read and understand someone else's test, as
|
||||||
|
* well as insuring that all tests behave correctly
|
||||||
|
* with the test harness.
|
||||||
|
* There is a section following this for test-
|
||||||
|
* classes
|
||||||
|
******************************************************/
|
||||||
|
private static boolean theTestPassed = false;
|
||||||
|
private static boolean testGeneratedInterrupt = false;
|
||||||
|
private static String failureMessage = "";
|
||||||
|
|
||||||
|
private static Thread mainThread = null;
|
||||||
|
|
||||||
|
private static int sleepTime = 300000;
|
||||||
|
|
||||||
|
// Not sure about what happens if multiple of this test are
|
||||||
|
// instantiated in the same VM. Being static (and using
|
||||||
|
// static vars), it aint gonna work. Not worrying about
|
||||||
|
// it for now.
|
||||||
|
public static void main( String args[] ) throws InterruptedException
|
||||||
|
{
|
||||||
|
mainThread = Thread.currentThread();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
catch( TestPassedException e )
|
||||||
|
{
|
||||||
|
//The test passed, so just return from main and harness will
|
||||||
|
// interepret this return as a pass
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//At this point, neither test pass nor test fail has been
|
||||||
|
// called -- either would have thrown an exception and ended the
|
||||||
|
// test, so we know we have multiple threads.
|
||||||
|
|
||||||
|
//Test involves other threads, so sleep and wait for them to
|
||||||
|
// called pass() or fail()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep( sleepTime );
|
||||||
|
//Timed out, so fail the test
|
||||||
|
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
//The test harness may have interrupted the test. If so, rethrow the exception
|
||||||
|
// so that the harness gets it and deals with it.
|
||||||
|
if( ! testGeneratedInterrupt ) throw e;
|
||||||
|
|
||||||
|
//reset flag in case hit this code more than once for some reason (just safety)
|
||||||
|
testGeneratedInterrupt = false;
|
||||||
|
|
||||||
|
if ( theTestPassed == false )
|
||||||
|
{
|
||||||
|
throw new RuntimeException( failureMessage );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}//main
|
||||||
|
|
||||||
|
public static synchronized void setTimeoutTo( int seconds )
|
||||||
|
{
|
||||||
|
sleepTime = seconds * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void pass()
|
||||||
|
{
|
||||||
|
Sysout.println( "The test passed." );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//first check if this is executing in main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//Still in the main thread, so set the flag just for kicks,
|
||||||
|
// and throw a test passed exception which will be caught
|
||||||
|
// and end the test.
|
||||||
|
theTestPassed = true;
|
||||||
|
throw new TestPassedException();
|
||||||
|
}
|
||||||
|
theTestPassed = true;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//pass()
|
||||||
|
|
||||||
|
public static synchronized void fail()
|
||||||
|
{
|
||||||
|
//test writer didn't specify why test failed, so give generic
|
||||||
|
fail( "it just plain failed! :-)" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void fail( String whyFailed )
|
||||||
|
{
|
||||||
|
Sysout.println( "The test failed: " + whyFailed );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//check if this called from main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//If main thread, fail now 'cause not sleeping
|
||||||
|
throw new RuntimeException( whyFailed );
|
||||||
|
}
|
||||||
|
theTestPassed = false;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
failureMessage = whyFailed;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//fail()
|
||||||
|
|
||||||
|
}// class NonFocusableResizableTooSmall
|
||||||
|
|
||||||
|
//This exception is used to exit from any level of call nesting
|
||||||
|
// when it's determined that the test has passed, and immediately
|
||||||
|
// end the test.
|
||||||
|
class TestPassedException extends RuntimeException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*********** End Standard Test Machinery Section **********
|
||||||
|
|
||||||
|
|
||||||
|
//************ Begin classes defined for the test ****************
|
||||||
|
|
||||||
|
// if want to make listeners, here is the recommended place for them, then instantiate
|
||||||
|
// them in init()
|
||||||
|
|
||||||
|
/* Example of a class which may be written as part of a test
|
||||||
|
class NewClass implements anInterface
|
||||||
|
{
|
||||||
|
static int newVar = 0;
|
||||||
|
|
||||||
|
public void eventDispatched(AWTEvent e)
|
||||||
|
{
|
||||||
|
//Counting events to see if we get enough
|
||||||
|
eventCount++;
|
||||||
|
|
||||||
|
if( eventCount == 20 )
|
||||||
|
{
|
||||||
|
//got enough events, so pass
|
||||||
|
|
||||||
|
NonFocusableResizableTooSmall.pass();
|
||||||
|
}
|
||||||
|
else if( tries == 20 )
|
||||||
|
{
|
||||||
|
//tried too many times without getting enough events so fail
|
||||||
|
|
||||||
|
NonFocusableResizableTooSmall.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}// eventDispatched()
|
||||||
|
|
||||||
|
}// NewClass class
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//************** End classes defined for the test *******************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************
|
||||||
|
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 );
|
||||||
|
System.out.println(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 );
|
||||||
|
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,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@test %W% %E%
|
||||||
|
@bug 6598089
|
||||||
|
@summary Tests restoring focus on a single disabled coponent
|
||||||
|
@author Anton Tarasov: area=awt-focus
|
||||||
|
@library ../../regtesthelpers
|
||||||
|
@build Util
|
||||||
|
@run main RestoreFocusOnDisabledComponentTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.applet.Applet;
|
||||||
|
import test.java.awt.regtesthelpers.Util;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The bug is not reproducible on Windows.
|
||||||
|
*/
|
||||||
|
public class RestoreFocusOnDisabledComponentTest extends Applet {
|
||||||
|
Frame frame = new Frame("Frame") {public String toString() {return "FRAME";}};
|
||||||
|
Button b0 = new Button("button0") {public String toString() {return "B-0";}};
|
||||||
|
Button b1 = new Button("button1") {public String toString() {return "B-1";}};
|
||||||
|
volatile int nFocused;
|
||||||
|
Robot robot;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
RestoreFocusOnDisabledComponentTest app = new RestoreFocusOnDisabledComponentTest();
|
||||||
|
app.init();
|
||||||
|
app.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
robot = Util.createRobot();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
frame.add(b0);
|
||||||
|
frame.add(b1);
|
||||||
|
frame.setLayout(new FlowLayout());
|
||||||
|
frame.pack();
|
||||||
|
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
Util.waitForIdle(robot);
|
||||||
|
KeyboardFocusManager.setCurrentKeyboardFocusManager(new DefaultKeyboardFocusManager() {
|
||||||
|
public boolean dispatchEvent(AWTEvent e) {
|
||||||
|
if (e.getID() == FocusEvent.FOCUS_GAINED) {
|
||||||
|
// Trying to emulate timings. b1 should be disabled just by the time it gets
|
||||||
|
// FOCUS_GAINED event. The latter is a result of disabling b0 that initiates
|
||||||
|
// focus auto transfer.
|
||||||
|
if (e.getSource() == b1) {
|
||||||
|
b1.setEnabled(false);
|
||||||
|
|
||||||
|
} else if (e.getSource() == b0) {
|
||||||
|
if (++nFocused > 10) {
|
||||||
|
nFocused = -1;
|
||||||
|
throw new TestFailedException("Focus went into busy loop!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.dispatchEvent(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Initiating focus auto transfer.
|
||||||
|
// Focus will be requested to b1. When FOCUS_GAINED is being dispatched to b1, it will
|
||||||
|
// be disabled. This will trigger focus restoring. Focus will be requested to b0 (the
|
||||||
|
// last opposite component). When FOCUS_GAINED is being dispatched to b0, it will
|
||||||
|
// also be disabled. However, the last opposite component (and the most recent focus owner)
|
||||||
|
// will still be b0. When DKFM initiates focus restoring it should detect restoring
|
||||||
|
// on the same component and break.
|
||||||
|
b0.setEnabled(false);
|
||||||
|
|
||||||
|
Util.waitForIdle(robot);
|
||||||
|
if (nFocused != -1) {
|
||||||
|
System.out.println("Test passed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestFailedException extends RuntimeException {
|
||||||
|
TestFailedException(String msg) {
|
||||||
|
super("Test failed: " + msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
411
jdk/test/java/awt/Mixing/ValidBounds.java
Normal file
411
jdk/test/java/awt/Mixing/ValidBounds.java
Normal file
@ -0,0 +1,411 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@test
|
||||||
|
@bug 6637796
|
||||||
|
@summary Shape should be correctly updated on invalid components
|
||||||
|
@author anthony.petrov@...: area=awt.mixing
|
||||||
|
@library ../regtesthelpers
|
||||||
|
@build Util
|
||||||
|
@run main ValidBounds
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ValidBounds.java
|
||||||
|
*
|
||||||
|
* summary: Shape should be correctly updated on invalid components
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import test.java.awt.regtesthelpers.Util;
|
||||||
|
|
||||||
|
public class ValidBounds
|
||||||
|
{
|
||||||
|
|
||||||
|
static volatile boolean clickPassed = false;
|
||||||
|
|
||||||
|
private static void init()
|
||||||
|
{
|
||||||
|
//*** Create instructions for the user here ***
|
||||||
|
|
||||||
|
String[] instructions =
|
||||||
|
{
|
||||||
|
"This is an AUTOMATIC test, simply wait until it is done.",
|
||||||
|
"The result (passed or failed) will be shown in the",
|
||||||
|
"message window below."
|
||||||
|
};
|
||||||
|
Sysout.createDialog( );
|
||||||
|
Sysout.printInstructions( instructions );
|
||||||
|
|
||||||
|
|
||||||
|
// Create the frame and the button
|
||||||
|
Frame f = new Frame();
|
||||||
|
f.setBounds(100, 100, 400, 300);
|
||||||
|
|
||||||
|
Button b = new Button("OK");
|
||||||
|
|
||||||
|
f.setLayout(null);
|
||||||
|
f.add(b);
|
||||||
|
b.setBounds(50, 50, 200, 50);
|
||||||
|
|
||||||
|
b.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent e) {
|
||||||
|
clickPassed = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
f.setVisible(true);
|
||||||
|
|
||||||
|
// Let's make the button much smaller first...
|
||||||
|
Robot robot = Util.createRobot();
|
||||||
|
robot.setAutoDelay(20);
|
||||||
|
|
||||||
|
Util.waitForIdle(robot);
|
||||||
|
|
||||||
|
b.setBounds(50, 50, 5, 5);
|
||||||
|
Util.waitForIdle(robot);
|
||||||
|
|
||||||
|
// ... and now let's enlarge it.
|
||||||
|
b.setBounds(50, 50, 200, 50);
|
||||||
|
Util.waitForIdle(robot);
|
||||||
|
|
||||||
|
// If the button doesn't receive the click, it means that the test
|
||||||
|
// failed: the shape of the button was not enlarged.
|
||||||
|
Point heavyLoc = b.getLocationOnScreen();
|
||||||
|
robot.mouseMove(heavyLoc.x + 20, heavyLoc.y + 20);
|
||||||
|
|
||||||
|
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||||
|
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||||
|
Util.waitForIdle(robot);
|
||||||
|
|
||||||
|
if (clickPassed) {
|
||||||
|
pass();
|
||||||
|
} else {
|
||||||
|
fail("The button cannot be clicked.");
|
||||||
|
}
|
||||||
|
}//End init()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************
|
||||||
|
* Standard Test Machinery Section
|
||||||
|
* DO NOT modify anything in this section -- it's a
|
||||||
|
* standard chunk of code which has all of the
|
||||||
|
* synchronisation necessary for the test harness.
|
||||||
|
* By keeping it the same in all tests, it is easier
|
||||||
|
* to read and understand someone else's test, as
|
||||||
|
* well as insuring that all tests behave correctly
|
||||||
|
* with the test harness.
|
||||||
|
* There is a section following this for test-
|
||||||
|
* classes
|
||||||
|
******************************************************/
|
||||||
|
private static boolean theTestPassed = false;
|
||||||
|
private static boolean testGeneratedInterrupt = false;
|
||||||
|
private static String failureMessage = "";
|
||||||
|
|
||||||
|
private static Thread mainThread = null;
|
||||||
|
|
||||||
|
private static int sleepTime = 300000;
|
||||||
|
|
||||||
|
// Not sure about what happens if multiple of this test are
|
||||||
|
// instantiated in the same VM. Being static (and using
|
||||||
|
// static vars), it aint gonna work. Not worrying about
|
||||||
|
// it for now.
|
||||||
|
public static void main( String args[] ) throws InterruptedException
|
||||||
|
{
|
||||||
|
mainThread = Thread.currentThread();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
catch( TestPassedException e )
|
||||||
|
{
|
||||||
|
//The test passed, so just return from main and harness will
|
||||||
|
// interepret this return as a pass
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//At this point, neither test pass nor test fail has been
|
||||||
|
// called -- either would have thrown an exception and ended the
|
||||||
|
// test, so we know we have multiple threads.
|
||||||
|
|
||||||
|
//Test involves other threads, so sleep and wait for them to
|
||||||
|
// called pass() or fail()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep( sleepTime );
|
||||||
|
//Timed out, so fail the test
|
||||||
|
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
//The test harness may have interrupted the test. If so, rethrow the exception
|
||||||
|
// so that the harness gets it and deals with it.
|
||||||
|
if( ! testGeneratedInterrupt ) throw e;
|
||||||
|
|
||||||
|
//reset flag in case hit this code more than once for some reason (just safety)
|
||||||
|
testGeneratedInterrupt = false;
|
||||||
|
|
||||||
|
if ( theTestPassed == false )
|
||||||
|
{
|
||||||
|
throw new RuntimeException( failureMessage );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}//main
|
||||||
|
|
||||||
|
public static synchronized void setTimeoutTo( int seconds )
|
||||||
|
{
|
||||||
|
sleepTime = seconds * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void pass()
|
||||||
|
{
|
||||||
|
Sysout.println( "The test passed." );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//first check if this is executing in main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//Still in the main thread, so set the flag just for kicks,
|
||||||
|
// and throw a test passed exception which will be caught
|
||||||
|
// and end the test.
|
||||||
|
theTestPassed = true;
|
||||||
|
throw new TestPassedException();
|
||||||
|
}
|
||||||
|
theTestPassed = true;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//pass()
|
||||||
|
|
||||||
|
public static synchronized void fail()
|
||||||
|
{
|
||||||
|
//test writer didn't specify why test failed, so give generic
|
||||||
|
fail( "it just plain failed! :-)" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void fail( String whyFailed )
|
||||||
|
{
|
||||||
|
Sysout.println( "The test failed: " + whyFailed );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//check if this called from main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//If main thread, fail now 'cause not sleeping
|
||||||
|
throw new RuntimeException( whyFailed );
|
||||||
|
}
|
||||||
|
theTestPassed = false;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
failureMessage = whyFailed;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//fail()
|
||||||
|
|
||||||
|
}// class ValidBounds
|
||||||
|
|
||||||
|
//This exception is used to exit from any level of call nesting
|
||||||
|
// when it's determined that the test has passed, and immediately
|
||||||
|
// end the test.
|
||||||
|
class TestPassedException extends RuntimeException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*********** End Standard Test Machinery Section **********
|
||||||
|
|
||||||
|
|
||||||
|
//************ Begin classes defined for the test ****************
|
||||||
|
|
||||||
|
// if want to make listeners, here is the recommended place for them, then instantiate
|
||||||
|
// them in init()
|
||||||
|
|
||||||
|
/* Example of a class which may be written as part of a test
|
||||||
|
class NewClass implements anInterface
|
||||||
|
{
|
||||||
|
static int newVar = 0;
|
||||||
|
|
||||||
|
public void eventDispatched(AWTEvent e)
|
||||||
|
{
|
||||||
|
//Counting events to see if we get enough
|
||||||
|
eventCount++;
|
||||||
|
|
||||||
|
if( eventCount == 20 )
|
||||||
|
{
|
||||||
|
//got enough events, so pass
|
||||||
|
|
||||||
|
ValidBounds.pass();
|
||||||
|
}
|
||||||
|
else if( tries == 20 )
|
||||||
|
{
|
||||||
|
//tried too many times without getting enough events so fail
|
||||||
|
|
||||||
|
ValidBounds.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}// eventDispatched()
|
||||||
|
|
||||||
|
}// NewClass class
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//************** End classes defined for the test *******************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************
|
||||||
|
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 );
|
||||||
|
System.out.println(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 );
|
||||||
|
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,466 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@test %I% %E%
|
||||||
|
@bug 4080029
|
||||||
|
@summary Modal Dialog block input to all frame windows not just its parent.
|
||||||
|
@author dmitry.cherepanov: area=awt.modal
|
||||||
|
@run main/manual CloseBlocker
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ManualMainTest.java
|
||||||
|
*
|
||||||
|
* summary: The test opens and closes blocker dialog, the test verifies
|
||||||
|
* that active window is correct when the dialog is closed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
|
||||||
|
public class CloseBlocker
|
||||||
|
{
|
||||||
|
|
||||||
|
private static void init()
|
||||||
|
{
|
||||||
|
//*** Create instructions for the user here ***
|
||||||
|
|
||||||
|
String[] instructions =
|
||||||
|
{
|
||||||
|
" the test will be run 6 times, to start next test just close all ",
|
||||||
|
" windows of previous; the instructions are the same for all tests: ",
|
||||||
|
" 1) there are two frames (one the frames has 'show modal' button), ",
|
||||||
|
" 2) press the button to show a dialog, ",
|
||||||
|
" 3) close the dialog (an alternative scenario - activate another",
|
||||||
|
" native window before closing the dialog), ",
|
||||||
|
" 4) the frame with button should become next active window, ",
|
||||||
|
" if it's true, then the test passed, otherwise, it failed. ",
|
||||||
|
" Press 'pass' button only after all of the 6 tests are completed, ",
|
||||||
|
" the number of the currently executed test is displayed on the ",
|
||||||
|
" output window. "
|
||||||
|
};
|
||||||
|
Sysout.createDialog( );
|
||||||
|
Sysout.printInstructions( instructions );
|
||||||
|
|
||||||
|
test(true, true, false);
|
||||||
|
test(true, true, true);
|
||||||
|
test(false, true, false); // 3rd parameter has no affect for ownerless
|
||||||
|
|
||||||
|
test(true, false, false);
|
||||||
|
test(true, false, true);
|
||||||
|
test(false, false, false); // 3rd parameter has no affect for ownerless
|
||||||
|
|
||||||
|
}//End init()
|
||||||
|
|
||||||
|
private static final Object obj = new Object();
|
||||||
|
private static int counter = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ownerless parameter indicates whether the blocker dialog
|
||||||
|
* has owner. The usual parameter indicates whether the blocker
|
||||||
|
* dialog is a Java dialog (non-native dialog like file dialog).
|
||||||
|
*/
|
||||||
|
private static void test(final boolean ownerless, final boolean usual, final boolean initiallyOwnerIsActive) {
|
||||||
|
|
||||||
|
Sysout.print(" * test #" + (++counter) + " is running ... ");
|
||||||
|
|
||||||
|
final Frame active = new Frame();
|
||||||
|
final Frame nonactive = new Frame();
|
||||||
|
Button button = new Button("show modal");
|
||||||
|
button.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent ae) {
|
||||||
|
Dialog dialog = null;
|
||||||
|
Frame parent = ownerless ? null : (initiallyOwnerIsActive? active : nonactive);
|
||||||
|
if (usual) {
|
||||||
|
dialog = new Dialog(parent, "Sample", true);
|
||||||
|
} else {
|
||||||
|
dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
|
||||||
|
}
|
||||||
|
dialog.addWindowListener(new WindowAdapter(){
|
||||||
|
public void windowClosing(WindowEvent e){
|
||||||
|
e.getWindow().dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.setBounds(200, 200, 200, 200);
|
||||||
|
dialog.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
active.add(button);
|
||||||
|
active.setBounds(200, 400, 200, 200);
|
||||||
|
WindowAdapter adapter = new WindowAdapter(){
|
||||||
|
public void windowClosing(WindowEvent e){
|
||||||
|
active.dispose();
|
||||||
|
nonactive.dispose();
|
||||||
|
synchronized(obj) {
|
||||||
|
obj.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
active.addWindowListener(adapter);
|
||||||
|
active.setVisible(true);
|
||||||
|
|
||||||
|
nonactive.setBounds(400, 400, 200, 200);
|
||||||
|
nonactive.addWindowListener(adapter);
|
||||||
|
nonactive.setVisible(true);
|
||||||
|
|
||||||
|
synchronized(obj) {
|
||||||
|
try{
|
||||||
|
obj.wait();
|
||||||
|
} catch(Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sysout.println(" completed. ");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************
|
||||||
|
* Standard Test Machinery Section
|
||||||
|
* DO NOT modify anything in this section -- it's a
|
||||||
|
* standard chunk of code which has all of the
|
||||||
|
* synchronisation necessary for the test harness.
|
||||||
|
* By keeping it the same in all tests, it is easier
|
||||||
|
* to read and understand someone else's test, as
|
||||||
|
* well as insuring that all tests behave correctly
|
||||||
|
* with the test harness.
|
||||||
|
* There is a section following this for test-defined
|
||||||
|
* classes
|
||||||
|
******************************************************/
|
||||||
|
private static boolean theTestPassed = false;
|
||||||
|
private static boolean testGeneratedInterrupt = false;
|
||||||
|
private static String failureMessage = "";
|
||||||
|
|
||||||
|
private static Thread mainThread = null;
|
||||||
|
|
||||||
|
private static int sleepTime = 300000;
|
||||||
|
|
||||||
|
public static void main( String args[] ) throws InterruptedException
|
||||||
|
{
|
||||||
|
mainThread = Thread.currentThread();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
catch( TestPassedException e )
|
||||||
|
{
|
||||||
|
//The test passed, so just return from main and harness will
|
||||||
|
// interepret this return as a pass
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//At this point, neither test passed nor test failed has been
|
||||||
|
// called -- either would have thrown an exception and ended the
|
||||||
|
// test, so we know we have multiple threads.
|
||||||
|
|
||||||
|
//Test involves other threads, so sleep and wait for them to
|
||||||
|
// called pass() or fail()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep( sleepTime );
|
||||||
|
//Timed out, so fail the test
|
||||||
|
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
if( ! testGeneratedInterrupt ) throw e;
|
||||||
|
|
||||||
|
//reset flag in case hit this code more than once for some reason (just safety)
|
||||||
|
testGeneratedInterrupt = false;
|
||||||
|
if ( theTestPassed == false )
|
||||||
|
{
|
||||||
|
throw new RuntimeException( failureMessage );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}//main
|
||||||
|
|
||||||
|
public static synchronized void setTimeoutTo( int seconds )
|
||||||
|
{
|
||||||
|
sleepTime = seconds * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void pass()
|
||||||
|
{
|
||||||
|
Sysout.println( "The test passed." );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//first check if this is executing in main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//Still in the main thread, so set the flag just for kicks,
|
||||||
|
// and throw a test passed exception which will be caught
|
||||||
|
// and end the test.
|
||||||
|
theTestPassed = true;
|
||||||
|
throw new TestPassedException();
|
||||||
|
}
|
||||||
|
//pass was called from a different thread, so set the flag and interrupt
|
||||||
|
// the main thead.
|
||||||
|
theTestPassed = true;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//pass()
|
||||||
|
|
||||||
|
public static synchronized void fail()
|
||||||
|
{
|
||||||
|
//test writer didn't specify why test failed, so give generic
|
||||||
|
fail( "it just plain failed! :-)" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void fail( String whyFailed )
|
||||||
|
{
|
||||||
|
Sysout.println( "The test failed: " + whyFailed );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//check if this called from main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//If main thread, fail now 'cause not sleeping
|
||||||
|
throw new RuntimeException( whyFailed );
|
||||||
|
}
|
||||||
|
theTestPassed = false;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
failureMessage = whyFailed;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//fail()
|
||||||
|
|
||||||
|
}// class ManualMainTest
|
||||||
|
|
||||||
|
//This exception is used to exit from any level of call nesting
|
||||||
|
// when it's determined that the test has passed, and immediately
|
||||||
|
// end the test.
|
||||||
|
class TestPassedException extends RuntimeException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*********** End Standard Test Machinery Section **********
|
||||||
|
|
||||||
|
|
||||||
|
//************ Begin classes defined for the test ****************
|
||||||
|
|
||||||
|
// make listeners in a class defined here, and instantiate them in init()
|
||||||
|
|
||||||
|
/* Example of a class which may be written as part of a test
|
||||||
|
class NewClass implements anInterface
|
||||||
|
{
|
||||||
|
static int newVar = 0;
|
||||||
|
|
||||||
|
public void eventDispatched(AWTEvent e)
|
||||||
|
{
|
||||||
|
//Counting events to see if we get enough
|
||||||
|
eventCount++;
|
||||||
|
|
||||||
|
if( eventCount == 20 )
|
||||||
|
{
|
||||||
|
//got enough events, so pass
|
||||||
|
|
||||||
|
ManualMainTest.pass();
|
||||||
|
}
|
||||||
|
else if( tries == 20 )
|
||||||
|
{
|
||||||
|
//tried too many times without getting enough events so fail
|
||||||
|
|
||||||
|
ManualMainTest.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}// eventDispatched()
|
||||||
|
|
||||||
|
}// NewClass class
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//************** End classes defined for the test *******************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************
|
||||||
|
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, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void print( String messageIn )
|
||||||
|
{
|
||||||
|
dialog.displayMessage( messageIn, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
}// 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 implements ActionListener
|
||||||
|
{
|
||||||
|
|
||||||
|
TextArea instructionsText;
|
||||||
|
TextArea messageText;
|
||||||
|
int maxStringLength = 80;
|
||||||
|
Panel buttonP = new Panel();
|
||||||
|
Button passB = new Button( "pass" );
|
||||||
|
Button failB = new Button( "fail" );
|
||||||
|
|
||||||
|
//DO NOT call this directly, go through Sysout
|
||||||
|
public TestDialog( Frame frame, String name )
|
||||||
|
{
|
||||||
|
super( frame, name );
|
||||||
|
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||||
|
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||||
|
add( "North", instructionsText );
|
||||||
|
|
||||||
|
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||||
|
add("Center", messageText);
|
||||||
|
|
||||||
|
passB = new Button( "pass" );
|
||||||
|
passB.setActionCommand( "pass" );
|
||||||
|
passB.addActionListener( this );
|
||||||
|
buttonP.add( "East", passB );
|
||||||
|
|
||||||
|
failB = new Button( "fail" );
|
||||||
|
failB.setActionCommand( "fail" );
|
||||||
|
failB.addActionListener( this );
|
||||||
|
buttonP.add( "West", failB );
|
||||||
|
|
||||||
|
add( "South", buttonP );
|
||||||
|
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, boolean nextLine )
|
||||||
|
{
|
||||||
|
messageText.append( messageIn + (nextLine? "\n" : "") );
|
||||||
|
System.out.println(messageIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//catch presses of the passed and failed buttons.
|
||||||
|
//simply call the standard pass() or fail() static methods of
|
||||||
|
//ManualMainTest
|
||||||
|
public void actionPerformed( ActionEvent e )
|
||||||
|
{
|
||||||
|
if( e.getActionCommand() == "pass" )
|
||||||
|
{
|
||||||
|
CloseBlocker.pass();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CloseBlocker.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}// TestDialog class
|
@ -0,0 +1,456 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@test %I% %E%
|
||||||
|
@bug 4080029
|
||||||
|
@summary Modal Dialog block input to all frame windows not just its parent.
|
||||||
|
@author dmitry.cherepanov: area=awt.modal
|
||||||
|
@run main/manual OverBlocker
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OverBlocker.java
|
||||||
|
*
|
||||||
|
* summary: The test verifies that if user tries to activate the blocked dialog
|
||||||
|
* then the blocker dialog appears over the other windows
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
|
||||||
|
public class OverBlocker
|
||||||
|
{
|
||||||
|
|
||||||
|
private static void init()
|
||||||
|
{
|
||||||
|
//*** Create instructions for the user here ***
|
||||||
|
|
||||||
|
String[] instructions =
|
||||||
|
{
|
||||||
|
" the test will be run 4 times, to start next test just close all ",
|
||||||
|
" windows of previous; the instructions are the same for all tests: ",
|
||||||
|
" 1) there is a frame with 'show modal' button, ",
|
||||||
|
" 2) press the button to show a dialog, ",
|
||||||
|
" 3) activate any non-Java application, move the app over the dialog, ",
|
||||||
|
" 4) click on the frame by mouse, ",
|
||||||
|
" 5) make sure that the dialog comes up from the application and ",
|
||||||
|
" now the dialog overlaps the app as well as the frame, ",
|
||||||
|
" if it's true, then the test passed, otherwise, it failed. ",
|
||||||
|
" Press 'pass' button only after all of the 4 tests are completed, ",
|
||||||
|
" the number of the currently executed test is displayed on the ",
|
||||||
|
" output window. "
|
||||||
|
};
|
||||||
|
Sysout.createDialog( );
|
||||||
|
Sysout.printInstructions( instructions );
|
||||||
|
|
||||||
|
test(false, true);
|
||||||
|
test(true, true);
|
||||||
|
test(true, false);
|
||||||
|
test(false, false);
|
||||||
|
|
||||||
|
}//End init()
|
||||||
|
|
||||||
|
private static final Object obj = new Object();
|
||||||
|
private static int counter = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ownerless parameter indicates whether the blocker dialog
|
||||||
|
* has owner. The usual parameter indicates whether the blocker
|
||||||
|
* dialog is a Java dialog (non-native dialog like file dialog).
|
||||||
|
*/
|
||||||
|
private static void test(final boolean ownerless, final boolean usual) {
|
||||||
|
|
||||||
|
Sysout.print(" * test #" + (++counter) + " is running ... ");
|
||||||
|
|
||||||
|
final Frame frame = new Frame();
|
||||||
|
Button button = new Button("show modal");
|
||||||
|
button.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent ae) {
|
||||||
|
Dialog dialog = null;
|
||||||
|
Frame parent = ownerless ? null : frame;
|
||||||
|
if (usual) {
|
||||||
|
dialog = new Dialog(parent, "Sample", true);
|
||||||
|
} else {
|
||||||
|
dialog = new FileDialog(parent, "Sample", FileDialog.LOAD);
|
||||||
|
}
|
||||||
|
dialog.addWindowListener(new WindowAdapter(){
|
||||||
|
public void windowClosing(WindowEvent e){
|
||||||
|
e.getWindow().dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.setBounds(200, 200, 200, 200);
|
||||||
|
dialog.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
frame.add(button);
|
||||||
|
frame.setBounds(400, 400, 200, 200);
|
||||||
|
frame.addWindowListener(new WindowAdapter(){
|
||||||
|
public void windowClosing(WindowEvent e){
|
||||||
|
e.getWindow().dispose();
|
||||||
|
synchronized(obj) {
|
||||||
|
obj.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
synchronized(obj) {
|
||||||
|
try{
|
||||||
|
obj.wait();
|
||||||
|
} catch(Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sysout.println(" completed. ");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************
|
||||||
|
* Standard Test Machinery Section
|
||||||
|
* DO NOT modify anything in this section -- it's a
|
||||||
|
* standard chunk of code which has all of the
|
||||||
|
* synchronisation necessary for the test harness.
|
||||||
|
* By keeping it the same in all tests, it is easier
|
||||||
|
* to read and understand someone else's test, as
|
||||||
|
* well as insuring that all tests behave correctly
|
||||||
|
* with the test harness.
|
||||||
|
* There is a section following this for test-defined
|
||||||
|
* classes
|
||||||
|
******************************************************/
|
||||||
|
private static boolean theTestPassed = false;
|
||||||
|
private static boolean testGeneratedInterrupt = false;
|
||||||
|
private static String failureMessage = "";
|
||||||
|
|
||||||
|
private static Thread mainThread = null;
|
||||||
|
|
||||||
|
private static int sleepTime = 300000;
|
||||||
|
|
||||||
|
public static void main( String args[] ) throws InterruptedException
|
||||||
|
{
|
||||||
|
mainThread = Thread.currentThread();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
catch( TestPassedException e )
|
||||||
|
{
|
||||||
|
//The test passed, so just return from main and harness will
|
||||||
|
// interepret this return as a pass
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//At this point, neither test passed nor test failed has been
|
||||||
|
// called -- either would have thrown an exception and ended the
|
||||||
|
// test, so we know we have multiple threads.
|
||||||
|
|
||||||
|
//Test involves other threads, so sleep and wait for them to
|
||||||
|
// called pass() or fail()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep( sleepTime );
|
||||||
|
//Timed out, so fail the test
|
||||||
|
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
if( ! testGeneratedInterrupt ) throw e;
|
||||||
|
|
||||||
|
//reset flag in case hit this code more than once for some reason (just safety)
|
||||||
|
testGeneratedInterrupt = false;
|
||||||
|
if ( theTestPassed == false )
|
||||||
|
{
|
||||||
|
throw new RuntimeException( failureMessage );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}//main
|
||||||
|
|
||||||
|
public static synchronized void setTimeoutTo( int seconds )
|
||||||
|
{
|
||||||
|
sleepTime = seconds * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void pass()
|
||||||
|
{
|
||||||
|
Sysout.println( "The test passed." );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//first check if this is executing in main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//Still in the main thread, so set the flag just for kicks,
|
||||||
|
// and throw a test passed exception which will be caught
|
||||||
|
// and end the test.
|
||||||
|
theTestPassed = true;
|
||||||
|
throw new TestPassedException();
|
||||||
|
}
|
||||||
|
//pass was called from a different thread, so set the flag and interrupt
|
||||||
|
// the main thead.
|
||||||
|
theTestPassed = true;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//pass()
|
||||||
|
|
||||||
|
public static synchronized void fail()
|
||||||
|
{
|
||||||
|
//test writer didn't specify why test failed, so give generic
|
||||||
|
fail( "it just plain failed! :-)" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void fail( String whyFailed )
|
||||||
|
{
|
||||||
|
Sysout.println( "The test failed: " + whyFailed );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//check if this called from main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//If main thread, fail now 'cause not sleeping
|
||||||
|
throw new RuntimeException( whyFailed );
|
||||||
|
}
|
||||||
|
theTestPassed = false;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
failureMessage = whyFailed;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//fail()
|
||||||
|
|
||||||
|
}// class ManualMainTest
|
||||||
|
|
||||||
|
//This exception is used to exit from any level of call nesting
|
||||||
|
// when it's determined that the test has passed, and immediately
|
||||||
|
// end the test.
|
||||||
|
class TestPassedException extends RuntimeException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*********** End Standard Test Machinery Section **********
|
||||||
|
|
||||||
|
|
||||||
|
//************ Begin classes defined for the test ****************
|
||||||
|
|
||||||
|
// make listeners in a class defined here, and instantiate them in init()
|
||||||
|
|
||||||
|
/* Example of a class which may be written as part of a test
|
||||||
|
class NewClass implements anInterface
|
||||||
|
{
|
||||||
|
static int newVar = 0;
|
||||||
|
|
||||||
|
public void eventDispatched(AWTEvent e)
|
||||||
|
{
|
||||||
|
//Counting events to see if we get enough
|
||||||
|
eventCount++;
|
||||||
|
|
||||||
|
if( eventCount == 20 )
|
||||||
|
{
|
||||||
|
//got enough events, so pass
|
||||||
|
|
||||||
|
ManualMainTest.pass();
|
||||||
|
}
|
||||||
|
else if( tries == 20 )
|
||||||
|
{
|
||||||
|
//tried too many times without getting enough events so fail
|
||||||
|
|
||||||
|
ManualMainTest.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}// eventDispatched()
|
||||||
|
|
||||||
|
}// NewClass class
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//************** End classes defined for the test *******************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************
|
||||||
|
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, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void print( String messageIn )
|
||||||
|
{
|
||||||
|
dialog.displayMessage( messageIn, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
}// 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 implements ActionListener
|
||||||
|
{
|
||||||
|
|
||||||
|
TextArea instructionsText;
|
||||||
|
TextArea messageText;
|
||||||
|
int maxStringLength = 80;
|
||||||
|
Panel buttonP = new Panel();
|
||||||
|
Button passB = new Button( "pass" );
|
||||||
|
Button failB = new Button( "fail" );
|
||||||
|
|
||||||
|
//DO NOT call this directly, go through Sysout
|
||||||
|
public TestDialog( Frame frame, String name )
|
||||||
|
{
|
||||||
|
super( frame, name );
|
||||||
|
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||||
|
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||||
|
add( "North", instructionsText );
|
||||||
|
|
||||||
|
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||||
|
add("Center", messageText);
|
||||||
|
|
||||||
|
passB = new Button( "pass" );
|
||||||
|
passB.setActionCommand( "pass" );
|
||||||
|
passB.addActionListener( this );
|
||||||
|
buttonP.add( "East", passB );
|
||||||
|
|
||||||
|
failB = new Button( "fail" );
|
||||||
|
failB.setActionCommand( "fail" );
|
||||||
|
failB.addActionListener( this );
|
||||||
|
buttonP.add( "West", failB );
|
||||||
|
|
||||||
|
add( "South", buttonP );
|
||||||
|
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, boolean nextLine )
|
||||||
|
{
|
||||||
|
messageText.append( messageIn + (nextLine? "\n" : "") );
|
||||||
|
System.out.println(messageIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//catch presses of the passed and failed buttons.
|
||||||
|
//simply call the standard pass() or fail() static methods of
|
||||||
|
//ManualMainTest
|
||||||
|
public void actionPerformed( ActionEvent e )
|
||||||
|
{
|
||||||
|
if( e.getActionCommand() == "pass" )
|
||||||
|
{
|
||||||
|
OverBlocker.pass();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OverBlocker.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}// TestDialog class
|
403
jdk/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java
Normal file
403
jdk/test/java/awt/Modal/WsDisabledStyle/Winkey/Winkey.java
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@test %I% %E%
|
||||||
|
@bug 6572263 6571808
|
||||||
|
@summary PIT:FileDialog minimized to taskbar(through 'Show Desktop')selecting the fileDialog using windowList
|
||||||
|
@author dmitry.cherepanov: area=awt.modal
|
||||||
|
@run main/manual Winkey
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Winkey.java
|
||||||
|
*
|
||||||
|
* summary: the test verifies that pressing combination of Windows key
|
||||||
|
* and M key to minimize all windows doesn't break AWT modality
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
|
||||||
|
public class Winkey
|
||||||
|
{
|
||||||
|
|
||||||
|
private static void init()
|
||||||
|
{
|
||||||
|
//*** Create instructions for the user here ***
|
||||||
|
|
||||||
|
String[] instructions =
|
||||||
|
{
|
||||||
|
" 1. there is a frame with a 'show modal' button, ",
|
||||||
|
" 2. press the button to show a modal dialog, ",
|
||||||
|
" 3. the modal dialog will be shown over the frame, ",
|
||||||
|
" 4. please verify that all (5.1, 5.2.1, 5.2.2) the following tests pass: ",
|
||||||
|
" ",
|
||||||
|
" 5.1. press combination Windows Key and M key to minimize all windows, ",
|
||||||
|
" 5.2. press combination Windows Key and D key to show desktop, ",
|
||||||
|
" 5.2.1. restore the dialog by choosing this one in the ALT-TAB list, ",
|
||||||
|
" 5.2.2. restore the dialog by mouse click on taskbar (on java or any other item)",
|
||||||
|
" ",
|
||||||
|
" 6. make sure that the dialog and the frame are visible, ",
|
||||||
|
" the bounds of the windows should be the same as before, ",
|
||||||
|
" if it's true, then the test passed; otherwise, it failed. "
|
||||||
|
};
|
||||||
|
Sysout.createDialog( );
|
||||||
|
Sysout.printInstructions( instructions );
|
||||||
|
|
||||||
|
final Frame frame = new Frame();
|
||||||
|
Button button = new Button("show modal");
|
||||||
|
button.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent ae) {
|
||||||
|
FileDialog dialog = new FileDialog((Frame)null, "Sample", FileDialog.LOAD);
|
||||||
|
dialog.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
frame.add(button);
|
||||||
|
frame.setBounds(400, 400, 200, 200);
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
}//End init()
|
||||||
|
|
||||||
|
/*****************************************************
|
||||||
|
* Standard Test Machinery Section
|
||||||
|
* DO NOT modify anything in this section -- it's a
|
||||||
|
* standard chunk of code which has all of the
|
||||||
|
* synchronisation necessary for the test harness.
|
||||||
|
* By keeping it the same in all tests, it is easier
|
||||||
|
* to read and understand someone else's test, as
|
||||||
|
* well as insuring that all tests behave correctly
|
||||||
|
* with the test harness.
|
||||||
|
* There is a section following this for test-defined
|
||||||
|
* classes
|
||||||
|
******************************************************/
|
||||||
|
private static boolean theTestPassed = false;
|
||||||
|
private static boolean testGeneratedInterrupt = false;
|
||||||
|
private static String failureMessage = "";
|
||||||
|
|
||||||
|
private static Thread mainThread = null;
|
||||||
|
|
||||||
|
private static int sleepTime = 300000;
|
||||||
|
|
||||||
|
public static void main( String args[] ) throws InterruptedException
|
||||||
|
{
|
||||||
|
mainThread = Thread.currentThread();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
catch( TestPassedException e )
|
||||||
|
{
|
||||||
|
//The test passed, so just return from main and harness will
|
||||||
|
// interepret this return as a pass
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//At this point, neither test passed nor test failed has been
|
||||||
|
// called -- either would have thrown an exception and ended the
|
||||||
|
// test, so we know we have multiple threads.
|
||||||
|
|
||||||
|
//Test involves other threads, so sleep and wait for them to
|
||||||
|
// called pass() or fail()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep( sleepTime );
|
||||||
|
//Timed out, so fail the test
|
||||||
|
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
if( ! testGeneratedInterrupt ) throw e;
|
||||||
|
|
||||||
|
//reset flag in case hit this code more than once for some reason (just safety)
|
||||||
|
testGeneratedInterrupt = false;
|
||||||
|
if ( theTestPassed == false )
|
||||||
|
{
|
||||||
|
throw new RuntimeException( failureMessage );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}//main
|
||||||
|
|
||||||
|
public static synchronized void setTimeoutTo( int seconds )
|
||||||
|
{
|
||||||
|
sleepTime = seconds * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void pass()
|
||||||
|
{
|
||||||
|
Sysout.println( "The test passed." );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//first check if this is executing in main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//Still in the main thread, so set the flag just for kicks,
|
||||||
|
// and throw a test passed exception which will be caught
|
||||||
|
// and end the test.
|
||||||
|
theTestPassed = true;
|
||||||
|
throw new TestPassedException();
|
||||||
|
}
|
||||||
|
//pass was called from a different thread, so set the flag and interrupt
|
||||||
|
// the main thead.
|
||||||
|
theTestPassed = true;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//pass()
|
||||||
|
|
||||||
|
public static synchronized void fail()
|
||||||
|
{
|
||||||
|
//test writer didn't specify why test failed, so give generic
|
||||||
|
fail( "it just plain failed! :-)" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void fail( String whyFailed )
|
||||||
|
{
|
||||||
|
Sysout.println( "The test failed: " + whyFailed );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//check if this called from main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//If main thread, fail now 'cause not sleeping
|
||||||
|
throw new RuntimeException( whyFailed );
|
||||||
|
}
|
||||||
|
theTestPassed = false;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
failureMessage = whyFailed;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//fail()
|
||||||
|
|
||||||
|
}// class ManualMainTest
|
||||||
|
|
||||||
|
//This exception is used to exit from any level of call nesting
|
||||||
|
// when it's determined that the test has passed, and immediately
|
||||||
|
// end the test.
|
||||||
|
class TestPassedException extends RuntimeException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*********** End Standard Test Machinery Section **********
|
||||||
|
|
||||||
|
|
||||||
|
//************ Begin classes defined for the test ****************
|
||||||
|
|
||||||
|
// make listeners in a class defined here, and instantiate them in init()
|
||||||
|
|
||||||
|
/* Example of a class which may be written as part of a test
|
||||||
|
class NewClass implements anInterface
|
||||||
|
{
|
||||||
|
static int newVar = 0;
|
||||||
|
|
||||||
|
public void eventDispatched(AWTEvent e)
|
||||||
|
{
|
||||||
|
//Counting events to see if we get enough
|
||||||
|
eventCount++;
|
||||||
|
|
||||||
|
if( eventCount == 20 )
|
||||||
|
{
|
||||||
|
//got enough events, so pass
|
||||||
|
|
||||||
|
ManualMainTest.pass();
|
||||||
|
}
|
||||||
|
else if( tries == 20 )
|
||||||
|
{
|
||||||
|
//tried too many times without getting enough events so fail
|
||||||
|
|
||||||
|
ManualMainTest.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}// eventDispatched()
|
||||||
|
|
||||||
|
}// NewClass class
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//************** End classes defined for the test *******************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************
|
||||||
|
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 implements ActionListener
|
||||||
|
{
|
||||||
|
|
||||||
|
TextArea instructionsText;
|
||||||
|
TextArea messageText;
|
||||||
|
int maxStringLength = 80;
|
||||||
|
Panel buttonP = new Panel();
|
||||||
|
Button passB = new Button( "pass" );
|
||||||
|
Button failB = new Button( "fail" );
|
||||||
|
|
||||||
|
//DO NOT call this directly, go through Sysout
|
||||||
|
public TestDialog( Frame frame, String name )
|
||||||
|
{
|
||||||
|
super( frame, name );
|
||||||
|
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||||
|
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||||
|
add( "North", instructionsText );
|
||||||
|
|
||||||
|
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||||
|
add("Center", messageText);
|
||||||
|
|
||||||
|
passB = new Button( "pass" );
|
||||||
|
passB.setActionCommand( "pass" );
|
||||||
|
passB.addActionListener( this );
|
||||||
|
buttonP.add( "East", passB );
|
||||||
|
|
||||||
|
failB = new Button( "fail" );
|
||||||
|
failB.setActionCommand( "fail" );
|
||||||
|
failB.addActionListener( this );
|
||||||
|
buttonP.add( "West", failB );
|
||||||
|
|
||||||
|
add( "South", buttonP );
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//catch presses of the passed and failed buttons.
|
||||||
|
//simply call the standard pass() or fail() static methods of
|
||||||
|
//ManualMainTest
|
||||||
|
public void actionPerformed( ActionEvent e )
|
||||||
|
{
|
||||||
|
if( e.getActionCommand() == "pass" )
|
||||||
|
{
|
||||||
|
Winkey.pass();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Winkey.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}// TestDialog class
|
432
jdk/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java
Normal file
432
jdk/test/java/awt/event/MouseEvent/SmoothWheel/SmoothWheel.java
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
@test %W% %E% %I%, %G%
|
||||||
|
@bug 6524352
|
||||||
|
@summary support for high-resolution mouse wheel
|
||||||
|
@author dmitry cherepanov: area=awt.event
|
||||||
|
@run main/manual SmoothWheel
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SmoothWheel.java
|
||||||
|
*
|
||||||
|
* summary:
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
|
||||||
|
public class SmoothWheel
|
||||||
|
{
|
||||||
|
|
||||||
|
//*** test-writer defined static variables go here ***
|
||||||
|
|
||||||
|
|
||||||
|
private static void init()
|
||||||
|
{
|
||||||
|
String[] instructions =
|
||||||
|
{
|
||||||
|
"1. the test is for high-resolution mouse wheel only, ",
|
||||||
|
" refer to the cr# 6524352 for more info about such devices, ",
|
||||||
|
"2. you'll see a frame, the frame contains a checkbox, ",
|
||||||
|
"3. initially, the state of the checkbox is off, ",
|
||||||
|
" use mouse wheel over the frame, ",
|
||||||
|
" and the frame will change its size gradually, ",
|
||||||
|
"4. turn on the checkbox, ",
|
||||||
|
" use mouse wheel again over the frame, ",
|
||||||
|
" now the frame will change its size smoothly, ",
|
||||||
|
"5. if the frame has always the same size or",
|
||||||
|
" if the frame changes its size equally in 3,4 cases, ",
|
||||||
|
" then the test failed. Otherwise, it passed."
|
||||||
|
};
|
||||||
|
|
||||||
|
Sysout.createDialog( );
|
||||||
|
Sysout.printInstructions( instructions );
|
||||||
|
|
||||||
|
final Frame frame = new Frame();
|
||||||
|
final Checkbox checkbox = new Checkbox("smooth wheel?");
|
||||||
|
checkbox.setState(false);
|
||||||
|
|
||||||
|
frame.setLayout (new FlowLayout());
|
||||||
|
frame.add(checkbox);
|
||||||
|
|
||||||
|
frame.addMouseWheelListener(new MouseWheelListener() {
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
|
Sysout.println(e.toString());
|
||||||
|
double wheelRotation = 0;
|
||||||
|
if (checkbox.getState()) {
|
||||||
|
wheelRotation = e.getPreciseWheelRotation();
|
||||||
|
} else {
|
||||||
|
wheelRotation = e.getWheelRotation();
|
||||||
|
}
|
||||||
|
Dimension size = frame.getSize();
|
||||||
|
size.width += 10 * wheelRotation;
|
||||||
|
size.height += 10 * wheelRotation;
|
||||||
|
frame.setSize(size);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frame.setBounds(200, 200, 200, 200);
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
}//End init()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************
|
||||||
|
* Standard Test Machinery Section
|
||||||
|
* DO NOT modify anything in this section -- it's a
|
||||||
|
* standard chunk of code which has all of the
|
||||||
|
* synchronisation necessary for the test harness.
|
||||||
|
* By keeping it the same in all tests, it is easier
|
||||||
|
* to read and understand someone else's test, as
|
||||||
|
* well as insuring that all tests behave correctly
|
||||||
|
* with the test harness.
|
||||||
|
* There is a section following this for test-defined
|
||||||
|
* classes
|
||||||
|
******************************************************/
|
||||||
|
private static boolean theTestPassed = false;
|
||||||
|
private static boolean testGeneratedInterrupt = false;
|
||||||
|
private static String failureMessage = "";
|
||||||
|
|
||||||
|
private static Thread mainThread = null;
|
||||||
|
|
||||||
|
private static int sleepTime = 300000;
|
||||||
|
|
||||||
|
public static void main( String args[] ) throws InterruptedException
|
||||||
|
{
|
||||||
|
mainThread = Thread.currentThread();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
catch( TestPassedException e )
|
||||||
|
{
|
||||||
|
//The test passed, so just return from main and harness will
|
||||||
|
// interepret this return as a pass
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//At this point, neither test passed nor test failed has been
|
||||||
|
// called -- either would have thrown an exception and ended the
|
||||||
|
// test, so we know we have multiple threads.
|
||||||
|
|
||||||
|
//Test involves other threads, so sleep and wait for them to
|
||||||
|
// called pass() or fail()
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep( sleepTime );
|
||||||
|
//Timed out, so fail the test
|
||||||
|
throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
if( ! testGeneratedInterrupt ) throw e;
|
||||||
|
|
||||||
|
//reset flag in case hit this code more than once for some reason (just safety)
|
||||||
|
testGeneratedInterrupt = false;
|
||||||
|
if ( theTestPassed == false )
|
||||||
|
{
|
||||||
|
throw new RuntimeException( failureMessage );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}//main
|
||||||
|
|
||||||
|
public static synchronized void setTimeoutTo( int seconds )
|
||||||
|
{
|
||||||
|
sleepTime = seconds * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void pass()
|
||||||
|
{
|
||||||
|
Sysout.println( "The test passed." );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//first check if this is executing in main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//Still in the main thread, so set the flag just for kicks,
|
||||||
|
// and throw a test passed exception which will be caught
|
||||||
|
// and end the test.
|
||||||
|
theTestPassed = true;
|
||||||
|
throw new TestPassedException();
|
||||||
|
}
|
||||||
|
//pass was called from a different thread, so set the flag and interrupt
|
||||||
|
// the main thead.
|
||||||
|
theTestPassed = true;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
if (mainThread != null){
|
||||||
|
mainThread.interrupt();
|
||||||
|
}
|
||||||
|
}//pass()
|
||||||
|
|
||||||
|
public static synchronized void fail()
|
||||||
|
{
|
||||||
|
//test writer didn't specify why test failed, so give generic
|
||||||
|
fail( "it just plain failed! :-)" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void fail( String whyFailed )
|
||||||
|
{
|
||||||
|
Sysout.println( "The test failed: " + whyFailed );
|
||||||
|
Sysout.println( "The test is over, hit Ctl-C to stop Java VM" );
|
||||||
|
//check if this called from main thread
|
||||||
|
if ( mainThread == Thread.currentThread() )
|
||||||
|
{
|
||||||
|
//If main thread, fail now 'cause not sleeping
|
||||||
|
throw new RuntimeException( whyFailed );
|
||||||
|
}
|
||||||
|
theTestPassed = false;
|
||||||
|
testGeneratedInterrupt = true;
|
||||||
|
failureMessage = whyFailed;
|
||||||
|
mainThread.interrupt();
|
||||||
|
}//fail()
|
||||||
|
|
||||||
|
}// class ManualMainTest
|
||||||
|
|
||||||
|
//This exception is used to exit from any level of call nesting
|
||||||
|
// when it's determined that the test has passed, and immediately
|
||||||
|
// end the test.
|
||||||
|
class TestPassedException extends RuntimeException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//*********** End Standard Test Machinery Section **********
|
||||||
|
|
||||||
|
|
||||||
|
//************ Begin classes defined for the test ****************
|
||||||
|
|
||||||
|
// make listeners in a class defined here, and instantiate them in init()
|
||||||
|
|
||||||
|
/* Example of a class which may be written as part of a test
|
||||||
|
class NewClass implements anInterface
|
||||||
|
{
|
||||||
|
static int newVar = 0;
|
||||||
|
|
||||||
|
public void eventDispatched(AWTEvent e)
|
||||||
|
{
|
||||||
|
//Counting events to see if we get enough
|
||||||
|
eventCount++;
|
||||||
|
|
||||||
|
if( eventCount == 20 )
|
||||||
|
{
|
||||||
|
//got enough events, so pass
|
||||||
|
|
||||||
|
ManualMainTest.pass();
|
||||||
|
}
|
||||||
|
else if( tries == 20 )
|
||||||
|
{
|
||||||
|
//tried too many times without getting enough events so fail
|
||||||
|
|
||||||
|
ManualMainTest.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}// eventDispatched()
|
||||||
|
|
||||||
|
}// NewClass class
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//************** End classes defined for the test *******************
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************
|
||||||
|
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;
|
||||||
|
private static boolean numbering = false;
|
||||||
|
private static int messageNumber = 0;
|
||||||
|
|
||||||
|
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." );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Enables message counting for the tester. */
|
||||||
|
public static void enableNumbering(boolean enable){
|
||||||
|
numbering = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printInstructions( String[] instructions )
|
||||||
|
{
|
||||||
|
dialog.printInstructions( instructions );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void println( String messageIn )
|
||||||
|
{
|
||||||
|
if (numbering) {
|
||||||
|
messageIn = "" + messageNumber + " " + messageIn;
|
||||||
|
messageNumber++;
|
||||||
|
}
|
||||||
|
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 implements ActionListener
|
||||||
|
{
|
||||||
|
|
||||||
|
TextArea instructionsText;
|
||||||
|
TextArea messageText;
|
||||||
|
int maxStringLength = 80;
|
||||||
|
Panel buttonP = new Panel();
|
||||||
|
Button passB = new Button( "pass" );
|
||||||
|
Button failB = new Button( "fail" );
|
||||||
|
|
||||||
|
//DO NOT call this directly, go through Sysout
|
||||||
|
public TestDialog( Frame frame, String name )
|
||||||
|
{
|
||||||
|
super( frame, name );
|
||||||
|
int scrollBoth = TextArea.SCROLLBARS_BOTH;
|
||||||
|
instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
|
||||||
|
add( "North", instructionsText );
|
||||||
|
|
||||||
|
messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
|
||||||
|
add("Center", messageText);
|
||||||
|
|
||||||
|
passB = new Button( "pass" );
|
||||||
|
passB.setActionCommand( "pass" );
|
||||||
|
passB.addActionListener( this );
|
||||||
|
buttonP.add( "East", passB );
|
||||||
|
|
||||||
|
failB = new Button( "fail" );
|
||||||
|
failB.setActionCommand( "fail" );
|
||||||
|
failB.addActionListener( this );
|
||||||
|
buttonP.add( "West", failB );
|
||||||
|
|
||||||
|
add( "South", buttonP );
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//catch presses of the passed and failed buttons.
|
||||||
|
//simply call the standard pass() or fail() static methods of
|
||||||
|
//ManualMainTest
|
||||||
|
public void actionPerformed( ActionEvent e )
|
||||||
|
{
|
||||||
|
if( e.getActionCommand() == "pass" )
|
||||||
|
{
|
||||||
|
SmoothWheel.pass();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SmoothWheel.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}// TestDialog class
|
Loading…
Reference in New Issue
Block a user