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

Merge

......@@ -24,20 +24,17 @@
*/
package javax.swing;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.lang.reflect.*;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.util.*;
import com.sun.java.swing.SwingUtilities3;
import sun.awt.SubRegionShowable;
import sun.java2d.SunGraphics2D;
import sun.security.action.GetPropertyAction;
import sun.java2d.pipe.hw.ExtendedBufferCapabilities;
import sun.awt.SunToolkit;
import sun.util.logging.PlatformLogger;
......@@ -119,10 +116,6 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
* Farthest JComponent ancestor for the current paint/copyArea.
*/
private JComponent rootJ;
/**
* Parent Applet/Window for the current paint/copyArea
*/
private Container root;
/**
* Location of component being painted relative to root.
*/
......@@ -278,7 +271,9 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
public boolean paint(JComponent paintingComponent,
JComponent bufferComponent, Graphics g,
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) &&
((SunGraphics2D)g).getDestination() == root) {
// BufferStrategy may have already constrained the Graphics. To
......@@ -319,7 +314,9 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
//
// If the buffer isn't in sync there is no point in doing a copyArea,
// 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) {
Rectangle cBounds = c.getVisibleRect();
int relX = xOffset + x;
......@@ -500,14 +497,14 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
*
* @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) {
if (bsg != null) {
bsg.dispose();
bsg = null;
}
bufferStrategy = null;
if (fetchRoot(c)) {
if (root != null) {
boolean contentsLost = false;
BufferInfo bufferInfo = getBufferInfo(root);
if (bufferInfo == null) {
......@@ -567,10 +564,10 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
return false;
}
private boolean fetchRoot(JComponent c) {
private Container fetchRoot(JComponent c) {
boolean encounteredHW = false;
rootJ = c;
root = c;
Container root = c;
xOffset = yOffset = 0;
while (root != null &&
(!(root instanceof Window) &&
......@@ -597,7 +594,7 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
// heavyweights. If we didn't do this when we
// went to show the descendants of the nested hw
// you would see nothing, so, we bail out here.
return false;
return null;
}
}
}
......@@ -613,11 +610,11 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager {
// bit tricky with Swing. This gives a good approximation
// of the various ways to turn on double buffering for
// components.
return true;
return root;
}
}
// 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -334,6 +334,7 @@ SplashRedrawWindow(Splash * splash) {
XDestroyImage(ximage);
SplashRemoveDecoration(splash);
XMapWindow(splash->display, splash->window);
XFlush(splash->display);
}
void SplashReconfigureNow(Splash * splash) {
......
......@@ -615,6 +615,14 @@ public abstract class WComponentPeer extends WObjectPeer
_dispose();
}
public void disposeLater() {
postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), new Runnable() {
public void run() {
dispose();
}
}));
}
public synchronized void setForeground(Color c) {
foreground = c;
_setForeground(c.getRGB());
......
......@@ -183,6 +183,7 @@ jmethodID AwtComponent::isEnabledMID;
jmethodID AwtComponent::getLocationOnScreenMID;
jmethodID AwtComponent::replaceSurfaceDataMID;
jmethodID AwtComponent::replaceSurfaceDataLaterMID;
jmethodID AwtComponent::disposeLaterMID;
HKL AwtComponent::m_hkl = ::GetKeyboardLayout(0);
LANGID AwtComponent::m_idLang = LOWORD(::GetKeyboardLayout(0));
......@@ -246,6 +247,7 @@ AwtComponent::AwtComponent()
m_hCursorCache = NULL;
m_bSubclassed = FALSE;
m_bPauseDestroy = FALSE;
m_MessagesProcessing = 0;
m_wheelRotationAmount = 0;
......@@ -319,6 +321,12 @@ void AwtComponent::Dispose()
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
AwtObject::Dispose();
}
......@@ -1377,6 +1385,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
case WM_CREATE: mr = WmCreate(); break;
case WM_CLOSE: mr = WmClose(); break;
case WM_DESTROY: mr = WmDestroy(); break;
case WM_NCDESTROY: mr = WmNcDestroy(); break;
case WM_ERASEBKGND:
mr = WmEraseBkgnd((HDC)wParam, *(BOOL*)&retValue); break;
......@@ -1965,10 +1974,24 @@ LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam)
*/
MsgRouting AwtComponent::WmDestroy()
{
// fix for 6259348: we should enter the SyncCall critical section before
// 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);
return mrConsume;
}
/*
* 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;
......@@ -6300,6 +6323,7 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
env->GetMethodID(peerCls, "replaceSurfaceData", "()V");
AwtComponent::replaceSurfaceDataLaterMID =
env->GetMethodID(peerCls, "replaceSurfaceDataLater", "()V");
AwtComponent::disposeLaterMID = env->GetMethodID(peerCls, "disposeLater", "()V");
DASSERT(AwtComponent::xID);
DASSERT(AwtComponent::yID);
......@@ -6318,6 +6342,8 @@ Java_java_awt_Component_initIDs(JNIEnv *env, jclass cls)
DASSERT(AwtComponent::getLocationOnScreenMID);
DASSERT(AwtComponent::replaceSurfaceDataMID);
DASSERT(AwtComponent::replaceSurfaceDataLaterMID);
DASSERT(AwtComponent::disposeLaterMID);
CATCH_BAD_ALLOC;
}
......
......@@ -119,6 +119,7 @@ public:
static jmethodID getLocationOnScreenMID;
static jmethodID replaceSurfaceDataMID;
static jmethodID replaceSurfaceDataLaterMID;
static jmethodID disposeLaterMID;
static const UINT WmAwtIsComponent;
static jint * masks; //InputEvent mask array
......@@ -490,6 +491,7 @@ public:
virtual MsgRouting WmCreate() {return mrDoDefault;}
virtual MsgRouting WmClose() {return mrDoDefault;}
virtual MsgRouting WmDestroy();
virtual MsgRouting WmNcDestroy();
virtual MsgRouting WmActivate(UINT nState, BOOL fMinimized, HWND opposite)
{
......@@ -711,6 +713,10 @@ public:
return m_MessagesProcessing == 0;
}
BOOL IsDestroyPaused() const {
return m_bPauseDestroy;
}
protected:
static AwtComponent* GetComponentImpl(HWND hWnd);
......@@ -752,6 +758,7 @@ private:
UINT m_mouseButtonClickAllowed;
BOOL m_bSubclassed;
BOOL m_bPauseDestroy;
COLORREF m_colorForeground;
COLORREF m_colorBackground;
......
......@@ -733,26 +733,13 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message,
return 0;
}
case WM_AWT_DISPOSE: {
BOOL canDispose = TRUE;
CriticalSection &syncCS = AwtToolkit::GetInstance().GetSyncCS();
int shouldEnterCriticalSection = (int)lParam;
if (shouldEnterCriticalSection == 1) {
canDispose = syncCS.TryEnter();
}
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();
}
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();
}
} else {
AwtToolkit::GetInstance().PostMessage(WM_AWT_DISPOSE, wParam, lParam);
}
return 0;
}
......@@ -1340,27 +1327,48 @@ BOOL AwtToolkit::PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc)
while (!m_breakMessageLoop && (*lpPeekMessageFunc)(msg)) {
foundOne = TRUE;
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
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);
}
ProcessMsg(msg);
}
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
AwtToolkit::PrimaryIdleFunc() {
AwtToolkit::SetBusy(FALSE);
......
......@@ -305,6 +305,8 @@ public:
UINT MessageLoop(IDLEPROC lpIdleFunc, PEEKMESSAGEPROC lpPeekMessageFunc);
BOOL PumpWaitingMessages(PEEKMESSAGEPROC lpPeekMessageFunc);
void PumpToDestroy(class AwtComponent* p);
void ProcessMsg(MSG& msg);
BOOL PreProcessMsg(MSG& msg);
BOOL PreProcessMouseMsg(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 {
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.
先完成此消息的编辑!
想要评论请 注册