提交 4e91a930 编写于 作者: L lana

Merge

...@@ -24,20 +24,17 @@ ...@@ -24,20 +24,17 @@
*/ */
package javax.swing; package javax.swing;
import java.applet.Applet;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.awt.image.*; import java.awt.image.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.util.*; import java.util.*;
import com.sun.java.swing.SwingUtilities3; import com.sun.java.swing.SwingUtilities3;
import sun.awt.SubRegionShowable; import sun.awt.SubRegionShowable;
import sun.java2d.SunGraphics2D; import sun.java2d.SunGraphics2D;
import sun.security.action.GetPropertyAction;
import sun.java2d.pipe.hw.ExtendedBufferCapabilities; import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger;
...@@ -119,10 +116,6 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager { ...@@ -119,10 +116,6 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
* Farthest JComponent ancestor for the current paint/copyArea. * Farthest JComponent ancestor for the current paint/copyArea.
*/ */
private JComponent rootJ; private JComponent rootJ;
/**
* Parent Applet/Window for the current paint/copyArea
*/
private Container root;
/** /**
* Location of component being painted relative to root. * Location of component being painted relative to root.
*/ */
...@@ -278,7 +271,9 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager { ...@@ -278,7 +271,9 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
public boolean paint(JComponent paintingComponent, public boolean paint(JComponent paintingComponent,
JComponent bufferComponent, Graphics g, JComponent bufferComponent, Graphics g,
int x, int y, int w, int h) { int x, int y, int w, int h) {
if (prepare(paintingComponent, true, x, y, w, h)) { Container root = fetchRoot(paintingComponent);
if (prepare(paintingComponent, root, true, x, y, w, h)) {
if ((g instanceof SunGraphics2D) && if ((g instanceof SunGraphics2D) &&
((SunGraphics2D)g).getDestination() == root) { ((SunGraphics2D)g).getDestination() == root) {
// BufferStrategy may have already constrained the Graphics. To // BufferStrategy may have already constrained the Graphics. To
...@@ -319,7 +314,9 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager { ...@@ -319,7 +314,9 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
// //
// If the buffer isn't in sync there is no point in doing a copyArea, // If the buffer isn't in sync there is no point in doing a copyArea,
// it has garbage. // it has garbage.
if (prepare(c, false, 0, 0, 0, 0) && bufferInfo.isInSync()) { Container root = fetchRoot(c);
if (prepare(c, root, false, 0, 0, 0, 0) && bufferInfo.isInSync()) {
if (clip) { if (clip) {
Rectangle cBounds = c.getVisibleRect(); Rectangle cBounds = c.getVisibleRect();
int relX = xOffset + x; int relX = xOffset + x;
...@@ -500,14 +497,14 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager { ...@@ -500,14 +497,14 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
* *
* @return true if should use buffering per window in painting. * @return true if should use buffering per window in painting.
*/ */
private boolean prepare(JComponent c, boolean isPaint, int x, int y, private boolean prepare(JComponent c, Container root, boolean isPaint, int x, int y,
int w, int h) { int w, int h) {
if (bsg != null) { if (bsg != null) {
bsg.dispose(); bsg.dispose();
bsg = null; bsg = null;
} }
bufferStrategy = null; bufferStrategy = null;
if (fetchRoot(c)) { if (root != null) {
boolean contentsLost = false; boolean contentsLost = false;
BufferInfo bufferInfo = getBufferInfo(root); BufferInfo bufferInfo = getBufferInfo(root);
if (bufferInfo == null) { if (bufferInfo == null) {
...@@ -567,10 +564,10 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager { ...@@ -567,10 +564,10 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
return false; return false;
} }
private boolean fetchRoot(JComponent c) { private Container fetchRoot(JComponent c) {
boolean encounteredHW = false; boolean encounteredHW = false;
rootJ = c; rootJ = c;
root = c; Container root = c;
xOffset = yOffset = 0; xOffset = yOffset = 0;
while (root != null && while (root != null &&
(!(root instanceof Window) && (!(root instanceof Window) &&
...@@ -597,7 +594,7 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager { ...@@ -597,7 +594,7 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
// heavyweights. If we didn't do this when we // heavyweights. If we didn't do this when we
// went to show the descendants of the nested hw // went to show the descendants of the nested hw
// you would see nothing, so, we bail out here. // you would see nothing, so, we bail out here.
return false; return null;
} }
} }
} }
...@@ -613,11 +610,11 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager { ...@@ -613,11 +610,11 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
// bit tricky with Swing. This gives a good approximation // bit tricky with Swing. This gives a good approximation
// of the various ways to turn on double buffering for // of the various ways to turn on double buffering for
// components. // components.
return true; return root;
} }
} }
// Don't do true double buffering. // Don't do true double buffering.
return false; return null;
} }
/** /**
......
/* /*
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2011, Oracle and/or its affiliates. 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
...@@ -334,6 +334,7 @@ SplashRedrawWindow(Splash * splash) { ...@@ -334,6 +334,7 @@ SplashRedrawWindow(Splash * splash) {
XDestroyImage(ximage); XDestroyImage(ximage);
SplashRemoveDecoration(splash); SplashRemoveDecoration(splash);
XMapWindow(splash->display, splash->window); XMapWindow(splash->display, splash->window);
XFlush(splash->display);
} }
void SplashReconfigureNow(Splash * splash) { void SplashReconfigureNow(Splash * splash) {
......
...@@ -615,6 +615,14 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -615,6 +615,14 @@ public abstract class WComponentPeer extends WObjectPeer
_dispose(); _dispose();
} }
public void disposeLater() {
postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), new Runnable() {
public void run() {
dispose();
}
}));
}
public synchronized void setForeground(Color c) { public synchronized void setForeground(Color c) {
foreground = c; foreground = c;
_setForeground(c.getRGB()); _setForeground(c.getRGB());
......
...@@ -183,6 +183,7 @@ jmethodID AwtComponent::isEnabledMID; ...@@ -183,6 +183,7 @@ jmethodID AwtComponent::isEnabledMID;
jmethodID AwtComponent::getLocationOnScreenMID; jmethodID AwtComponent::getLocationOnScreenMID;
jmethodID AwtComponent::replaceSurfaceDataMID; jmethodID AwtComponent::replaceSurfaceDataMID;
jmethodID AwtComponent::replaceSurfaceDataLaterMID; jmethodID AwtComponent::replaceSurfaceDataLaterMID;
jmethodID AwtComponent::disposeLaterMID;
HKL AwtComponent::m_hkl = ::GetKeyboardLayout(0); HKL AwtComponent::m_hkl = ::GetKeyboardLayout(0);
LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0)); LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0));
...@@ -246,6 +247,7 @@ AwtComponent::AwtComponent() ...@@ -246,6 +247,7 @@ AwtComponent::AwtComponent()
m_hCursorCache = NULL; m_hCursorCache = NULL;
m_bSubclassed = FALSE; m_bSubclassed = FALSE;
m_bPauseDestroy = FALSE;
m_MessagesProcessing = 0; m_MessagesProcessing = 0;
m_wheelRotationAmount = 0; m_wheelRotationAmount = 0;
...@@ -319,6 +321,12 @@ void AwtComponent::Dispose() ...@@ -319,6 +321,12 @@ void AwtComponent::Dispose()
m_brushBackground = NULL; m_brushBackground = NULL;
} }
if (m_bPauseDestroy) {
// AwtComponent::WmNcDestroy could be released now
m_bPauseDestroy = FALSE;
m_hwnd = NULL;
}
// The component instance is deleted using AwtObject::Dispose() method // The component instance is deleted using AwtObject::Dispose() method
AwtObject::Dispose(); AwtObject::Dispose();
} }
...@@ -1377,6 +1385,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) ...@@ -1377,6 +1385,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
case WM_CREATE: mr = WmCreate(); break; case WM_CREATE: mr = WmCreate(); break;
case WM_CLOSE: mr = WmClose(); break; case WM_CLOSE: mr = WmClose(); break;
case WM_DESTROY: mr = WmDestroy(); break; case WM_DESTROY: mr = WmDestroy(); break;
case WM_NCDESTROY: mr = WmNcDestroy(); break;
case WM_ERASEBKGND: case WM_ERASEBKGND:
mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break; mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break;
...@@ -1965,10 +1974,24 @@ LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -1965,10 +1974,24 @@ LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
*/ */
MsgRouting AwtComponent::WmDestroy() MsgRouting AwtComponent::WmDestroy()
{ {
// fix for 6259348: we should enter the SyncCall critical section before return mrConsume;
// disposing the native object, that is value 1 of lParam is intended for }
if(m_peerObject != NULL) { // is not being terminating
AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)m_peerObject, (LPARAM)1); /*
* This message should only be received when a window is destroyed by
* Windows, and not Java. It is sent only after child windows were destroyed.
*/
MsgRouting AwtComponent::WmNcDestroy()
{
if (m_peerObject != NULL) { // is not being terminating
// Stay in this handler until AwtComponent::Dispose is called.
m_bPauseDestroy = TRUE;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
// Post invocation event for WObjectPeer.dispose to EDT
env->CallVoidMethod(m_peerObject, AwtComponent::disposeLaterMID);
// Wait until AwtComponent::Dispose is called
AwtToolkit::GetInstance().PumpToDestroy(this);
} }
return mrConsume; return mrConsume;
...@@ -6300,6 +6323,7 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls) ...@@ -6300,6 +6323,7 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
env->GetMethodID(peerCls, "replaceSurfaceData", "()V"); env->GetMethodID(peerCls, "replaceSurfaceData", "()V");
AwtComponent::replaceSurfaceDataLaterMID = AwtComponent::replaceSurfaceDataLaterMID =
env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V"); env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V");
AwtComponent::disposeLaterMID = env->GetMethodID(peerCls, "disposeLater", "()V");
DASSERT(AwtComponent::xID); DASSERT(AwtComponent::xID);
DASSERT(AwtComponent::yID); DASSERT(AwtComponent::yID);
...@@ -6318,6 +6342,8 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls) ...@@ -6318,6 +6342,8 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
DASSERT(AwtComponent::getLocationOnScreenMID); DASSERT(AwtComponent::getLocationOnScreenMID);
DASSERT(AwtComponent::replaceSurfaceDataMID); DASSERT(AwtComponent::replaceSurfaceDataMID);
DASSERT(AwtComponent::replaceSurfaceDataLaterMID); DASSERT(AwtComponent::replaceSurfaceDataLaterMID);
DASSERT(AwtComponent::disposeLaterMID);
CATCH_BAD_ALLOC; CATCH_BAD_ALLOC;
} }
......
...@@ -119,6 +119,7 @@ public: ...@@ -119,6 +119,7 @@ public:
static jmethodID getLocationOnScreenMID; static jmethodID getLocationOnScreenMID;
static jmethodID replaceSurfaceDataMID; static jmethodID replaceSurfaceDataMID;
static jmethodID replaceSurfaceDataLaterMID; static jmethodID replaceSurfaceDataLaterMID;
static jmethodID disposeLaterMID;
static const UINT WmAwtIsComponent; static const UINT WmAwtIsComponent;
static jint * masks; //InputEvent mask array static jint * masks; //InputEvent mask array
...@@ -490,6 +491,7 @@ public: ...@@ -490,6 +491,7 @@ public:
virtual MsgRouting WmCreate() {return mrDoDefault;} virtual MsgRouting WmCreate() {return mrDoDefault;}
virtual MsgRouting WmClose() {return mrDoDefault;} virtual MsgRouting WmClose() {return mrDoDefault;}
virtual MsgRouting WmDestroy(); virtual MsgRouting WmDestroy();
virtual MsgRouting WmNcDestroy();
virtual MsgRouting WmActivate(UINT nState, BOOL fMinimized, HWND opposite) virtual MsgRouting WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
{ {
...@@ -711,6 +713,10 @@ public: ...@@ -711,6 +713,10 @@ public:
return m_MessagesProcessing == 0; return m_MessagesProcessing == 0;
} }
BOOL IsDestroyPaused() const {
return m_bPauseDestroy;
}
protected: protected:
static AwtComponent* GetComponentImpl(HWND hWnd); static AwtComponent* GetComponentImpl(HWND hWnd);
...@@ -752,6 +758,7 @@ private: ...@@ -752,6 +758,7 @@ private:
UINT m_mouseButtonClickAllowed; UINT m_mouseButtonClickAllowed;
BOOL m_bSubclassed; BOOL m_bSubclassed;
BOOL m_bPauseDestroy;
COLORREF m_colorForeground; COLORREF m_colorForeground;
COLORREF m_colorBackground; COLORREF m_colorBackground;
......
...@@ -733,26 +733,13 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message, ...@@ -733,26 +733,13 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
return 0; return 0;
} }
case WM_AWT_DISPOSE: { case WM_AWT_DISPOSE: {
BOOL canDispose = TRUE; if(wParam != NULL) {
CriticalSection &syncCS = AwtToolkit::GetInstance().GetSyncCS(); jobject self = (jobject)wParam;
int shouldEnterCriticalSection = (int)lParam; AwtObject *o = (AwtObject *) JNI_GET_PDATA(self);
if (shouldEnterCriticalSection == 1) { env->DeleteGlobalRef(self);
canDispose = syncCS.TryEnter(); if(o != NULL && theAwtObjectList.Remove(o)) {
} o->Dispose();
if (canDispose) {
if(wParam != NULL) {
jobject self = (jobject)wParam;
AwtObject *o = (AwtObject *) JNI_GET_PDATA(self);
env->DeleteGlobalRef(self);
if(o != NULL && theAwtObjectList.Remove(o)) {
o->Dispose();
}
if (shouldEnterCriticalSection) {
syncCS.Leave();
}
} }
} else {
AwtToolkit::GetInstance().PostMessage(WM_AWT_DISPOSE, wParam, lParam);
} }
return 0; return 0;
} }
...@@ -1340,27 +1327,48 @@ BOOL AwtToolkit::PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc) ...@@ -1340,27 +1327,48 @@ BOOL AwtToolkit::PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc)
while (!m_breakMessageLoop && (*lpPeekMessageFunc)(msg)) { while (!m_breakMessageLoop && (*lpPeekMessageFunc)(msg)) {
foundOne = TRUE; foundOne = TRUE;
if (msg.message == WM_QUIT) { ProcessMsg(msg);
m_breakMessageLoop = TRUE;
m_messageLoopResult = static_cast<UINT>(msg.wParam);
if (m_messageLoopResult == EXIT_ALL_ENCLOSING_LOOPS)
::PostQuitMessage(static_cast<int>(msg.wParam)); // make sure all loops exit
break;
}
else if (msg.message != WM_NULL) {
/*
* The AWT in standalone mode (that is, dynamically loaded from the
* Java VM) doesn't have any translation tables to worry about, so
* TranslateAccelerator isn't called.
*/
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
} }
return foundOne; return foundOne;
} }
void AwtToolkit::PumpToDestroy(class AwtComponent* p)
{
MSG msg;
DASSERT(AwtToolkit::PrimaryIdleFunc != NULL);
DASSERT(AwtToolkit::CommonPeekMessageFunc != NULL);
while (p->IsDestroyPaused() && !m_breakMessageLoop) {
PrimaryIdleFunc();
while (p->IsDestroyPaused() && !m_breakMessageLoop && CommonPeekMessageFunc(msg)) {
ProcessMsg(msg);
}
}
}
void AwtToolkit::ProcessMsg(MSG& msg)
{
if (msg.message == WM_QUIT) {
m_breakMessageLoop = TRUE;
m_messageLoopResult = static_cast<UINT>(msg.wParam);
if (m_messageLoopResult == EXIT_ALL_ENCLOSING_LOOPS)
::PostQuitMessage(static_cast<int>(msg.wParam)); // make sure all loops exit
}
else if (msg.message != WM_NULL) {
/*
* The AWT in standalone mode (that is, dynamically loaded from the
* Java VM) doesn't have any translation tables to worry about, so
* TranslateAccelerator isn't called.
*/
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
VOID CALLBACK VOID CALLBACK
AwtToolkit::PrimaryIdleFunc() { AwtToolkit::PrimaryIdleFunc() {
AwtToolkit::SetBusy(FALSE); AwtToolkit::SetBusy(FALSE);
......
...@@ -305,6 +305,8 @@ public: ...@@ -305,6 +305,8 @@ public:
UINT MessageLoop(IDLEPROC lpIdleFunc, PEEKMESSAGEPROC lpPeekMessageFunc); UINT MessageLoop(IDLEPROC lpIdleFunc, PEEKMESSAGEPROC lpPeekMessageFunc);
BOOL PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc); BOOL PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc);
void PumpToDestroy(class AwtComponent* p);
void ProcessMsg(MSG& msg);
BOOL PreProcessMsg(MSG& msg); BOOL PreProcessMsg(MSG& msg);
BOOL PreProcessMouseMsg(class AwtComponent* p, MSG& msg); BOOL PreProcessMouseMsg(class AwtComponent* p, MSG& msg);
BOOL PreProcessKeyMsg(class AwtComponent* p, MSG& msg); BOOL PreProcessKeyMsg(class AwtComponent* p, MSG& msg);
......
/*
* Copyright (c) 2007, 2011, 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 6827032
* @summary Color chooser with drag enabled shouldn't throw NPE
* @author Peter Zhelezniakov
* @library ../regtesthelpers
*/
import sun.awt.SunToolkit;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
public class Test6827032 {
private static volatile Point point;
private static JColorChooser cc;
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(new NimbusLookAndFeel());
Robot robot = new Robot();
robot.setAutoDelay(50);
SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createAndShowGUI();
}
});
toolkit.realSync();
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
Component previewPanel = Util.findSubComponent(cc, "javax.swing.colorchooser.DefaultPreviewPanel");
point = previewPanel.getLocationOnScreen();
}
});
point.translate(5, 5);
robot.mouseMove(point.x, point.y);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame(Test6827032.class.getName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cc = new JColorChooser();
cc.setDragEnabled(true);
frame.add(cc);
frame.pack();
frame.setVisible(true);
}
}
...@@ -116,4 +116,28 @@ public class Util { ...@@ -116,4 +116,28 @@ public class Util {
System.out.println("Got OOME"); System.out.println("Got OOME");
} }
/**
* Find a sub component by class name.
* Always run this method on the EDT thread
*/
public static Component findSubComponent(Component parent, String className) {
String parentClassName = parent.getClass().getName();
if (parentClassName.contains(className)) {
return parent;
}
if (parent instanceof Container) {
for (Component child : ((Container) parent).getComponents()) {
Component subComponent = findSubComponent(child, className);
if (subComponent != null) {
return subComponent;
}
}
}
return null;
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册