提交 32069921 编写于 作者: L lana

Merge

......@@ -277,10 +277,8 @@ public class Dialog extends Window {
*/
String title;
private transient volatile boolean keepBlockingEDT = false;
private transient volatile boolean keepBlockingCT = false;
private transient ModalEventFilter modalFilter;
private transient volatile SecondaryLoop secondaryLoop;
/*
* Indicates that this dialog is being hidden. This flag is set to true at
......@@ -1005,12 +1003,6 @@ public class Dialog extends Window {
super.setVisible(b);
}
/**
* Stores the app context on which event dispatch thread the dialog
* is being shown. Initialized in show(), used in hideAndDisposeHandler()
*/
transient private AppContext showAppContext;
/**
* Makes the {@code Dialog} visible. If the dialog and/or its owner
* are not yet displayable, both are made displayable. The
......@@ -1037,39 +1029,18 @@ public class Dialog extends Window {
if (!isModal()) {
conditionalShow(null, null);
} else {
// Set this variable before calling conditionalShow(). That
// way, if the Dialog is hidden right after being shown, we
// won't mistakenly block this thread.
keepBlockingEDT = true;
keepBlockingCT = true;
// Store the app context on which this dialog is being shown.
// Event dispatch thread of this app context will be sleeping until
// we wake it by any event from hideAndDisposeHandler().
showAppContext = AppContext.getAppContext();
AppContext showAppContext = AppContext.getAppContext();
AtomicLong time = new AtomicLong();
Component predictedFocusOwner = null;
try {
predictedFocusOwner = getMostRecentFocusOwner();
if (conditionalShow(predictedFocusOwner, time)) {
// We have two mechanisms for blocking: 1. If we're on the
// EventDispatchThread, start a new event pump. 2. If we're
// on any other thread, call wait() on the treelock.
modalFilter = ModalEventFilter.createFilterForDialog(this);
final Runnable pumpEventsForFilter = new Runnable() {
public void run() {
EventDispatchThread dispatchThread =
(EventDispatchThread)Thread.currentThread();
dispatchThread.pumpEventsForFilter(new Conditional() {
public boolean evaluate() {
synchronized (getTreeLock()) {
return keepBlockingEDT && windowClosingException == null;
}
}
}, modalFilter);
Conditional cond = new Conditional() {
@Override
public boolean evaluate() {
return windowClosingException == null;
}
};
......@@ -1096,44 +1067,10 @@ public class Dialog extends Window {
modalityPushed();
try {
if (EventQueue.isDispatchThread()) {
/*
* dispose SequencedEvent we are dispatching on current
* AppContext, to prevent us from hang.
*
*/
// BugId 4531693 (son@sparc.spb.su)
SequencedEvent currentSequencedEvent = KeyboardFocusManager.
getCurrentKeyboardFocusManager().getCurrentSequencedEvent();
if (currentSequencedEvent != null) {
currentSequencedEvent.dispose();
}
/*
* Event processing is done inside doPrivileged block so that
* it wouldn't matter even if user code is on the stack
* Fix for BugId 6300270
*/
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
pumpEventsForFilter.run();
return null;
}
});
} else {
synchronized (getTreeLock()) {
Toolkit.getEventQueue().postEvent(new PeerEvent(this,
pumpEventsForFilter,
PeerEvent.PRIORITY_EVENT));
while (keepBlockingCT && windowClosingException == null) {
try {
getTreeLock().wait();
} catch (InterruptedException e) {
break;
}
}
}
EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
secondaryLoop = eventQueue.createSecondaryLoop(cond, modalFilter, 5000);
if (!secondaryLoop.enter()) {
secondaryLoop = null;
}
} finally {
modalityPopped();
......@@ -1194,18 +1131,11 @@ public class Dialog extends Window {
windowClosingException = null;
}
}
final class WakingRunnable implements Runnable {
public void run() {
synchronized (getTreeLock()) {
keepBlockingCT = false;
getTreeLock().notifyAll();
}
}
}
private void hideAndDisposePreHandler() {
isInHide = true;
synchronized (getTreeLock()) {
if (keepBlockingEDT) {
if (secondaryLoop != null) {
modalHide();
// dialog can be shown and then disposed before its
// modal filter is created
......@@ -1217,20 +1147,9 @@ public class Dialog extends Window {
}
}
private void hideAndDisposeHandler() {
synchronized (getTreeLock()) {
if (keepBlockingEDT) {
keepBlockingEDT = false;
PeerEvent wakingEvent = new PeerEvent(getToolkit(), new WakingRunnable(), PeerEvent.PRIORITY_EVENT);
AppContext curAppContext = AppContext.getAppContext();
if (showAppContext != curAppContext) {
// Wake up event dispatch thread on which the dialog was
// initially shown
SunToolkit.postEvent(showAppContext, wakingEvent);
showAppContext = null;
} else {
Toolkit.getEventQueue().postEvent(wakingEvent);
}
}
if (secondaryLoop != null) {
secondaryLoop.exit();
secondaryLoop = null;
}
isInHide = false;
}
......
......@@ -113,8 +113,7 @@ class EventDispatchThread extends Thread {
pumpEventsForHierarchy(id, cond, null);
}
void pumpEventsForHierarchy(int id, Conditional cond, Component modalComponent)
{
void pumpEventsForHierarchy(int id, Conditional cond, Component modalComponent) {
pumpEventsForFilter(id, cond, new HierarchyEventFilter(modalComponent));
}
......@@ -124,6 +123,7 @@ class EventDispatchThread extends Thread {
void pumpEventsForFilter(int id, Conditional cond, EventFilter filter) {
addEventFilter(filter);
doDispatch = true;
while (doDispatch && cond.evaluate()) {
if (isInterrupted() || !pumpOneEventForFilters(id)) {
doDispatch = false;
......@@ -133,6 +133,7 @@ class EventDispatchThread extends Thread {
}
void addEventFilter(EventFilter filter) {
eventLog.finest("adding the event filter: " + filter);
synchronized (eventFilters) {
if (!eventFilters.contains(filter)) {
if (filter instanceof ModalEventFilter) {
......@@ -156,6 +157,7 @@ class EventDispatchThread extends Thread {
}
void removeEventFilter(EventFilter filter) {
eventLog.finest("removing the event filter: " + filter);
synchronized (eventFilters) {
eventFilters.remove(filter);
}
......
......@@ -883,6 +883,41 @@ public class EventQueue {
}
}
/**
* Creates a new {@code secondary loop} associated with this
* event queue. Use the {@link SecondaryLoop#enter} and
* {@link SecondaryLoop#exit} methods to start and stop the
* event loop and dispatch the events from this queue.
*
* @return secondaryLoop A new secondary loop object, which can
* be used to launch a new nested event
* loop and dispatch events from this queue
*
* @see SecondaryLoop#enter
* @see SecondaryLoop#exit
*
* @since 1.7
*/
public SecondaryLoop createSecondaryLoop() {
return createSecondaryLoop(null, null, 0);
}
SecondaryLoop createSecondaryLoop(Conditional cond, EventFilter filter, long interval) {
pushPopLock.lock();
try {
if (nextQueue != null) {
// Forward the request to the top of EventQueue stack
return nextQueue.createSecondaryLoop(cond, filter, interval);
}
if (dispatchThread == null) {
initDispatchThread();
}
return new WaitDispatchSupport(dispatchThread, cond, filter, interval);
} finally {
pushPopLock.unlock();
}
}
/**
* Returns true if the calling thread is
* {@link Toolkit#getSystemEventQueue the current AWT EventQueue}'s
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt;
/**
* A helper interface to run the nested event loop.
* <p>
* Objects that implement this interface are created with the
* {@link EventQueue#createSecondaryLoop} method. The interface
* provides two methods, {@link enter} and {@link exit},
* which can be used to start and stop the event loop.
* <p>
* When the {@link enter} method is called, the current
* thread is blocked until the loop is terminated by the
* {@link exit} method. Also, a new event loop is started
* on the event dispatch thread, which may or may not be
* the current thread. The loop can be terminated on any
* thread by calling its {@link exit} method. After the
* loop is terminated, the {@code SecondaryLoop} object can
* be reused to run a new nested event loop.
* <p>
* A typical use case of applying this interface is AWT
* and Swing modal dialogs. When a modal dialog is shown on
* the event dispatch thread, it enters a new secondary loop.
* Later, when the dialog is hidden or disposed, it exits
* the loop, and the thread continues its execution.
* <p>
* The following example illustrates a simple use case of
* secondary loops:
*
* <pre>
* SecondaryLoop loop;
*
* JButton jButton = new JButton("Button");
* jButton.addActionListener(new ActionListener() {
* {@code @Override}
* public void actionPerformed(ActionEvent e) {
* Toolkit tk = Toolkit.getDefaultToolkit();
* EventQueue eq = tk.getSystemEventQueue();
* loop = eq.createSecondaryLoop();
*
* // Spawn a new thread to do the work
* Thread worker = new WorkerThread();
* worker.start();
*
* // Enter the loop to block the current event
* // handler, but leave UI responsive
* if (!loop.enter()) {
* // Report an error
* }
* }
* });
*
* class WorkerThread extends Thread {
* {@code @Override}
* public void run() {
* // Perform calculations
* doSomethingUseful();
*
* // Exit the loop
* loop.exit();
* }
* }
* </pre>
*
* @see Dialog#show
* @see EventQueue#createSecondaryLoop
* @see Toolkit#getSystemEventQueue
*
* @author Anton Tarasov, Artem Ananiev
*
* @since 1.7
*/
public interface SecondaryLoop {
/**
* Blocks the execution of the current thread and enters a new
* secondary event loop on the event dispatch thread.
* <p>
* This method can be called by any thread including the event
* dispatch thread. This thread will be blocked until the {@link
* exit} method is called or the loop is terminated. A new
* secondary loop will be created on the event dispatch thread
* for dispatching events in either case.
* <p>
* This method can only start one new event loop at a time per
* object. If a secondary event loop has already been started
* by this object and is currently still running, this method
* returns {@code false} to indicate that it was not successful
* in starting a new event loop. Otherwise, this method blocks
* the calling thread and later returns {@code true} when the
* new event loop is terminated. At such time, this object can
* again be used to start another new event loop.
*
* @return {@code true} after termination of the secondary loop,
* if the secondary loop was started by this call,
* {@code false} otherwise
*/
public boolean enter();
/**
* Unblocks the execution of the thread blocked by the {@link
* enter} method and exits the secondary loop.
* <p>
* This method resumes the thread that called the {@link enter}
* method and exits the secondary loop that was created when
* the {@link enter} method was invoked.
* <p>
* Note that if any other secondary loop is started while this
* loop is running, the blocked thread will not resume execution
* until the nested loop is terminated.
* <p>
* If this secondary loop has not been started with the {@link
* enter} method, or this secondary loop has already finished
* with the {@link exit} method, this method returns {@code
* false}, otherwise {@code true} is returned.
*
* @return {@code true} if this loop was previously started and
* has not yet been finished with the {@link exit} method,
* {@code false} otherwise
*/
public boolean exit();
}
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import java.security.PrivilegedAction;
import java.security.AccessController;
import sun.awt.PeerEvent;
import sun.util.logging.PlatformLogger;
/**
* This utility class is used to suspend execution on a thread
* while still allowing {@code EventDispatchThread} to dispatch events.
* The API methods of the class are thread-safe.
*
* @author Anton Tarasov, Artem Ananiev
*
* @since 1.7
*/
class WaitDispatchSupport implements SecondaryLoop {
private final static PlatformLogger log =
PlatformLogger.getLogger("java.awt.event.WaitDispatchSupport");
private EventDispatchThread dispatchThread;
private EventFilter filter;
private volatile Conditional extCondition;
private volatile Conditional condition;
private long interval;
// Use a shared daemon timer to serve all the WaitDispatchSupports
private static Timer timer;
// When this WDS expires, we cancel the timer task leaving the
// shared timer up and running
private TimerTask timerTask;
private AtomicBoolean keepBlockingEDT = new AtomicBoolean(false);
private AtomicBoolean keepBlockingCT = new AtomicBoolean(false);
private static synchronized void initializeTimer() {
if (timer == null) {
timer = new Timer("AWT-WaitDispatchSupport-Timer", true);
}
}
/**
* Creates a {@code WaitDispatchSupport} instance to
* serve the given event dispatch thread.
*
* @param dispatchThread An event dispatch thread that
* should not stop dispatching events while waiting
*
* @since 1.7
*/
public WaitDispatchSupport(EventDispatchThread dispatchThread) {
this(dispatchThread, null);
}
/**
* Creates a {@code WaitDispatchSupport} instance to
* serve the given event dispatch thread.
*
* @param dispatchThread An event dispatch thread that
* should not stop dispatching events while waiting
* @param extCondition A conditional object used to determine
* if the loop should be terminated
*
* @since 1.7
*/
public WaitDispatchSupport(EventDispatchThread dispatchThread,
Conditional extCond)
{
if (dispatchThread == null) {
throw new IllegalArgumentException("The dispatchThread can not be null");
}
this.dispatchThread = dispatchThread;
this.extCondition = extCond;
this.condition = new Conditional() {
@Override
public boolean evaluate() {
if (log.isLoggable(PlatformLogger.FINEST)) {
log.finest("evaluate(): blockingEDT=" + keepBlockingEDT.get() +
", blockingCT=" + keepBlockingCT.get());
}
boolean extEvaluate =
(extCondition != null) ? extCondition.evaluate() : true;
if (!keepBlockingEDT.get() || !extEvaluate) {
if (timerTask != null) {
timerTask.cancel();
timerTask = null;
}
return false;
}
return true;
}
};
}
/**
* Creates a {@code WaitDispatchSupport} instance to
* serve the given event dispatch thread.
* <p>
* The {@link EventFilter} is set on the {@code dispatchThread}
* while waiting. The filter is removed on completion of the
* waiting process.
* <p>
*
*
* @param dispatchThread An event dispatch thread that
* should not stop dispatching events while waiting
* @param filter {@code EventFilter} to be set
* @param interval A time interval to wait for. Note that
* when the waiting process takes place on EDT
* there is no guarantee to stop it in the given time
*
* @since 1.7
*/
public WaitDispatchSupport(EventDispatchThread dispatchThread,
Conditional extCondition,
EventFilter filter, long interval)
{
this(dispatchThread, extCondition);
this.filter = filter;
if (interval < 0) {
throw new IllegalArgumentException("The interval value must be >= 0");
}
this.interval = interval;
if (interval != 0) {
initializeTimer();
}
}
/**
* @inheritDoc
*/
@Override
public boolean enter() {
log.fine("enter(): blockingEDT=" + keepBlockingEDT.get() +
", blockingCT=" + keepBlockingCT.get());
if (!keepBlockingEDT.compareAndSet(false, true)) {
log.fine("The secondary loop is already running, aborting");
return false;
}
final Runnable run = new Runnable() {
public void run() {
log.fine("Starting a new event pump");
if (filter == null) {
dispatchThread.pumpEvents(condition);
} else {
dispatchThread.pumpEventsForFilter(condition, filter);
}
}
};
// We have two mechanisms for blocking: if we're on the
// dispatch thread, start a new event pump; if we're
// on any other thread, call wait() on the treelock
Thread currentThread = Thread.currentThread();
if (currentThread == dispatchThread) {
log.finest("On dispatch thread: " + dispatchThread);
if (interval != 0) {
log.finest("scheduling the timer for " + interval + " ms");
timer.schedule(timerTask = new TimerTask() {
@Override
public void run() {
if (keepBlockingEDT.compareAndSet(true, false)) {
wakeupEDT();
}
}
}, interval);
}
// Dispose SequencedEvent we are dispatching on the the current
// AppContext, to prevent us from hang - see 4531693 for details
SequencedEvent currentSE = KeyboardFocusManager.
getCurrentKeyboardFocusManager().getCurrentSequencedEvent();
if (currentSE != null) {
log.fine("Dispose current SequencedEvent: " + currentSE);
currentSE.dispose();
}
// In case the exit() method is called before starting
// new event pump it will post the waking event to EDT.
// The event will be handled after the the new event pump
// starts. Thus, the enter() method will not hang.
//
// Event pump should be privileged. See 6300270.
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
run.run();
return null;
}
});
} else {
log.finest("On non-dispatch thread: " + currentThread);
synchronized (getTreeLock()) {
if (filter != null) {
dispatchThread.addEventFilter(filter);
}
try {
EventQueue eq = dispatchThread.getEventQueue();
eq.postEvent(new PeerEvent(this, run, PeerEvent.PRIORITY_EVENT));
keepBlockingCT.set(true);
if (interval > 0) {
long currTime = System.currentTimeMillis();
while (keepBlockingCT.get() &&
((extCondition != null) ? extCondition.evaluate() : true) &&
(currTime + interval > System.currentTimeMillis()))
{
getTreeLock().wait(interval);
}
} else {
while (keepBlockingCT.get() &&
((extCondition != null) ? extCondition.evaluate() : true))
{
getTreeLock().wait();
}
}
log.fine("waitDone " + keepBlockingEDT.get() + " " + keepBlockingCT.get());
} catch (InterruptedException e) {
log.fine("Exception caught while waiting: " + e);
} finally {
if (filter != null) {
dispatchThread.removeEventFilter(filter);
}
}
// If the waiting process has been stopped because of the
// time interval passed or an exception occurred, the state
// should be changed
keepBlockingEDT.set(false);
keepBlockingCT.set(false);
}
}
return true;
}
/**
* @inheritDoc
*/
public boolean exit() {
log.fine("exit(): blockingEDT=" + keepBlockingEDT.get() +
", blockingCT=" + keepBlockingCT.get());
if (keepBlockingEDT.compareAndSet(true, false)) {
wakeupEDT();
return true;
}
return false;
}
private final static Object getTreeLock() {
return Component.LOCK;
}
private final Runnable wakingRunnable = new Runnable() {
public void run() {
log.fine("Wake up EDT");
synchronized (getTreeLock()) {
keepBlockingCT.set(false);
getTreeLock().notifyAll();
}
log.fine("Wake up EDT done");
}
};
private void wakeupEDT() {
log.finest("wakeupEDT(): EDT == " + dispatchThread);
EventQueue eq = dispatchThread.getEventQueue();
eq.postEvent(new PeerEvent(this, wakingRunnable, PeerEvent.PRIORITY_EVENT));
}
}
......@@ -794,6 +794,11 @@ BOOL AwtMenuItem::IsSeparator() {
jobject jitem = GetTarget(env);
jstring label =
(jstring)(env)->GetObjectField(jitem, AwtMenuItem::labelID);
if (label == NULL) {
env->DeleteLocalRef(label);
env->DeleteLocalRef(jitem);
return FALSE; //separator must has '-' as label.
}
LPCWSTR labelW = JNU_GetStringPlatformChars(env, label, NULL);
BOOL isSeparator = (labelW && (wcscmp(labelW, L"-") == 0));
JNU_ReleaseStringPlatformChars(env, label, labelW);
......
......@@ -113,8 +113,6 @@ public:
// Used to prevent untrusted code from synthesizing a WM_PASTE message
// by posting a <CTRL>-V KeyEvent
BOOL m_synthetic;
virtual void EditSetSel(CHARRANGE &cr) = 0;
virtual void EditGetSel(CHARRANGE &cr) = 0;
virtual LONG EditGetCharFromPos(POINT& pt) = 0;
private:
......
......@@ -41,7 +41,9 @@ struct SetEchoCharStruct {
* AwtTextField methods
*/
AwtTextField::AwtTextField() {
AwtTextField::AwtTextField()
: m_initialRescrollFlag( true )
{
}
/* Create a new AwtTextField object and window. */
......@@ -116,10 +118,6 @@ void AwtTextField::EditSetSel(CHARRANGE &cr) {
SendMessage(EM_SETSEL, cr.cpMin, cr.cpMax);
}
void AwtTextField::EditGetSel(CHARRANGE &cr) {
SendMessage(EM_SETSEL, reinterpret_cast<WPARAM>(&cr.cpMin), reinterpret_cast<LPARAM>(&cr.cpMax));
}
LONG AwtTextField::EditGetCharFromPos(POINT& pt) {
return static_cast<LONG>(SendMessage(EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y)));
}
......@@ -153,11 +151,9 @@ AwtTextField::HandleEvent(MSG *msg, BOOL synthetic)
* The workaround also allows us to implement synthetic focus mechanism.
*/
if (IsFocusingMouseMessage(msg)) {
CHARRANGE cr;
LONG lCurPos = EditGetCharFromPos(msg->pt);
EditGetSel(cr);
/*
* NOTE: Plain EDIT control always clears selection on mouse
* button press. We are clearing the current selection only if
......@@ -174,6 +170,7 @@ AwtTextField::HandleEvent(MSG *msg, BOOL synthetic)
SetStartSelectionPos(lCurPos);
SetEndSelectionPos(lCurPos);
}
CHARRANGE cr;
cr.cpMin = GetStartSelectionPos();
cr.cpMax = GetEndSelectionPos();
EditSetSel(cr);
......@@ -310,6 +307,47 @@ ret:
delete secs;
}
void AwtTextField::Reshape(int x, int y, int w, int h)
{
AwtTextComponent::Reshape( x, y, w, h );
// Another option would be to call this
// after WM_SIZE notification is handled
initialRescroll();
}
// Windows' Edit control features:
// (i) if text selection is set while control's width or height is 0,
// text is scrolled oddly.
// (ii) if control's size is changed, text seems never be automatically
// rescrolled.
//
// This method is designed for the following scenario: AWT spawns Edit
// control with 0x0 dimensions, then sets text selection, then resizes the
// control (couple of times). This might cause text appear undesirably scrolled.
// So we reset/set selection again to rescroll text. (see also CR 6480547)
void AwtTextField::initialRescroll()
{
if( ! m_initialRescrollFlag ) {
return;
}
::RECT r;
BOOL ok = ::GetClientRect( GetHWnd(), &r );
if( ! ok || r.right==0 || r.bottom==0 ) {
return;
}
m_initialRescrollFlag = false;
DWORD start, end;
SendMessage( EM_GETSEL, (WPARAM)&start, (LPARAM)&end );
SendMessage( EM_SETSEL, (WPARAM)0, (LPARAM)0 );
SendMessage( EM_SETSEL, (WPARAM)start, (LPARAM)end );
}
/************************************************************************
* WTextFieldPeer native methods
*/
......
......@@ -55,9 +55,14 @@ public:
static void _SetEchoChar(void *param);
protected:
void EditSetSel(CHARRANGE &cr);
void EditGetSel(CHARRANGE &cr);
LONG EditGetCharFromPos(POINT& pt);
virtual void Reshape(int x, int y, int w, int h);
private:
void EditSetSel(CHARRANGE &cr);
void initialRescroll();
bool m_initialRescrollFlag;
};
#endif /* AWT_TEXTFIELD_H */
/*
* Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -193,12 +193,17 @@ public:
// Execute on Toolkit only.
INLINE static LRESULT SynthesizeWmActivate(BOOL doActivate, HWND targetHWnd, HWND oppositeHWnd) {
if (::IsWindowVisible(targetHWnd)) {
return ::SendMessage(targetHWnd, WM_ACTIVATE,
MAKEWPARAM(doActivate ? WA_ACTIVE : WA_INACTIVE, FALSE),
(LPARAM) oppositeHWnd);
if (doActivate &&
(!::IsWindowVisible(targetHWnd) || ::IsIconic(::GetAncestor(targetHWnd, GA_ROOT))))
{
// The activation is rejected if either:
// - The toplevel is not visible
// - The toplevel (or its embedder) is minimised
return 1;
}
return 1; // if not processed
return ::SendMessage(targetHWnd, WM_ACTIVATE,
MAKEWPARAM(doActivate ? WA_ACTIVE : WA_INACTIVE, FALSE),
(LPARAM) oppositeHWnd);
}
void moveToDefaultLocation(); /* moves Window to X,Y specified by Window Manger */
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
@test
@bug 6949936
@author Artem Ananiev: area=eventqueue
@run main/timeout=30 SecondaryLoopTest
*/
import java.awt.*;
/**
* Unit test for java.awt.SecondaryLoop implementation
*/
public class SecondaryLoopTest {
private static volatile boolean loopStarted;
private static volatile boolean doubleEntered;
private static volatile boolean loopActive;
private static volatile boolean eventDispatched;
public static void main(String[] args) throws Exception {
test(true, true);
test(true, false);
test(false, true);
test(false, false);
}
private static void test(final boolean enterEDT, final boolean exitEDT) throws Exception {
System.out.println("Running test(" + enterEDT + ", " + exitEDT + ")");
System.err.flush();
loopStarted = true;
Runnable enterRun = new Runnable() {
@Override
public void run() {
Toolkit tk = Toolkit.getDefaultToolkit();
EventQueue eq = tk.getSystemEventQueue();
final SecondaryLoop loop = eq.createSecondaryLoop();
doubleEntered = false;
eventDispatched = false;
Runnable eventRun = new Runnable() {
@Override
public void run() {
// Let the loop enter
sleep(1000);
if (loop.enter()) {
doubleEntered = true;
}
eventDispatched = true;
}
};
EventQueue.invokeLater(eventRun);
Runnable exitRun = new Runnable() {
@Override
public void run() {
// Let the loop enter and eventRun finish
sleep(2000);
if (doubleEntered) {
// Hopefully, we get here if the loop is entered twice
loop.exit();
}
loop.exit();
}
};
if (exitEDT) {
EventQueue.invokeLater(exitRun);
} else {
new Thread(exitRun).start();
}
if (!loop.enter()) {
loopStarted = false;
}
loopActive = eventDispatched;
}
};
if (enterEDT) {
EventQueue.invokeAndWait(enterRun);
} else {
enterRun.run();
}
// Print all the flags before we fail with exception
System.out.println(" loopStarted = " + loopStarted);
System.out.println(" doubleEntered = " + doubleEntered);
System.out.println(" loopActive = " + loopActive);
System.out.flush();
if (!loopStarted) {
throw new RuntimeException("Test FAILED: the secondary loop is not started");
}
if (doubleEntered) {
throw new RuntimeException("Test FAILED: the secondary loop is started twice");
}
if (!loopActive) {
throw new RuntimeException("Test FAILED: the secondary loop exited immediately");
}
}
private static void sleep(long t) {
try {
Thread.sleep(t);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
}
/* @test 1.5 98/07/23
@bug 4064202 4253466
@summary Test for Win32 NPE when MenuItem with null label added.
@author fred.ecks
@run main/othervm NullMenuLabelTest
*/
import java.awt.*;
public class NullMenuLabelTest {
public static void main(String[] args) {
Frame frame = new Frame("Test Frame");
frame.pack();
frame.setVisible(true);
MenuBar menuBar = new MenuBar();
frame.setMenuBar(menuBar);
Menu menu = new Menu(null);
menuBar.add(menu);
menu.add(new MenuItem(null));
// If we got this far, the test succeeded
frame.setVisible(false);
frame.dispose();
}
} // class NullMenuLabelTest
......@@ -53,13 +53,14 @@ public class ScrollSelectionTest extends Applet
frame.add(tf);
tf.select(0, 20);
String[] instructions =
{
String[] instructions = {
"INSTRUCTIONS:",
"This is a test for a win32 specific problem",
"If you see all the letters from 'a' to 'z' and",
"letters from 'a' to 't' are selected then test passes"
};
"If you see all the letters from 'a' to 'z' and",
"letters from 'a' to 't' are selected then test passes.",
"You may have to activate the frame to see the selection"
+ " highlighted (e.g. by clicking on frame's title)."
};
Sysout.createDialogWithInstructions( instructions );
}// init()
......
......@@ -114,6 +114,7 @@ public class SpuriousExitEnter_3 {
checkEvents(frameAdapter, 1, 1);
checkEvents(buttonAdapter, 0, 0);
w.setVisible(false);
Util.waitForIdle(r);
}
public static void main(String []s)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册