1.1 --- a/src/share/classes/javax/swing/JFileChooser.java Mon Aug 03 18:06:51 2009 -0700
1.2 +++ b/src/share/classes/javax/swing/JFileChooser.java Wed Aug 05 11:06:46 2009 -0700
1.3 @@ -1,5 +1,5 @@
1.4 /*
1.5 - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
1.6 + * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.8 *
1.9 * This code is free software; you can redistribute it and/or modify it
1.10 @@ -739,6 +739,11 @@
1.11
1.12 dialog.show();
1.13 firePropertyChange("JFileChooserDialogIsClosingProperty", dialog, null);
1.14 +
1.15 + // Remove all components from dialog. The MetalFileChooserUI.installUI() method (and other LAFs)
1.16 + // registers AWT listener for dialogs and produces memory leaks. It happens when
1.17 + // installUI invoked after the showDialog method.
1.18 + dialog.getContentPane().removeAll();
1.19 dialog.dispose();
1.20 dialog = null;
1.21 return returnValue;
2.1 --- a/src/share/classes/javax/swing/JInternalFrame.java Mon Aug 03 18:06:51 2009 -0700
2.2 +++ b/src/share/classes/javax/swing/JInternalFrame.java Wed Aug 05 11:06:46 2009 -0700
2.3 @@ -26,13 +26,10 @@
2.4 package javax.swing;
2.5
2.6 import java.awt.*;
2.7 -import java.awt.event.*;
2.8
2.9 import java.beans.PropertyVetoException;
2.10 import java.beans.PropertyChangeEvent;
2.11 -import java.util.EventListener;
2.12
2.13 -import javax.swing.border.Border;
2.14 import javax.swing.event.InternalFrameEvent;
2.15 import javax.swing.event.InternalFrameListener;
2.16 import javax.swing.plaf.*;
2.17 @@ -40,7 +37,6 @@
2.18 import javax.accessibility.*;
2.19
2.20 import java.io.ObjectOutputStream;
2.21 -import java.io.ObjectInputStream;
2.22 import java.io.IOException;
2.23 import java.lang.StringBuilder;
2.24 import java.beans.PropertyChangeListener;
2.25 @@ -1459,19 +1455,22 @@
2.26 SwingUtilities2.compositeRequestFocus(getDesktopIcon());
2.27 }
2.28 else {
2.29 - // FocusPropertyChangeListener will eventually update
2.30 - // lastFocusOwner. As focus requests are asynchronous
2.31 - // lastFocusOwner may be accessed before it has been correctly
2.32 - // updated. To avoid any problems, lastFocusOwner is immediately
2.33 - // set, assuming the request will succeed.
2.34 - lastFocusOwner = getMostRecentFocusOwner();
2.35 - if (lastFocusOwner == null) {
2.36 - // Make sure focus is restored somewhere, so that
2.37 - // we don't leave a focused component in another frame while
2.38 - // this frame is selected.
2.39 - lastFocusOwner = getContentPane();
2.40 + Component component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner();
2.41 + if ((component == null) || !SwingUtilities.isDescendingFrom(component, this)) {
2.42 + // FocusPropertyChangeListener will eventually update
2.43 + // lastFocusOwner. As focus requests are asynchronous
2.44 + // lastFocusOwner may be accessed before it has been correctly
2.45 + // updated. To avoid any problems, lastFocusOwner is immediately
2.46 + // set, assuming the request will succeed.
2.47 + setLastFocusOwner(getMostRecentFocusOwner());
2.48 + if (lastFocusOwner == null) {
2.49 + // Make sure focus is restored somewhere, so that
2.50 + // we don't leave a focused component in another frame while
2.51 + // this frame is selected.
2.52 + setLastFocusOwner(getContentPane());
2.53 + }
2.54 + lastFocusOwner.requestFocus();
2.55 }
2.56 - lastFocusOwner.requestFocus();
2.57 }
2.58 }
2.59
3.1 --- a/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java Mon Aug 03 18:06:51 2009 -0700
3.2 +++ b/src/share/classes/javax/swing/plaf/basic/BasicDesktopIconUI.java Wed Aug 05 11:06:46 2009 -0700
3.3 @@ -1,5 +1,5 @@
3.4 /*
3.5 - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
3.6 + * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3.8 *
3.9 * This code is free software; you can redistribute it and/or modify it
3.10 @@ -32,9 +32,6 @@
3.11 import javax.swing.border.*;
3.12 import javax.swing.plaf.*;
3.13 import java.beans.*;
3.14 -import java.util.EventListener;
3.15 -import java.io.Serializable;
3.16 -
3.17
3.18 /**
3.19 * Basic L&F for a minimized window on a desktop.
3.20 @@ -47,7 +44,6 @@
3.21
3.22 protected JInternalFrame.JDesktopIcon desktopIcon;
3.23 protected JInternalFrame frame;
3.24 - private DesktopIconMover desktopIconMover;
3.25
3.26 /**
3.27 * The title pane component used in the desktop icon.
3.28 @@ -128,21 +124,12 @@
3.29 mouseInputListener = createMouseInputListener();
3.30 desktopIcon.addMouseMotionListener(mouseInputListener);
3.31 desktopIcon.addMouseListener(mouseInputListener);
3.32 - getDesktopIconMover().installListeners();
3.33 }
3.34
3.35 protected void uninstallListeners() {
3.36 desktopIcon.removeMouseMotionListener(mouseInputListener);
3.37 desktopIcon.removeMouseListener(mouseInputListener);
3.38 mouseInputListener = null;
3.39 - getDesktopIconMover().uninstallListeners();
3.40 - }
3.41 -
3.42 - private DesktopIconMover getDesktopIconMover() {
3.43 - if (desktopIconMover == null) {
3.44 - desktopIconMover = new DesktopIconMover(desktopIcon);
3.45 - }
3.46 - return desktopIconMover;
3.47 }
3.48
3.49 protected void installDefaults() {
4.1 --- a/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java Mon Aug 03 18:06:51 2009 -0700
4.2 +++ b/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java Wed Aug 05 11:06:46 2009 -0700
4.3 @@ -1,5 +1,5 @@
4.4 /*
4.5 - * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
4.6 + * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4.8 *
4.9 * This code is free software; you can redistribute it and/or modify it
4.10 @@ -232,6 +232,10 @@
4.11 public void run0() {
4.12 FileSystemView fileSystem = filechooser.getFileSystemView();
4.13
4.14 + if (isInterrupted()) {
4.15 + return;
4.16 + }
4.17 +
4.18 File[] list = fileSystem.getFiles(currentDirectory, filechooser.isFileHidingEnabled());
4.19
4.20 if (isInterrupted()) {
4.21 @@ -268,8 +272,8 @@
4.22
4.23 // To avoid loads of synchronizations with Invoker and improve performance we
4.24 // execute the whole block on the COM thread
4.25 - DoChangeContents doChangeContents = ShellFolder.getInvoker().invoke(new Callable<DoChangeContents>() {
4.26 - public DoChangeContents call() throws Exception {
4.27 + DoChangeContents doChangeContents = ShellFolder.invoke(new Callable<DoChangeContents>() {
4.28 + public DoChangeContents call() {
4.29 int newSize = newFileCache.size();
4.30 int oldSize = fileCache.size();
4.31
5.1 --- a/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java Mon Aug 03 18:06:51 2009 -0700
5.2 +++ b/src/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java Wed Aug 05 11:06:46 2009 -0700
5.3 @@ -27,16 +27,10 @@
5.4
5.5 import java.awt.*;
5.6 import java.awt.event.*;
5.7 -import java.awt.peer.LightweightPeer;
5.8 -
5.9 import javax.swing.*;
5.10 -import javax.swing.border.*;
5.11 import javax.swing.plaf.*;
5.12 import javax.swing.event.*;
5.13 -
5.14 import java.beans.*;
5.15 -import java.io.Serializable;
5.16 -
5.17 import sun.swing.DefaultLookup;
5.18 import sun.swing.UIAction;
5.19
5.20 @@ -55,6 +49,7 @@
5.21 protected MouseInputAdapter borderListener;
5.22 protected PropertyChangeListener propertyChangeListener;
5.23 protected LayoutManager internalFrameLayout;
5.24 + protected ComponentListener componentListener;
5.25 protected MouseInputListener glassPaneDispatcher;
5.26 private InternalFrameListener internalFrameListener;
5.27
5.28 @@ -66,9 +61,9 @@
5.29 protected BasicInternalFrameTitlePane titlePane; // access needs this
5.30
5.31 private static DesktopManager sharedDesktopManager;
5.32 + private boolean componentListenerAdded = false;
5.33
5.34 private Rectangle parentBounds;
5.35 - private DesktopIconMover desktopIconMover;
5.36
5.37 private boolean dragging = false;
5.38 private boolean resizing = false;
5.39 @@ -209,17 +204,14 @@
5.40 frame.getGlassPane().addMouseListener(glassPaneDispatcher);
5.41 frame.getGlassPane().addMouseMotionListener(glassPaneDispatcher);
5.42 }
5.43 + componentListener = createComponentListener();
5.44 if (frame.getParent() != null) {
5.45 parentBounds = frame.getParent().getBounds();
5.46 }
5.47 - getDesktopIconMover().installListeners();
5.48 - }
5.49 -
5.50 - private DesktopIconMover getDesktopIconMover() {
5.51 - if (desktopIconMover == null) {
5.52 - desktopIconMover = new DesktopIconMover(frame);
5.53 + if ((frame.getParent() != null) && !componentListenerAdded) {
5.54 + frame.getParent().addComponentListener(componentListener);
5.55 + componentListenerAdded = true;
5.56 }
5.57 - return desktopIconMover;
5.58 }
5.59
5.60 // Provide a FocusListener to listen for a WINDOW_LOST_FOCUS event,
5.61 @@ -290,7 +282,11 @@
5.62 * @since 1.3
5.63 */
5.64 protected void uninstallListeners() {
5.65 - getDesktopIconMover().uninstallListeners();
5.66 + if ((frame.getParent() != null) && componentListenerAdded) {
5.67 + frame.getParent().removeComponentListener(componentListener);
5.68 + componentListenerAdded = false;
5.69 + }
5.70 + componentListener = null;
5.71 if (glassPaneDispatcher != null) {
5.72 frame.getGlassPane().removeMouseListener(glassPaneDispatcher);
5.73 frame.getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
5.74 @@ -1228,6 +1224,15 @@
5.75 }
5.76 }
5.77
5.78 + // Relocate the icon base on the new parent bounds.
5.79 + if (icon != null) {
5.80 + Rectangle iconBounds = icon.getBounds();
5.81 + int y = iconBounds.y +
5.82 + (parentNewBounds.height - parentBounds.height);
5.83 + icon.setBounds(iconBounds.x, y,
5.84 + iconBounds.width, iconBounds.height);
5.85 + }
5.86 +
5.87 // Update the new parent bounds for next resize.
5.88 if (!parentBounds.equals(parentNewBounds)) {
5.89 parentBounds = parentNewBounds;
5.90 @@ -1399,6 +1404,9 @@
5.91 // Cancel a resize in progress if the internal frame
5.92 // gets a setClosed(true) or dispose().
5.93 cancelResize();
5.94 + if ((frame.getParent() != null) && componentListenerAdded) {
5.95 + frame.getParent().removeComponentListener(componentListener);
5.96 + }
5.97 closeFrame(f);
5.98 }
5.99 } else if (JInternalFrame.IS_MAXIMUM_PROPERTY == prop) {
5.100 @@ -1431,6 +1439,10 @@
5.101 } else {
5.102 parentBounds = null;
5.103 }
5.104 + if ((frame.getParent() != null) && !componentListenerAdded) {
5.105 + f.getParent().addComponentListener(componentListener);
5.106 + componentListenerAdded = true;
5.107 + }
5.108 } else if (JInternalFrame.TITLE_PROPERTY == prop ||
5.109 prop == "closable" || prop == "iconable" ||
5.110 prop == "maximizable") {
6.1 --- a/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java Mon Aug 03 18:06:51 2009 -0700
6.2 +++ b/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java Wed Aug 05 11:06:46 2009 -0700
6.3 @@ -1,5 +1,5 @@
6.4 /*
6.5 - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
6.6 + * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6.8 *
6.9 * This code is free software; you can redistribute it and/or modify it
6.10 @@ -37,17 +37,12 @@
6.11 import java.beans.PropertyChangeEvent;
6.12
6.13 import java.awt.Component;
6.14 -import java.awt.Container;
6.15 -import java.awt.LayoutManager;
6.16 import java.awt.Rectangle;
6.17 import java.awt.Dimension;
6.18 import java.awt.Point;
6.19 import java.awt.Insets;
6.20 import java.awt.Graphics;
6.21 import java.awt.event.*;
6.22 -import java.io.Serializable;
6.23 -import java.awt.Toolkit;
6.24 -import java.awt.ComponentOrientation;
6.25
6.26 /**
6.27 * A default L&F implementation of ScrollPaneUI.
6.28 @@ -63,6 +58,7 @@
6.29 protected ChangeListener viewportChangeListener;
6.30 protected PropertyChangeListener spPropertyChangeListener;
6.31 private MouseWheelListener mouseScrollListener;
6.32 + private int oldExtent = Integer.MIN_VALUE;
6.33
6.34 /**
6.35 * PropertyChangeListener installed on the vertical scrollbar.
6.36 @@ -327,9 +323,13 @@
6.37 * leave it until someone claims.
6.38 */
6.39 value = Math.max(0, Math.min(max - extent, max - extent - viewPosition.x));
6.40 + if (oldExtent > extent) {
6.41 + value -= oldExtent - extent;
6.42 + }
6.43 }
6.44 }
6.45 }
6.46 + oldExtent = extent;
6.47 hsb.setValues(value, extent, 0, max);
6.48 }
6.49
6.50 @@ -1020,7 +1020,7 @@
6.51
6.52 if (viewport != null) {
6.53 if (e.getSource() == viewport) {
6.54 - viewportStateChanged(e);
6.55 + syncScrollPaneWithViewport();
6.56 }
6.57 else {
6.58 JScrollBar hsb = scrollpane.getHorizontalScrollBar();
6.59 @@ -1077,11 +1077,6 @@
6.60 viewport.setViewPosition(p);
6.61 }
6.62
6.63 - private void viewportStateChanged(ChangeEvent e) {
6.64 - syncScrollPaneWithViewport();
6.65 - }
6.66 -
6.67 -
6.68 //
6.69 // PropertyChangeListener: This is installed on both the JScrollPane
6.70 // and the horizontal/vertical scrollbars.
7.1 --- a/src/share/classes/javax/swing/plaf/basic/DesktopIconMover.java Mon Aug 03 18:06:51 2009 -0700
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,168 +0,0 @@
7.4 -/*
7.5 - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
7.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7.7 - *
7.8 - * This code is free software; you can redistribute it and/or modify it
7.9 - * under the terms of the GNU General Public License version 2 only, as
7.10 - * published by the Free Software Foundation. Sun designates this
7.11 - * particular file as subject to the "Classpath" exception as provided
7.12 - * by Sun in the LICENSE file that accompanied this code.
7.13 - *
7.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
7.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7.17 - * version 2 for more details (a copy is included in the LICENSE file that
7.18 - * accompanied this code).
7.19 - *
7.20 - * You should have received a copy of the GNU General Public License version
7.21 - * 2 along with this work; if not, write to the Free Software Foundation,
7.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7.23 - *
7.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
7.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
7.26 - * have any questions.
7.27 - */
7.28 -
7.29 -package javax.swing.plaf.basic;
7.30 -
7.31 -import javax.swing.*;
7.32 -import java.awt.*;
7.33 -import java.awt.event.*;
7.34 -import java.beans.*;
7.35 -
7.36 -/**
7.37 - * DesktopIconMover is intended to move desktop icon
7.38 - * when parent window is resized.
7.39 - */
7.40 -class DesktopIconMover implements ComponentListener, PropertyChangeListener {
7.41 - private Component parent;
7.42 - private JInternalFrame frame; // if not null, DesktopIconMover(frame)
7.43 - // constructor was used
7.44 - private JInternalFrame.JDesktopIcon icon;
7.45 - private Rectangle parentBounds;
7.46 - private boolean componentListenerAdded = false;
7.47 -
7.48 - public DesktopIconMover(JInternalFrame frame) {
7.49 - if (frame == null) {
7.50 - throw new NullPointerException("Frame cannot be null");
7.51 - }
7.52 - this.frame = frame;
7.53 - this.icon = frame.getDesktopIcon();
7.54 - if (icon == null) {
7.55 - throw new NullPointerException(
7.56 - "frame.getDesktopIcon() cannot be null");
7.57 - }
7.58 - this.parent = frame.getParent();
7.59 - if (this.parent != null) {
7.60 - parentBounds = this.parent.getBounds();
7.61 - }
7.62 - }
7.63 -
7.64 - public DesktopIconMover(JInternalFrame.JDesktopIcon icon) {
7.65 - if (icon == null) {
7.66 - throw new NullPointerException("Icon cannot be null");
7.67 - }
7.68 - this.icon = icon;
7.69 - this.parent = icon.getParent();
7.70 - if (this.parent != null) {
7.71 - parentBounds = this.parent.getBounds();
7.72 - }
7.73 - }
7.74 -
7.75 - public void installListeners() {
7.76 - if (frame != null) {
7.77 - frame.addPropertyChangeListener(this);
7.78 - } else {
7.79 - icon.addPropertyChangeListener(this);
7.80 - }
7.81 - addComponentListener();
7.82 - }
7.83 -
7.84 - public void uninstallListeners() {
7.85 - if (frame != null) {
7.86 - frame.removePropertyChangeListener(this);
7.87 - } else {
7.88 - icon.removePropertyChangeListener(this);
7.89 - }
7.90 - removeComponentListener();
7.91 - }
7.92 -
7.93 - public void propertyChange(PropertyChangeEvent evt) {
7.94 - String propName = evt.getPropertyName();
7.95 - if ("ancestor".equals(propName)) {
7.96 - Component newAncestor = (Component) evt.getNewValue();
7.97 -
7.98 - // Remove component listener if parent is changing
7.99 - Component probablyNewParent = getCurrentParent();
7.100 - if ((probablyNewParent != null) &&
7.101 - (!probablyNewParent.equals(parent))) {
7.102 - removeComponentListener();
7.103 - parent = probablyNewParent;
7.104 - }
7.105 -
7.106 - if (newAncestor == null) {
7.107 - removeComponentListener();
7.108 - } else {
7.109 - addComponentListener();
7.110 - }
7.111 -
7.112 - // Update parentBounds
7.113 - if (parent != null) {
7.114 - parentBounds = parent.getBounds();
7.115 - } else {
7.116 - parentBounds = null;
7.117 - }
7.118 - } else if (JInternalFrame.IS_CLOSED_PROPERTY.equals(propName)) {
7.119 - removeComponentListener();
7.120 - }
7.121 - }
7.122 -
7.123 - private void addComponentListener() {
7.124 - if (!componentListenerAdded && (parent != null)) {
7.125 - parent.addComponentListener(this);
7.126 - componentListenerAdded = true;
7.127 - }
7.128 - }
7.129 -
7.130 - private void removeComponentListener() {
7.131 - if ((parent != null) && componentListenerAdded) {
7.132 - parent.removeComponentListener(this);
7.133 - componentListenerAdded = false;
7.134 - }
7.135 - }
7.136 -
7.137 - private Component getCurrentParent() {
7.138 - if (frame != null) {
7.139 - return frame.getParent();
7.140 - } else {
7.141 - return icon.getParent();
7.142 - }
7.143 - }
7.144 -
7.145 - public void componentResized(ComponentEvent e) {
7.146 - if ((parent == null) || (parentBounds == null)) {
7.147 - return;
7.148 - }
7.149 -
7.150 - Rectangle parentNewBounds = parent.getBounds();
7.151 - if ((parentNewBounds == null) || parentNewBounds.equals(parentBounds)) {
7.152 - return;
7.153 - }
7.154 -
7.155 - // Move desktop icon only in up-down direction
7.156 - int newIconY = icon.getLocation().y +
7.157 - (parentNewBounds.height - parentBounds.height);
7.158 - icon.setLocation(icon.getLocation().x, newIconY);
7.159 -
7.160 - parentBounds = parentNewBounds;
7.161 - }
7.162 -
7.163 - public void componentMoved(ComponentEvent e) {
7.164 - }
7.165 -
7.166 - public void componentShown(ComponentEvent e) {
7.167 - }
7.168 -
7.169 - public void componentHidden(ComponentEvent e) {
7.170 - }
7.171 -}
8.1 --- a/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java Mon Aug 03 18:06:51 2009 -0700
8.2 +++ b/src/share/classes/javax/swing/plaf/nimbus/AbstractRegionPainter.java Wed Aug 05 11:06:46 2009 -0700
8.3 @@ -227,10 +227,10 @@
8.4 *
8.5 * @param x an encoded x value (0...1, or 1...2, or 2...3)
8.6 * @return the decoded x value
8.7 + * @throws IllegalArgumentException
8.8 + * if {@code x < 0} or {@code x > 3}
8.9 */
8.10 protected final float decodeX(float x) {
8.11 - if (ctx.canvasSize == null) return x;
8.12 -
8.13 if (x >= 0 && x <= 1) {
8.14 return x * leftWidth;
8.15 } else if (x > 1 && x < 2) {
8.16 @@ -238,7 +238,7 @@
8.17 } else if (x >= 2 && x <= 3) {
8.18 return ((x-2) * rightWidth) + leftWidth + centerWidth;
8.19 } else {
8.20 - throw new AssertionError("Invalid x");
8.21 + throw new IllegalArgumentException("Invalid x");
8.22 }
8.23 }
8.24
8.25 @@ -248,10 +248,10 @@
8.26 *
8.27 * @param y an encoded y value (0...1, or 1...2, or 2...3)
8.28 * @return the decoded y value
8.29 + * @throws IllegalArgumentException
8.30 + * if {@code y < 0} or {@code y > 3}
8.31 */
8.32 protected final float decodeY(float y) {
8.33 - if (ctx.canvasSize == null) return y;
8.34 -
8.35 if (y >= 0 && y <= 1) {
8.36 return y * topHeight;
8.37 } else if (y > 1 && y < 2) {
8.38 @@ -259,7 +259,7 @@
8.39 } else if (y >= 2 && y <= 3) {
8.40 return ((y-2) * bottomHeight) + topHeight + centerHeight;
8.41 } else {
8.42 - throw new AssertionError("Invalid y");
8.43 + throw new IllegalArgumentException("Invalid y");
8.44 }
8.45 }
8.46
8.47 @@ -271,10 +271,10 @@
8.48 * @param x an encoded x value of the bezier control point (0...1, or 1...2, or 2...3)
8.49 * @param dx the offset distance to the anchor from the control point x
8.50 * @return the decoded x location of the control point
8.51 + * @throws IllegalArgumentException
8.52 + * if {@code x < 0} or {@code x > 3}
8.53 */
8.54 protected final float decodeAnchorX(float x, float dx) {
8.55 - if (ctx.canvasSize == null) return x + dx;
8.56 -
8.57 if (x >= 0 && x <= 1) {
8.58 return decodeX(x) + (dx * leftScale);
8.59 } else if (x > 1 && x < 2) {
8.60 @@ -282,7 +282,7 @@
8.61 } else if (x >= 2 && x <= 3) {
8.62 return decodeX(x) + (dx * rightScale);
8.63 } else {
8.64 - throw new AssertionError("Invalid x");
8.65 + throw new IllegalArgumentException("Invalid x");
8.66 }
8.67 }
8.68
8.69 @@ -294,10 +294,10 @@
8.70 * @param y an encoded y value of the bezier control point (0...1, or 1...2, or 2...3)
8.71 * @param dy the offset distance to the anchor from the control point y
8.72 * @return the decoded y position of the control point
8.73 + * @throws IllegalArgumentException
8.74 + * if {@code y < 0} or {@code y > 3}
8.75 */
8.76 protected final float decodeAnchorY(float y, float dy) {
8.77 - if (ctx.canvasSize == null) return y + dy;
8.78 -
8.79 if (y >= 0 && y <= 1) {
8.80 return decodeY(y) + (dy * topScale);
8.81 } else if (y > 1 && y < 2) {
8.82 @@ -305,7 +305,7 @@
8.83 } else if (y >= 2 && y <= 3) {
8.84 return decodeY(y) + (dy * bottomScale);
8.85 } else {
8.86 - throw new AssertionError("Invalid y");
8.87 + throw new IllegalArgumentException("Invalid y");
8.88 }
8.89 }
8.90
8.91 @@ -363,6 +363,15 @@
8.92 * @param midpoints
8.93 * @param colors
8.94 * @return a valid LinearGradientPaint. This method never returns null.
8.95 + * @throws NullPointerException
8.96 + * if {@code midpoints} array is null,
8.97 + * or {@code colors} array is null,
8.98 + * @throws IllegalArgumentException
8.99 + * if start and end points are the same points,
8.100 + * or {@code midpoints.length != colors.length},
8.101 + * or {@code colors} is less than 2 in size,
8.102 + * or a {@code midpoints} value is less than 0.0 or greater than 1.0,
8.103 + * or the {@code midpoints} are not provided in strictly increasing order
8.104 */
8.105 protected final LinearGradientPaint decodeGradient(float x1, float y1, float x2, float y2, float[] midpoints, Color[] colors) {
8.106 if (x1 == x2 && y1 == y2) {
8.107 @@ -384,6 +393,15 @@
8.108 * @param midpoints
8.109 * @param colors
8.110 * @return a valid RadialGradientPaint. This method never returns null.
8.111 + * @throws NullPointerException
8.112 + * if {@code midpoints} array is null,
8.113 + * or {@code colors} array is null
8.114 + * @throws IllegalArgumentException
8.115 + * if {@code r} is non-positive,
8.116 + * or {@code midpoints.length != colors.length},
8.117 + * or {@code colors} is less than 2 in size,
8.118 + * or a {@code midpoints} value is less than 0.0 or greater than 1.0,
8.119 + * or the {@code midpoints} are not provided in strictly increasing order
8.120 */
8.121 protected final RadialGradientPaint decodeRadialGradient(float x, float y, float r, float[] midpoints, Color[] colors) {
8.122 if (r == 0f) {
8.123 @@ -537,10 +555,10 @@
8.124 this.maxVerticalScaleFactor = maxV;
8.125
8.126 if (canvasSize != null) {
8.127 - a = insets.left;
8.128 - b = canvasSize.width - insets.right;
8.129 - c = insets.top;
8.130 - d = canvasSize.height - insets.bottom;
8.131 + a = stretchingInsets.left;
8.132 + b = canvasSize.width - stretchingInsets.right;
8.133 + c = stretchingInsets.top;
8.134 + d = canvasSize.height - stretchingInsets.bottom;
8.135 this.canvasSize = canvasSize;
8.136 this.inverted = inverted;
8.137 if (inverted) {
9.1 --- a/src/share/classes/javax/swing/plaf/nimbus/NimbusIcon.java Mon Aug 03 18:06:51 2009 -0700
9.2 +++ b/src/share/classes/javax/swing/plaf/nimbus/NimbusIcon.java Wed Aug 05 11:06:46 2009 -0700
9.3 @@ -84,6 +84,8 @@
9.4 translatex = 1;
9.5 }
9.6 }
9.7 + } else if (c instanceof JMenu) {
9.8 + flip = ! c.getComponentOrientation().isLeftToRight();
9.9 }
9.10 if (g instanceof Graphics2D){
9.11 Graphics2D gfx = (Graphics2D)g;
10.1 --- a/src/share/classes/javax/swing/text/GlyphView.java Mon Aug 03 18:06:51 2009 -0700
10.2 +++ b/src/share/classes/javax/swing/text/GlyphView.java Wed Aug 05 11:06:46 2009 -0700
10.3 @@ -719,8 +719,9 @@
10.4 checkPainter();
10.5 int p0 = getStartOffset();
10.6 int p1 = painter.getBoundedPosition(this, p0, pos, len);
10.7 - return ((p1 > p0) && (getBreakSpot(p0, p1) != BreakIterator.DONE)) ?
10.8 - View.ExcellentBreakWeight : View.BadBreakWeight;
10.9 + return p1 == p0 ? View.BadBreakWeight :
10.10 + getBreakSpot(p0, p1) != BreakIterator.DONE ?
10.11 + View.ExcellentBreakWeight : View.GoodBreakWeight;
10.12 }
10.13 return super.getBreakWeight(axis, pos, len);
10.14 }
11.1 --- a/src/share/classes/javax/swing/text/ParagraphView.java Mon Aug 03 18:06:51 2009 -0700
11.2 +++ b/src/share/classes/javax/swing/text/ParagraphView.java Wed Aug 05 11:06:46 2009 -0700
11.3 @@ -175,23 +175,6 @@
11.4 }
11.5
11.6 /**
11.7 - * Adjusts the given row if possible to fit within the
11.8 - * layout span. By default this will try to find the
11.9 - * highest break weight possible nearest the end of
11.10 - * the row. If a forced break is encountered, the
11.11 - * break will be positioned there.
11.12 - * <p>
11.13 - * This is meant for internal usage, and should not be used directly.
11.14 - *
11.15 - * @param r the row to adjust to the current layout
11.16 - * span
11.17 - * @param desiredSpan the current layout span >= 0
11.18 - * @param x the location r starts at
11.19 - */
11.20 - protected void adjustRow(Row r, int desiredSpan, int x) {
11.21 - }
11.22 -
11.23 - /**
11.24 * Returns the next visual position for the cursor, in
11.25 * either the east or west direction.
11.26 * Overridden from <code>CompositeView</code>.
12.1 --- a/src/share/classes/sun/awt/shell/ShellFolder.java Mon Aug 03 18:06:51 2009 -0700
12.2 +++ b/src/share/classes/sun/awt/shell/ShellFolder.java Wed Aug 05 11:06:46 2009 -0700
12.3 @@ -1,5 +1,5 @@
12.4 /*
12.5 - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
12.6 + * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
12.8 *
12.9 * This code is free software; you can redistribute it and/or modify it
12.10 @@ -289,8 +289,8 @@
12.11
12.12 // To avoid loads of synchronizations with Invoker and improve performance we
12.13 // synchronize the whole code of the sort method once
12.14 - getInvoker().invoke(new Callable<Void>() {
12.15 - public Void call() throws Exception {
12.16 + invoke(new Callable<Void>() {
12.17 + public Void call() {
12.18 // Check that we can use the ShellFolder.sortChildren() method:
12.19 // 1. All files have the same non-null parent
12.20 // 2. All files is ShellFolders
12.21 @@ -330,8 +330,8 @@
12.22 public void sortChildren(final List<? extends File> files) {
12.23 // To avoid loads of synchronizations with Invoker and improve performance we
12.24 // synchronize the whole code of the sort method once
12.25 - getInvoker().invoke(new Callable<Void>() {
12.26 - public Void call() throws Exception {
12.27 + invoke(new Callable<Void>() {
12.28 + public Void call() {
12.29 Collections.sort(files, FILE_COMPARATOR);
12.30
12.31 return null;
12.32 @@ -502,17 +502,61 @@
12.33 }
12.34
12.35 /**
12.36 + * Invokes the {@code task} which doesn't throw checked exceptions
12.37 + * from its {@code call} method. If invokation is interrupted then Thread.currentThread().isInterrupted() will
12.38 + * be set and result will be {@code null}
12.39 + */
12.40 + public static <T> T invoke(Callable<T> task) {
12.41 + try {
12.42 + return invoke(task, RuntimeException.class);
12.43 + } catch (InterruptedException e) {
12.44 + return null;
12.45 + }
12.46 + }
12.47 +
12.48 + /**
12.49 + * Invokes the {@code task} which throws checked exceptions from its {@code call} method.
12.50 + * If invokation is interrupted then Thread.currentThread().isInterrupted() will
12.51 + * be set and InterruptedException will be thrown as well.
12.52 + */
12.53 + public static <T, E extends Throwable> T invoke(Callable<T> task, Class<E> exceptionClass)
12.54 + throws InterruptedException, E {
12.55 + try {
12.56 + return getInvoker().invoke(task);
12.57 + } catch (Exception e) {
12.58 + if (e instanceof RuntimeException) {
12.59 + // Rethrow unchecked exceptions
12.60 + throw (RuntimeException) e;
12.61 + }
12.62 +
12.63 + if (e instanceof InterruptedException) {
12.64 + // Set isInterrupted flag for current thread
12.65 + Thread.currentThread().interrupt();
12.66 +
12.67 + // Rethrow InterruptedException
12.68 + throw (InterruptedException) e;
12.69 + }
12.70 +
12.71 + if (exceptionClass.isInstance(e)) {
12.72 + throw exceptionClass.cast(e);
12.73 + }
12.74 +
12.75 + throw new RuntimeException("Unexpected error", e);
12.76 + }
12.77 + }
12.78 +
12.79 + /**
12.80 * Interface allowing to invoke tasks in different environments on different platforms.
12.81 */
12.82 public static interface Invoker {
12.83 /**
12.84 - * Invokes a callable task. If the {@code task} throws a checked exception,
12.85 - * it will be wrapped into a {@link RuntimeException}
12.86 + * Invokes a callable task.
12.87 *
12.88 * @param task a task to invoke
12.89 + * @throws Exception {@code InterruptedException} or an exception that was thrown from the {@code task}
12.90 * @return the result of {@code task}'s invokation
12.91 */
12.92 - <T> T invoke(Callable<T> task);
12.93 + <T> T invoke(Callable<T> task) throws Exception;
12.94 }
12.95
12.96 /**
13.1 --- a/src/share/classes/sun/awt/shell/ShellFolderManager.java Mon Aug 03 18:06:51 2009 -0700
13.2 +++ b/src/share/classes/sun/awt/shell/ShellFolderManager.java Wed Aug 05 11:06:46 2009 -0700
13.3 @@ -1,5 +1,5 @@
13.4 /*
13.5 - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
13.6 + * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
13.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
13.8 *
13.9 * This code is free software; you can redistribute it and/or modify it
13.10 @@ -108,12 +108,8 @@
13.11 }
13.12
13.13 private static class DirectInvoker implements ShellFolder.Invoker {
13.14 - public <T> T invoke(Callable<T> task) {
13.15 - try {
13.16 - return task.call();
13.17 - } catch (Exception e) {
13.18 - throw new RuntimeException(e);
13.19 - }
13.20 + public <T> T invoke(Callable<T> task) throws Exception {
13.21 + return task.call();
13.22 }
13.23 }
13.24 }
14.1 --- a/src/share/classes/sun/swing/FilePane.java Mon Aug 03 18:06:51 2009 -0700
14.2 +++ b/src/share/classes/sun/swing/FilePane.java Wed Aug 05 11:06:46 2009 -0700
14.3 @@ -1,6 +1,5 @@
14.4 -
14.5 /*
14.6 - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
14.7 + * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
14.8 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14.9 *
14.10 * This code is free software; you can redistribute it and/or modify it
14.11 @@ -905,8 +904,8 @@
14.12
14.13 @Override
14.14 public void sort() {
14.15 - ShellFolder.getInvoker().invoke(new Callable<Void>() {
14.16 - public Void call() throws Exception {
14.17 + ShellFolder.invoke(new Callable<Void>() {
14.18 + public Void call() {
14.19 DetailsTableRowSorter.super.sort();
14.20 return null;
14.21 }
15.1 --- a/src/share/classes/sun/swing/MenuItemLayoutHelper.java Mon Aug 03 18:06:51 2009 -0700
15.2 +++ b/src/share/classes/sun/swing/MenuItemLayoutHelper.java Wed Aug 05 11:06:46 2009 -0700
15.3 @@ -718,10 +718,10 @@
15.4 }
15.5
15.6 private void alignRect(Rectangle rect, int alignment, int origWidth) {
15.7 - if (alignment != SwingUtilities.LEFT) {
15.8 + if (alignment == SwingConstants.RIGHT) {
15.9 rect.x = rect.x + rect.width - origWidth;
15.10 - rect.width = origWidth;
15.11 }
15.12 + rect.width = origWidth;
15.13 }
15.14
15.15 protected void layoutIconAndTextInLabelRect(LayoutResult lr) {
16.1 --- a/src/solaris/classes/sun/awt/X11/XRobotPeer.java Mon Aug 03 18:06:51 2009 -0700
16.2 +++ b/src/solaris/classes/sun/awt/X11/XRobotPeer.java Wed Aug 05 11:06:46 2009 -0700
16.3 @@ -27,6 +27,7 @@
16.4 import java.awt.*;
16.5 import java.awt.peer.*;
16.6 import sun.awt.X11GraphicsConfig;
16.7 +import sun.awt.SunToolkit;
16.8
16.9 class XRobotPeer implements RobotPeer {
16.10 private X11GraphicsConfig xgc = null;
16.11 @@ -38,7 +39,8 @@
16.12
16.13 XRobotPeer(GraphicsConfiguration gc) {
16.14 this.xgc = (X11GraphicsConfig)gc;
16.15 - setup();
16.16 + SunToolkit tk = (SunToolkit)Toolkit.getDefaultToolkit();
16.17 + setup(tk.getNumberOfButtons());
16.18 }
16.19
16.20 public void dispose() {
16.21 @@ -81,7 +83,7 @@
16.22 return pixelArray;
16.23 }
16.24
16.25 - private static native synchronized void setup();
16.26 + private static native synchronized void setup(int numberOfButtons);
16.27
16.28 private static native synchronized void mouseMoveImpl(X11GraphicsConfig xgc, int x, int y);
16.29 private static native synchronized void mousePressImpl(int buttons);
17.1 --- a/src/solaris/native/sun/awt/awt_Robot.c Mon Aug 03 18:06:51 2009 -0700
17.2 +++ b/src/solaris/native/sun/awt/awt_Robot.c Wed Aug 05 11:06:46 2009 -0700
17.3 @@ -51,9 +51,8 @@
17.4
17.5 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
17.6
17.7 -extern int32_t getNumButtons();
17.8 -
17.9 static jint * masks;
17.10 +static jint num_buttons;
17.11
17.12 static int32_t isXTestAvailable() {
17.13 int32_t major_opcode, first_event, first_error;
17.14 @@ -164,34 +163,34 @@
17.15
17.16 /*********************************************************************************************/
17.17
17.18 +// this should be called from XRobotPeer constructor
17.19 JNIEXPORT void JNICALL
17.20 -Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls) {
17.21 +Java_sun_awt_X11_XRobotPeer_setup (JNIEnv * env, jclass cls, jint numberOfButtons) {
17.22 int32_t xtestAvailable;
17.23
17.24 -// this should be called from XRobotPeer constructor
17.25 + DTRACE_PRINTLN("RobotPeer: setup()");
17.26 +
17.27 + num_buttons = numberOfButtons;
17.28 +
17.29 jclass inputEventClazz = (*env)->FindClass(env, "java/awt/event/InputEvent");
17.30 jmethodID getButtonDownMasksID = (*env)->GetStaticMethodID(env, inputEventClazz, "getButtonDownMasks", "()[I");
17.31 jintArray obj = (jintArray)(*env)->CallStaticObjectMethod(env, inputEventClazz, getButtonDownMasksID);
17.32 - jsize len = (*env)->GetArrayLength(env, obj);
17.33 jint * tmp = (*env)->GetIntArrayElements(env, obj, JNI_FALSE);
17.34
17.35 - masks = (jint *)malloc(sizeof(jint)*len);
17.36 + masks = (jint *)malloc(sizeof(jint) * num_buttons);
17.37 if (masks == (jint *) NULL) {
17.38 JNU_ThrowOutOfMemoryError((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), NULL);
17.39 goto finally;
17.40 }
17.41
17.42 int i;
17.43 - for (i = 0; i < len; i++) {
17.44 + for (i = 0; i < num_buttons; i++) {
17.45 masks[i] = tmp[i];
17.46 }
17.47 (*env)->ReleaseIntArrayElements(env, obj, tmp, 0);
17.48 (*env)->DeleteLocalRef(env, obj);
17.49
17.50 - DTRACE_PRINTLN("RobotPeer: setup()");
17.51 -
17.52 AWT_LOCK();
17.53 -
17.54 xtestAvailable = isXTestAvailable();
17.55 DTRACE_PRINTLN1("RobotPeer: XTest available = %d", xtestAvailable);
17.56 if (!xtestAvailable) {
17.57 @@ -338,8 +337,6 @@
17.58 {
17.59 AWT_LOCK();
17.60
17.61 - int32_t num_buttons = getNumButtons(); //from XToolkit.c
17.62 -
17.63 DTRACE_PRINTLN1("RobotPeer: mouseAction(%i)", buttonMask);
17.64 DTRACE_PRINTLN1("RobotPeer: mouseAction, press = %d", isMousePress);
17.65
18.1 --- a/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java Mon Aug 03 18:06:51 2009 -0700
18.2 +++ b/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java Wed Aug 05 11:06:46 2009 -0700
18.3 @@ -1,5 +1,5 @@
18.4 /*
18.5 - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
18.6 + * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
18.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
18.8 *
18.9 * This code is free software; you can redistribute it and/or modify it
18.10 @@ -29,7 +29,6 @@
18.11 import java.awt.Toolkit;
18.12 import java.awt.image.BufferedImage;
18.13 import java.io.File;
18.14 -import java.io.FileNotFoundException;
18.15 import java.io.IOException;
18.16 import java.util.*;
18.17 import java.util.concurrent.*;
18.18 @@ -185,8 +184,8 @@
18.19 boolean disposed;
18.20 public void dispose() {
18.21 if (disposed) return;
18.22 - ShellFolder.getInvoker().invoke(new Callable<Void>() {
18.23 - public Void call() throws Exception {
18.24 + invoke(new Callable<Void>() {
18.25 + public Void call() {
18.26 if (relativePIDL != 0) {
18.27 releasePIDL(relativePIDL);
18.28 }
18.29 @@ -224,7 +223,7 @@
18.30 */
18.31 private boolean isPersonal;
18.32
18.33 - private static String composePathForCsidl(int csidl) throws IOException {
18.34 + private static String composePathForCsidl(int csidl) throws IOException, InterruptedException {
18.35 String path = getFileSystemPath(csidl);
18.36 return path == null
18.37 ? ("ShellFolder: 0x" + Integer.toHexString(csidl))
18.38 @@ -235,12 +234,13 @@
18.39 * Create a system special shell folder, such as the
18.40 * desktop or Network Neighborhood.
18.41 */
18.42 - Win32ShellFolder2(final int csidl) throws IOException {
18.43 + Win32ShellFolder2(final int csidl) throws IOException, InterruptedException {
18.44 // Desktop is parent of DRIVES and NETWORK, not necessarily
18.45 // other special shell folders.
18.46 super(null, composePathForCsidl(csidl));
18.47 - ShellFolder.getInvoker().invoke(new Callable<Void>() {
18.48 - public Void call() throws Exception {
18.49 +
18.50 + invoke(new Callable<Void>() {
18.51 + public Void call() throws InterruptedException {
18.52 if (csidl == DESKTOP) {
18.53 initDesktop();
18.54 } else {
18.55 @@ -276,7 +276,7 @@
18.56 }
18.57 return null;
18.58 }
18.59 - });
18.60 + }, InterruptedException.class);
18.61
18.62 sun.java2d.Disposer.addRecord(this, disposer);
18.63 }
18.64 @@ -296,13 +296,13 @@
18.65 /**
18.66 * Creates a shell folder with a parent and relative PIDL
18.67 */
18.68 - Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) {
18.69 + Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) throws InterruptedException {
18.70 super(parent,
18.71 - ShellFolder.getInvoker().invoke(new Callable<String>() {
18.72 - public String call() throws Exception {
18.73 + invoke(new Callable<String>() {
18.74 + public String call() {
18.75 return getFileSystemPath(parent.getIShellFolder(), relativePIDL);
18.76 }
18.77 - })
18.78 + }, RuntimeException.class)
18.79 );
18.80 this.disposer.relativePIDL = relativePIDL;
18.81 getAbsolutePath();
18.82 @@ -335,8 +335,8 @@
18.83 * drive (normally "C:\").
18.84 */
18.85 protected Object writeReplace() throws java.io.ObjectStreamException {
18.86 - return ShellFolder.getInvoker().invoke(new Callable<File>() {
18.87 - public File call() throws Exception {
18.88 + return invoke(new Callable<File>() {
18.89 + public File call() {
18.90 if (isFileSystem()) {
18.91 return new File(getPath());
18.92 } else {
18.93 @@ -398,11 +398,11 @@
18.94 /**
18.95 * Accessor for IShellFolder
18.96 */
18.97 - public long getIShellFolder() {
18.98 + private long getIShellFolder() {
18.99 if (disposer.pIShellFolder == 0) {
18.100 - disposer.pIShellFolder =
18.101 - ShellFolder.getInvoker().invoke(new Callable<Long>() {
18.102 - public Long call() throws Exception {
18.103 + try {
18.104 + disposer.pIShellFolder = invoke(new Callable<Long>() {
18.105 + public Long call() {
18.106 assert(isDirectory());
18.107 assert(parent != null);
18.108 long parentIShellFolder = getParentIShellFolder();
18.109 @@ -421,7 +421,10 @@
18.110 }
18.111 return pIShellFolder;
18.112 }
18.113 - });
18.114 + }, RuntimeException.class);
18.115 + } catch (InterruptedException e) {
18.116 + // Ignore error
18.117 + }
18.118 }
18.119 return disposer.pIShellFolder;
18.120 }
18.121 @@ -505,18 +508,23 @@
18.122 }
18.123
18.124 if (parent == rhs.parent || parent.equals(rhs.parent)) {
18.125 - return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL);
18.126 + try {
18.127 + return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL);
18.128 + } catch (InterruptedException e) {
18.129 + return false;
18.130 + }
18.131 }
18.132
18.133 return false;
18.134 }
18.135
18.136 - private static boolean pidlsEqual(final long pIShellFolder, final long pidl1, final long pidl2) {
18.137 - return ShellFolder.getInvoker().invoke(new Callable<Boolean>() {
18.138 - public Boolean call() throws Exception {
18.139 - return (compareIDs(pIShellFolder, pidl1, pidl2) == 0);
18.140 + private static boolean pidlsEqual(final long pIShellFolder, final long pidl1, final long pidl2)
18.141 + throws InterruptedException {
18.142 + return invoke(new Callable<Boolean>() {
18.143 + public Boolean call() {
18.144 + return compareIDs(pIShellFolder, pidl1, pidl2) == 0;
18.145 }
18.146 - });
18.147 + }, RuntimeException.class);
18.148 }
18.149
18.150 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
18.151 @@ -539,14 +547,16 @@
18.152 * Return whether the given attribute flag is set for this object
18.153 */
18.154 public boolean hasAttribute(final int attribute) {
18.155 - return ShellFolder.getInvoker().invoke(new Callable<Boolean>() {
18.156 - public Boolean call() throws Exception {
18.157 + Boolean result = invoke(new Callable<Boolean>() {
18.158 + public Boolean call() {
18.159 // Caching at this point doesn't seem to be cost efficient
18.160 return (getAttributes0(getParentIShellFolder(),
18.161 getRelativePIDL(), attribute)
18.162 & attribute) != 0;
18.163 }
18.164 });
18.165 +
18.166 + return result != null && result;
18.167 }
18.168
18.169 /**
18.170 @@ -561,32 +571,29 @@
18.171 private static native int getAttributes0(long pParentIShellFolder, long pIDL, int attrsMask);
18.172
18.173 // Return the path to the underlying file system object
18.174 + // Should be called from the COM thread
18.175 private static String getFileSystemPath(final long parentIShellFolder, final long relativePIDL) {
18.176 - return ShellFolder.getInvoker().invoke(new Callable<String>() {
18.177 - public String call() throws Exception {
18.178 - int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER;
18.179 - if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() &&
18.180 - getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) {
18.181 + int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER;
18.182 + if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() &&
18.183 + getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) {
18.184
18.185 - String s =
18.186 - getFileSystemPath(Win32ShellFolderManager2.getDesktop().getIShellFolder(),
18.187 - getLinkLocation(parentIShellFolder, relativePIDL, false));
18.188 - if (s != null && s.startsWith("\\\\")) {
18.189 - return s;
18.190 - }
18.191 - }
18.192 - return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_FORPARSING);
18.193 + String s =
18.194 + getFileSystemPath(Win32ShellFolderManager2.getDesktop().getIShellFolder(),
18.195 + getLinkLocation(parentIShellFolder, relativePIDL, false));
18.196 + if (s != null && s.startsWith("\\\\")) {
18.197 + return s;
18.198 }
18.199 - });
18.200 + }
18.201 + return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_FORPARSING);
18.202 }
18.203
18.204 // Needs to be accessible to Win32ShellFolderManager2
18.205 - static String getFileSystemPath(final int csidl) throws IOException {
18.206 - return ShellFolder.getInvoker().invoke(new Callable<String>() {
18.207 - public String call() throws Exception {
18.208 + static String getFileSystemPath(final int csidl) throws IOException, InterruptedException {
18.209 + return invoke(new Callable<String>() {
18.210 + public String call() throws IOException {
18.211 return getFileSystemPath0(csidl);
18.212 }
18.213 - });
18.214 + }, IOException.class);
18.215 }
18.216
18.217 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
18.218 @@ -630,13 +637,14 @@
18.219 */
18.220 // Returns an IEnumIDList interface for an IShellFolder. The value
18.221 // returned must be released using releaseEnumObjects().
18.222 - private long getEnumObjects(long pIShellFolder, final boolean includeHiddenFiles) {
18.223 - final boolean isDesktop = (disposer.pIShellFolder == getDesktopIShellFolder());
18.224 - return ShellFolder.getInvoker().invoke(new Callable<Long>() {
18.225 - public Long call() throws Exception {
18.226 + private long getEnumObjects(final boolean includeHiddenFiles) throws InterruptedException {
18.227 + return invoke(new Callable<Long>() {
18.228 + public Long call() {
18.229 + boolean isDesktop = disposer.pIShellFolder == getDesktopIShellFolder();
18.230 +
18.231 return getEnumObjects(disposer.pIShellFolder, isDesktop, includeHiddenFiles);
18.232 }
18.233 - });
18.234 + }, RuntimeException.class);
18.235 }
18.236
18.237 // Returns an IEnumIDList interface for an IShellFolder. The value
18.238 @@ -670,58 +678,62 @@
18.239 security.checkRead(getPath());
18.240 }
18.241
18.242 - return ShellFolder.getInvoker().invoke(new Callable<File[]>() {
18.243 - public File[] call() throws Exception {
18.244 - if (!isDirectory()) {
18.245 - return null;
18.246 + try {
18.247 + return invoke(new Callable<File[]>() {
18.248 + public File[] call() throws InterruptedException {
18.249 + if (!isDirectory()) {
18.250 + return null;
18.251 + }
18.252 + // Links to directories are not directories and cannot be parents.
18.253 + // This does not apply to folders in My Network Places (NetHood)
18.254 + // because they are both links and real directories!
18.255 + if (isLink() && !hasAttribute(ATTRIB_FOLDER)) {
18.256 + return new File[0];
18.257 + }
18.258 +
18.259 + Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop();
18.260 + Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal();
18.261 +
18.262 + // If we are a directory, we have a parent and (at least) a
18.263 + // relative PIDL. We must first ensure we are bound to the
18.264 + // parent so we have an IShellFolder to query.
18.265 + long pIShellFolder = getIShellFolder();
18.266 + // Now we can enumerate the objects in this folder.
18.267 + ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
18.268 + long pEnumObjects = getEnumObjects(includeHiddenFiles);
18.269 + if (pEnumObjects != 0) {
18.270 + long childPIDL;
18.271 + int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
18.272 + do {
18.273 + childPIDL = getNextChild(pEnumObjects);
18.274 + boolean releasePIDL = true;
18.275 + if (childPIDL != 0 &&
18.276 + (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
18.277 + Win32ShellFolder2 childFolder;
18.278 + if (Win32ShellFolder2.this.equals(desktop)
18.279 + && personal != null
18.280 + && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
18.281 + childFolder = personal;
18.282 + } else {
18.283 + childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
18.284 + releasePIDL = false;
18.285 + }
18.286 + list.add(childFolder);
18.287 + }
18.288 + if (releasePIDL) {
18.289 + releasePIDL(childPIDL);
18.290 + }
18.291 + } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
18.292 + releaseEnumObjects(pEnumObjects);
18.293 + }
18.294 + return Thread.currentThread().isInterrupted()
18.295 + ? new File[0]
18.296 + : list.toArray(new ShellFolder[list.size()]);
18.297 }
18.298 - // Links to directories are not directories and cannot be parents.
18.299 - // This does not apply to folders in My Network Places (NetHood)
18.300 - // because they are both links and real directories!
18.301 - if (isLink() && !hasAttribute(ATTRIB_FOLDER)) {
18.302 - return new File[0];
18.303 - }
18.304 -
18.305 - Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop();
18.306 - Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal();
18.307 -
18.308 - // If we are a directory, we have a parent and (at least) a
18.309 - // relative PIDL. We must first ensure we are bound to the
18.310 - // parent so we have an IShellFolder to query.
18.311 - long pIShellFolder = getIShellFolder();
18.312 - // Now we can enumerate the objects in this folder.
18.313 - ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
18.314 - long pEnumObjects = getEnumObjects(pIShellFolder, includeHiddenFiles);
18.315 - if (pEnumObjects != 0) {
18.316 - long childPIDL;
18.317 - int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
18.318 - do {
18.319 - childPIDL = getNextChild(pEnumObjects);
18.320 - boolean releasePIDL = true;
18.321 - if (childPIDL != 0 &&
18.322 - (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
18.323 - Win32ShellFolder2 childFolder;
18.324 - if (Win32ShellFolder2.this.equals(desktop)
18.325 - && personal != null
18.326 - && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
18.327 - childFolder = personal;
18.328 - } else {
18.329 - childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
18.330 - releasePIDL = false;
18.331 - }
18.332 - list.add(childFolder);
18.333 - }
18.334 - if (releasePIDL) {
18.335 - releasePIDL(childPIDL);
18.336 - }
18.337 - } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
18.338 - releaseEnumObjects(pEnumObjects);
18.339 - }
18.340 - return Thread.currentThread().isInterrupted()
18.341 - ? new File[0]
18.342 - : list.toArray(new ShellFolder[list.size()]);
18.343 - }
18.344 - });
18.345 + }, InterruptedException.class);
18.346 + } catch (InterruptedException e) {
18.347 + return new File[0];
18.348 + }
18.349 }
18.350
18.351
18.352 @@ -730,13 +742,13 @@
18.353 *
18.354 * @return The child shellfolder, or null if not found.
18.355 */
18.356 - Win32ShellFolder2 getChildByPath(final String filePath) {
18.357 - return ShellFolder.getInvoker().invoke(new Callable<Win32ShellFolder2>() {
18.358 - public Win32ShellFolder2 call() throws Exception {
18.359 + Win32ShellFolder2 getChildByPath(final String filePath) throws InterruptedException {
18.360 + return invoke(new Callable<Win32ShellFolder2>() {
18.361 + public Win32ShellFolder2 call() throws InterruptedException {
18.362 long pIShellFolder = getIShellFolder();
18.363 - long pEnumObjects = getEnumObjects(pIShellFolder, true);
18.364 + long pEnumObjects = getEnumObjects(true);
18.365 Win32ShellFolder2 child = null;
18.366 - long childPIDL = 0;
18.367 + long childPIDL;
18.368
18.369 while ((childPIDL = getNextChild(pEnumObjects)) != 0) {
18.370 if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) {
18.371 @@ -753,7 +765,7 @@
18.372 releaseEnumObjects(pEnumObjects);
18.373 return child;
18.374 }
18.375 - });
18.376 + }, InterruptedException.class);
18.377 }
18.378
18.379 private Boolean cachedIsLink;
18.380 @@ -791,8 +803,8 @@
18.381 }
18.382
18.383 private ShellFolder getLinkLocation(final boolean resolve) {
18.384 - return ShellFolder.getInvoker().invoke(new Callable<ShellFolder>() {
18.385 - public ShellFolder call() throws Exception {
18.386 + return invoke(new Callable<ShellFolder>() {
18.387 + public ShellFolder call() {
18.388 if (!isLink()) {
18.389 return null;
18.390 }
18.391 @@ -805,6 +817,8 @@
18.392 location =
18.393 Win32ShellFolderManager2.createShellFolderFromRelativePIDL(getDesktop(),
18.394 linkLocationPIDL);
18.395 + } catch (InterruptedException e) {
18.396 + // Return null
18.397 } catch (InternalError e) {
18.398 // Could be a link to a non-bindable object, such as a network connection
18.399 // TODO: getIShellFolder() should throw FileNotFoundException instead
18.400 @@ -816,19 +830,12 @@
18.401 }
18.402
18.403 // Parse a display name into a PIDL relative to the current IShellFolder.
18.404 - long parseDisplayName(final String name) throws FileNotFoundException {
18.405 - try {
18.406 - return ShellFolder.getInvoker().invoke(new Callable<Long>() {
18.407 - public Long call() throws Exception {
18.408 - return parseDisplayName0(getIShellFolder(), name);
18.409 - }
18.410 - });
18.411 - } catch (RuntimeException e) {
18.412 - if (e.getCause() instanceof IOException) {
18.413 - throw new FileNotFoundException("Could not find file " + name);
18.414 + long parseDisplayName(final String name) throws IOException, InterruptedException {
18.415 + return invoke(new Callable<Long>() {
18.416 + public Long call() throws IOException {
18.417 + return parseDisplayName0(getIShellFolder(), name);
18.418 }
18.419 - throw e;
18.420 - }
18.421 + }, IOException.class);
18.422 }
18.423
18.424 // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
18.425 @@ -846,8 +853,8 @@
18.426 public String getDisplayName() {
18.427 if (displayName == null) {
18.428 displayName =
18.429 - ShellFolder.getInvoker().invoke(new Callable<String>() {
18.430 - public String call() throws Exception {
18.431 + invoke(new Callable<String>() {
18.432 + public String call() {
18.433 return getDisplayNameOf(getParentIShellFolder(),
18.434 getRelativePIDL(), SHGDN_NORMAL);
18.435 }
18.436 @@ -867,8 +874,8 @@
18.437 if (folderType == null) {
18.438 final long absolutePIDL = getAbsolutePIDL();
18.439 folderType =
18.440 - ShellFolder.getInvoker().invoke(new Callable<String>() {
18.441 - public String call() throws Exception {
18.442 + invoke(new Callable<String>() {
18.443 + public String call() {
18.444 return getFolderType(absolutePIDL);
18.445 }
18.446 });
18.447 @@ -926,15 +933,12 @@
18.448
18.449 public static native int[] getFileChooserBitmapBits();
18.450
18.451 + // Should be called from the COM thread
18.452 private long getIShellIcon() {
18.453 if (pIShellIcon == -1L) {
18.454 - pIShellIcon =
18.455 - ShellFolder.getInvoker().invoke(new Callable<Long>() {
18.456 - public Long call() throws Exception {
18.457 - return getIShellIcon(getIShellFolder());
18.458 - }
18.459 - });
18.460 + pIShellIcon = getIShellIcon(getIShellFolder());
18.461 }
18.462 +
18.463 return pIShellIcon;
18.464 }
18.465
18.466 @@ -988,8 +992,8 @@
18.467 Image icon = getLargeIcon ? largeIcon : smallIcon;
18.468 if (icon == null) {
18.469 icon =
18.470 - ShellFolder.getInvoker().invoke(new Callable<Image>() {
18.471 - public Image call() throws Exception {
18.472 + invoke(new Callable<Image>() {
18.473 + public Image call() {
18.474 Image newIcon = null;
18.475 if (isFileSystem()) {
18.476 long parentIShellIcon = (parent != null)
18.477 @@ -1113,8 +1117,8 @@
18.478 private static final int LVCFMT_CENTER = 2;
18.479
18.480 public ShellFolderColumnInfo[] getFolderColumns() {
18.481 - return ShellFolder.getInvoker().invoke(new Callable<ShellFolderColumnInfo[]>() {
18.482 - public ShellFolderColumnInfo[] call() throws Exception {
18.483 + return invoke(new Callable<ShellFolderColumnInfo[]>() {
18.484 + public ShellFolderColumnInfo[] call() {
18.485 ShellFolderColumnInfo[] columns = doGetColumnInfo(getIShellFolder());
18.486
18.487 if (columns != null) {
18.488 @@ -1143,8 +1147,8 @@
18.489 }
18.490
18.491 public Object getFolderColumnValue(final int column) {
18.492 - return ShellFolder.getInvoker().invoke(new Callable<Object>() {
18.493 - public Object call() throws Exception {
18.494 + return invoke(new Callable<Object>() {
18.495 + public Object call() {
18.496 return doGetColumnValue(getParentIShellFolder(), getRelativePIDL(), column);
18.497 }
18.498 });
18.499 @@ -1163,8 +1167,8 @@
18.500 public void sortChildren(final List<? extends File> files) {
18.501 // To avoid loads of synchronizations with Invoker and improve performance we
18.502 // synchronize the whole code of the sort method once
18.503 - getInvoker().invoke(new Callable<Void>() {
18.504 - public Void call() throws Exception {
18.505 + invoke(new Callable<Void>() {
18.506 + public Void call() {
18.507 Collections.sort(files, new ColumnComparator(getIShellFolder(), 0));
18.508
18.509 return null;
18.510 @@ -1184,19 +1188,21 @@
18.511
18.512 // compares 2 objects within this folder by the specified column
18.513 public int compare(final File o, final File o1) {
18.514 - return ShellFolder.getInvoker().invoke(new Callable<Integer>() {
18.515 - public Integer call() throws Exception {
18.516 + Integer result = invoke(new Callable<Integer>() {
18.517 + public Integer call() {
18.518 if (o instanceof Win32ShellFolder2
18.519 - && o1 instanceof Win32ShellFolder2) {
18.520 + && o1 instanceof Win32ShellFolder2) {
18.521 // delegates comparison to native method
18.522 return compareIDsByColumn(parentIShellFolder,
18.523 - ((Win32ShellFolder2) o).getRelativePIDL(),
18.524 - ((Win32ShellFolder2) o1).getRelativePIDL(),
18.525 - columnIdx);
18.526 + ((Win32ShellFolder2) o).getRelativePIDL(),
18.527 + ((Win32ShellFolder2) o1).getRelativePIDL(),
18.528 + columnIdx);
18.529 }
18.530 return 0;
18.531 }
18.532 });
18.533 +
18.534 + return result == null ? 0 : result;
18.535 }
18.536 }
18.537 }
19.1 --- a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Mon Aug 03 18:06:51 2009 -0700
19.2 +++ b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Wed Aug 05 11:06:46 2009 -0700
19.3 @@ -1,5 +1,5 @@
19.4 /*
19.5 - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
19.6 + * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
19.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
19.8 *
19.9 * This code is free software; you can redistribute it and/or modify it
19.10 @@ -58,10 +58,15 @@
19.11 }
19.12
19.13 public ShellFolder createShellFolder(File file) throws FileNotFoundException {
19.14 - return createShellFolder(getDesktop(), file);
19.15 + try {
19.16 + return createShellFolder(getDesktop(), file);
19.17 + } catch (InterruptedException e) {
19.18 + throw new FileNotFoundException("Execution was interrupted");
19.19 + }
19.20 }
19.21
19.22 - static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file) throws FileNotFoundException {
19.23 + static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file)
19.24 + throws FileNotFoundException, InterruptedException {
19.25 long pIDL;
19.26 try {
19.27 pIDL = parent.parseDisplayName(file.getCanonicalPath());
19.28 @@ -77,7 +82,8 @@
19.29 return folder;
19.30 }
19.31
19.32 - static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL) {
19.33 + static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL)
19.34 + throws InterruptedException {
19.35 // Walk down this relative pIDL, creating new nodes for each of the entries
19.36 while (pIDL != 0) {
19.37 long curPIDL = Win32ShellFolder2.copyFirstPIDLEntry(pIDL);
19.38 @@ -108,7 +114,9 @@
19.39 try {
19.40 desktop = new Win32ShellFolder2(DESKTOP);
19.41 } catch (IOException e) {
19.42 - desktop = null;
19.43 + // Ignore error
19.44 + } catch (InterruptedException e) {
19.45 + // Ignore error
19.46 }
19.47 }
19.48 return desktop;
19.49 @@ -119,7 +127,9 @@
19.50 try {
19.51 drives = new Win32ShellFolder2(DRIVES);
19.52 } catch (IOException e) {
19.53 - drives = null;
19.54 + // Ignore error
19.55 + } catch (InterruptedException e) {
19.56 + // Ignore error
19.57 }
19.58 }
19.59 return drives;
19.60 @@ -132,8 +142,10 @@
19.61 if (path != null) {
19.62 recent = createShellFolder(getDesktop(), new File(path));
19.63 }
19.64 + } catch (InterruptedException e) {
19.65 + // Ignore error
19.66 } catch (IOException e) {
19.67 - recent = null;
19.68 + // Ignore error
19.69 }
19.70 }
19.71 return recent;
19.72 @@ -144,7 +156,9 @@
19.73 try {
19.74 network = new Win32ShellFolder2(NETWORK);
19.75 } catch (IOException e) {
19.76 - network = null;
19.77 + // Ignore error
19.78 + } catch (InterruptedException e) {
19.79 + // Ignore error
19.80 }
19.81 }
19.82 return network;
19.83 @@ -164,8 +178,10 @@
19.84 personal.setIsPersonal();
19.85 }
19.86 }
19.87 + } catch (InterruptedException e) {
19.88 + // Ignore error
19.89 } catch (IOException e) {
19.90 - personal = null;
19.91 + // Ignore error
19.92 }
19.93 }
19.94 return personal;
19.95 @@ -267,6 +283,9 @@
19.96 }
19.97 } catch (IOException e) {
19.98 // Skip this value
19.99 + } catch (InterruptedException e) {
19.100 + // Return empty result
19.101 + return new File[0];
19.102 }
19.103 } while (value != null);
19.104
19.105 @@ -476,33 +495,39 @@
19.106 return comThread;
19.107 }
19.108
19.109 - public <T> T invoke(Callable<T> task) {
19.110 - try {
19.111 - if (Thread.currentThread() == comThread) {
19.112 - // if it's already called from the COM
19.113 - // thread, we don't need to delegate the task
19.114 - return task.call();
19.115 - } else {
19.116 - while (true) {
19.117 - Future<T> future = submit(task);
19.118 + public <T> T invoke(Callable<T> task) throws Exception {
19.119 + if (Thread.currentThread() == comThread) {
19.120 + // if it's already called from the COM
19.121 + // thread, we don't need to delegate the task
19.122 + return task.call();
19.123 + } else {
19.124 + Future<T> future;
19.125
19.126 - try {
19.127 - return future.get();
19.128 - } catch (InterruptedException e) {
19.129 - // Repeat the attempt
19.130 - future.cancel(true);
19.131 - }
19.132 + try {
19.133 + future = submit(task);
19.134 + } catch (RejectedExecutionException e) {
19.135 + throw new InterruptedException(e.getMessage());
19.136 + }
19.137 +
19.138 + try {
19.139 + return future.get();
19.140 + } catch (InterruptedException e) {
19.141 + future.cancel(true);
19.142 +
19.143 + throw e;
19.144 + } catch (ExecutionException e) {
19.145 + Throwable cause = e.getCause();
19.146 +
19.147 + if (cause instanceof Exception) {
19.148 + throw (Exception) cause;
19.149 }
19.150 +
19.151 + if (cause instanceof Error) {
19.152 + throw (Error) cause;
19.153 + }
19.154 +
19.155 + throw new RuntimeException("Unexpected error", cause);
19.156 }
19.157 - } catch (Exception e) {
19.158 - Throwable cause = (e instanceof ExecutionException) ? e.getCause() : e;
19.159 - if (cause instanceof RuntimeException) {
19.160 - throw (RuntimeException) cause;
19.161 - }
19.162 - if (cause instanceof Error) {
19.163 - throw (Error) cause;
19.164 - }
19.165 - throw new RuntimeException(cause);
19.166 }
19.167 }
19.168 }
20.1 --- a/src/windows/native/sun/windows/awt_Component.cpp Mon Aug 03 18:06:51 2009 -0700
20.2 +++ b/src/windows/native/sun/windows/awt_Component.cpp Wed Aug 05 11:06:46 2009 -0700
20.3 @@ -3739,11 +3739,12 @@
20.4
20.5 MsgRouting AwtComponent::WmImeSetContext(BOOL fSet, LPARAM *lplParam)
20.6 {
20.7 - // This message causes native status window shown even it is disabled. So don't
20.8 - // let DefWindowProc process this message if this IMC is disabled.
20.9 + // If the Windows input context is disabled, do not let Windows
20.10 + // display any UIs.
20.11 HIMC hIMC = ImmGetContext();
20.12 if (hIMC == NULL) {
20.13 - return mrConsume;
20.14 + *lplParam = 0;
20.15 + return mrDoDefault;
20.16 }
20.17
20.18 if (fSet) {
21.1 --- a/test/java/awt/EventQueue/6638195/bug6638195.java Mon Aug 03 18:06:51 2009 -0700
21.2 +++ b/test/java/awt/EventQueue/6638195/bug6638195.java Wed Aug 05 11:06:46 2009 -0700
21.3 @@ -1,5 +1,5 @@
21.4 /*
21.5 - * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
21.6 + * Copyright 2008-2009 Sun Microsystems, Inc. All Rights Reserved.
21.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
21.8 *
21.9 * This code is free software; you can redistribute it and/or modify it
21.10 @@ -23,7 +23,7 @@
21.11
21.12 /* @test
21.13 *
21.14 - * @bug 6638195
21.15 + * @bug 6638195 6844297
21.16 * @author Igor Kushnirskiy
21.17 * @summary tests if EventQueueDelegate.Delegate is invoked.
21.18 */
21.19 @@ -47,11 +47,22 @@
21.20 }
21.21
21.22 private static void runTest(MyEventQueueDelegate delegate) throws Exception {
21.23 + // We need an empty runnable here, so the next event is
21.24 + // processed with a new EventQueueDelegate. See 6844297
21.25 + // for details
21.26 EventQueue.invokeLater(
21.27 new Runnable() {
21.28 public void run() {
21.29 }
21.30 });
21.31 + // The following event is expected to be processed by
21.32 + // the EventQueueDelegate instance
21.33 + EventQueue.invokeLater(
21.34 + new Runnable() {
21.35 + public void run() {
21.36 + }
21.37 + });
21.38 + // Finally, proceed on the main thread
21.39 final CountDownLatch latch = new CountDownLatch(1);
21.40 EventQueue.invokeLater(
21.41 new Runnable() {
21.42 @@ -60,7 +71,7 @@
21.43 }
21.44 });
21.45 latch.await();
21.46 - if (! delegate.allInvoked()) {
21.47 + if (!delegate.allInvoked()) {
21.48 throw new RuntimeException("failed");
21.49 }
21.50 }
21.51 @@ -125,6 +136,7 @@
21.52
21.53 return objectMap;
21.54 }
21.55 +
21.56 static class MyEventQueueDelegate implements EventQueueDelegate.Delegate {
21.57 private volatile boolean getNextEventInvoked = false;
21.58 private volatile boolean beforeDispatchInvoked = false;
22.1 --- a/test/java/awt/Frame/FrameSize/TestFrameSize.java Mon Aug 03 18:06:51 2009 -0700
22.2 +++ b/test/java/awt/Frame/FrameSize/TestFrameSize.java Wed Aug 05 11:06:46 2009 -0700
22.3 @@ -1,5 +1,6 @@
22.4 /*
22.5 * Copyright 2009 Red Hat, Inc. All Rights Reserved.
22.6 + * Portions Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
22.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
22.8 *
22.9 * This code is free software; you can redistribute it and/or modify it
22.10 @@ -37,35 +38,62 @@
22.11 * Test fails if size of window is wrong
22.12 */
22.13
22.14 -import java.awt.Dimension;
22.15 -import java.awt.Frame;
22.16 +import java.awt.*;
22.17
22.18 public class TestFrameSize {
22.19
22.20 - static Dimension desiredDimensions = new Dimension(200, 200);
22.21 - static int ERROR_MARGIN = 15;
22.22 - static Frame mainWindow;
22.23 + static Dimension desiredDimensions = new Dimension(200, 200);
22.24 + static Frame mainWindow;
22.25
22.26 - public static void drawGui() {
22.27 - mainWindow = new Frame("");
22.28 - mainWindow.setPreferredSize(desiredDimensions);
22.29 - mainWindow.pack();
22.30 + private static Dimension getClientSize(Frame window) {
22.31 + Dimension size = window.getSize();
22.32 + Insets insets = window.getInsets();
22.33
22.34 - Dimension actualDimensions = mainWindow.getSize();
22.35 - System.out.println("Desired dimensions: " + desiredDimensions.toString());
22.36 - System.out.println("Actual dimensions: " + actualDimensions.toString());
22.37 - if (Math.abs(actualDimensions.height - desiredDimensions.height) > ERROR_MARGIN) {
22.38 - throw new RuntimeException("Incorrect widow size");
22.39 - }
22.40 + System.out.println("getClientSize() for " + window);
22.41 + System.out.println(" size: " + size);
22.42 + System.out.println(" insets: " + insets);
22.43 +
22.44 + return new Dimension(
22.45 + size.width - insets.left - insets.right,
22.46 + size.height - insets.top - insets.bottom);
22.47 + }
22.48 +
22.49 + public static void drawGui() {
22.50 + mainWindow = new Frame("");
22.51 + mainWindow.setPreferredSize(desiredDimensions);
22.52 + mainWindow.pack();
22.53 +
22.54 + Dimension actualDimensions = mainWindow.getSize();
22.55 + System.out.println("Desired dimensions: " + desiredDimensions.toString());
22.56 + System.out.println("Actual dimensions: " + actualDimensions.toString());
22.57 + if (!actualDimensions.equals(desiredDimensions)) {
22.58 + throw new RuntimeException("Incorrect widow size");
22.59 }
22.60
22.61 - public static void main(String[] args) {
22.62 - try {
22.63 - drawGui();
22.64 - } finally {
22.65 - if (mainWindow != null) {
22.66 - mainWindow.dispose();
22.67 - }
22.68 - }
22.69 + // pack() guarantees to preserve the size of the client area after
22.70 + // showing the window.
22.71 + Dimension clientSize1 = getClientSize(mainWindow);
22.72 + System.out.println("Client size before showing: " + clientSize1);
22.73 +
22.74 + mainWindow.setVisible(true);
22.75 +
22.76 + ((sun.awt.SunToolkit)Toolkit.getDefaultToolkit()).realSync();
22.77 +
22.78 + Dimension clientSize2 = getClientSize(mainWindow);
22.79 + System.out.println("Client size after showing: " + clientSize2);
22.80 +
22.81 + if (!clientSize2.equals(clientSize1)) {
22.82 + throw new RuntimeException("Incorrect client area size.");
22.83 }
22.84 + }
22.85 +
22.86 + public static void main(String[] args) {
22.87 + try {
22.88 + drawGui();
22.89 + } finally {
22.90 + if (mainWindow != null) {
22.91 + mainWindow.dispose();
22.92 + }
22.93 + }
22.94 + }
22.95 }
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/test/javax/swing/JInternalFrame/Test6505027.java Wed Aug 05 11:06:46 2009 -0700
23.3 @@ -0,0 +1,136 @@
23.4 +/*
23.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
23.7 + *
23.8 + * This code is free software; you can redistribute it and/or modify it
23.9 + * under the terms of the GNU General Public License version 2 only, as
23.10 + * published by the Free Software Foundation.
23.11 + *
23.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
23.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23.15 + * version 2 for more details (a copy is included in the LICENSE file that
23.16 + * accompanied this code).
23.17 + *
23.18 + * You should have received a copy of the GNU General Public License version
23.19 + * 2 along with this work; if not, write to the Free Software Foundation,
23.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23.21 + *
23.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
23.24 + * have any questions.
23.25 + */
23.26 +
23.27 +/*
23.28 + * @test
23.29 + * @bug 6505027
23.30 + * @summary Tests focus problem inside internal frame
23.31 + * @author Sergey Malenkov
23.32 + */
23.33 +
23.34 +import java.awt.AWTException;
23.35 +import java.awt.BorderLayout;
23.36 +import java.awt.Component;
23.37 +import java.awt.Container;
23.38 +import java.awt.KeyboardFocusManager;
23.39 +import java.awt.Point;
23.40 +import java.awt.Robot;
23.41 +import java.awt.event.InputEvent;
23.42 +import javax.swing.DefaultCellEditor;
23.43 +import javax.swing.JComboBox;
23.44 +import javax.swing.JDesktopPane;
23.45 +import javax.swing.JFrame;
23.46 +import javax.swing.JInternalFrame;
23.47 +import javax.swing.JScrollPane;
23.48 +import javax.swing.JTable;
23.49 +import javax.swing.JTextField;
23.50 +import javax.swing.SwingUtilities;
23.51 +import javax.swing.WindowConstants;
23.52 +import javax.swing.table.DefaultTableModel;
23.53 +import javax.swing.table.TableColumn;
23.54 +
23.55 +public class Test6505027 implements Runnable {
23.56 +
23.57 + private static final boolean INTERNAL = true;
23.58 + private static final boolean TERMINATE = true;
23.59 +
23.60 + private static final int WIDTH = 450;
23.61 + private static final int HEIGHT = 200;
23.62 + private static final int OFFSET = 10;
23.63 + private static final long PAUSE = 2048L;
23.64 +
23.65 + private static final String[] COLUMNS = { "Size", "Shape" }; // NON-NLS
23.66 + private static final String[] ITEMS = { "a", "b", "c", "d" }; // NON-NLS
23.67 + private static final String KEY = "terminateEditOnFocusLost"; // NON-NLS
23.68 +
23.69 + public static void main(String[] args) {
23.70 + SwingUtilities.invokeLater(new Test6505027());
23.71 +
23.72 + Component component = null;
23.73 + while (component == null) {
23.74 + try {
23.75 + Thread.sleep(PAUSE);
23.76 + }
23.77 + catch (InterruptedException exception) {
23.78 + // ignore interrupted exception
23.79 + }
23.80 + component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
23.81 + }
23.82 + if (!component.getClass().equals(JComboBox.class)) {
23.83 + throw new Error("unexpected focus owner: " + component);
23.84 + }
23.85 + SwingUtilities.getWindowAncestor(component).dispose();
23.86 + }
23.87 +
23.88 + private JTable table;
23.89 + private Point point;
23.90 +
23.91 + public void run() {
23.92 + if (this.table == null) {
23.93 + JFrame main = new JFrame();
23.94 + main.setSize(WIDTH + OFFSET * 3, HEIGHT + OFFSET * 5);
23.95 + main.setLocationRelativeTo(null);
23.96 + main.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
23.97 + main.setVisible(true);
23.98 +
23.99 + Container container = main;
23.100 + if (INTERNAL) {
23.101 + JInternalFrame frame = new JInternalFrame();
23.102 + frame.setBounds(OFFSET, OFFSET, WIDTH, HEIGHT);
23.103 + frame.setVisible(true);
23.104 +
23.105 + JDesktopPane desktop = new JDesktopPane();
23.106 + desktop.add(frame, new Integer(1));
23.107 +
23.108 + container.add(desktop);
23.109 + container = frame;
23.110 + }
23.111 + this.table = new JTable(new DefaultTableModel(COLUMNS, 2));
23.112 + if (TERMINATE) {
23.113 + this.table.putClientProperty(KEY, Boolean.TRUE);
23.114 + }
23.115 + TableColumn column = this.table.getColumn(COLUMNS[1]);
23.116 + column.setCellEditor(new DefaultCellEditor(new JComboBox(ITEMS)));
23.117 +
23.118 + container.add(BorderLayout.NORTH, new JTextField());
23.119 + container.add(BorderLayout.CENTER, new JScrollPane(this.table));
23.120 +
23.121 + SwingUtilities.invokeLater(this);
23.122 + }
23.123 + else if (this.point == null) {
23.124 + this.point = this.table.getCellRect(1, 1, false).getLocation();
23.125 + SwingUtilities.convertPointToScreen(this.point, this.table);
23.126 + SwingUtilities.invokeLater(this);
23.127 + }
23.128 + else {
23.129 + try {
23.130 + Robot robot = new Robot();
23.131 + robot.mouseMove(this.point.x + 1, this.point.y + 1);
23.132 + robot.mousePress(InputEvent.BUTTON1_MASK);
23.133 + }
23.134 + catch (AWTException exception) {
23.135 + throw new Error("unexpected exception", exception);
23.136 + }
23.137 + }
23.138 + }
23.139 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/test/javax/swing/JInternalFrame/Test6802868.java Wed Aug 05 11:06:46 2009 -0700
24.3 @@ -0,0 +1,108 @@
24.4 +/*
24.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
24.7 + *
24.8 + * This code is free software; you can redistribute it and/or modify it
24.9 + * under the terms of the GNU General Public License version 2 only, as
24.10 + * published by the Free Software Foundation.
24.11 + *
24.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
24.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24.15 + * version 2 for more details (a copy is included in the LICENSE file that
24.16 + * accompanied this code).
24.17 + *
24.18 + * You should have received a copy of the GNU General Public License version
24.19 + * 2 along with this work; if not, write to the Free Software Foundation,
24.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24.21 + *
24.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
24.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
24.24 + * have any questions.
24.25 + */
24.26 +
24.27 +/*
24.28 + * @test
24.29 + * @bug 6802868
24.30 + * @summary JInternalFrame is not maximized when maximized parent frame
24.31 + * @author Alexander Potochkin
24.32 + */
24.33 +
24.34 +import sun.awt.SunToolkit;
24.35 +
24.36 +import java.awt.Dimension;
24.37 +import java.awt.Point;
24.38 +import java.awt.Robot;
24.39 +import java.awt.Toolkit;
24.40 +import java.beans.PropertyVetoException;
24.41 +import javax.swing.JDesktopPane;
24.42 +import javax.swing.JFrame;
24.43 +import javax.swing.JInternalFrame;
24.44 +import javax.swing.SwingUtilities;
24.45 +
24.46 +public class Test6802868 {
24.47 + static JInternalFrame jif;
24.48 + static JFrame frame;
24.49 + static Dimension size;
24.50 + static Point location;
24.51 +
24.52 + public static void main(String[] args) throws Exception {
24.53 + Robot robot = new Robot();
24.54 + robot.setAutoDelay(20);
24.55 + SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
24.56 +
24.57 + SwingUtilities.invokeAndWait(new Runnable() {
24.58 + public void run() {
24.59 + frame = new JFrame();
24.60 + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
24.61 +
24.62 + JDesktopPane jdp = new JDesktopPane();
24.63 + frame.getContentPane().add(jdp);
24.64 +
24.65 + jif = new JInternalFrame("Title", true, true, true, true);
24.66 + jdp.add(jif);
24.67 + jif.setVisible(true);
24.68 +
24.69 + frame.setSize(200, 200);
24.70 + frame.setLocationRelativeTo(null);
24.71 + frame.setVisible(true);
24.72 +
24.73 + try {
24.74 + jif.setMaximum(true);
24.75 + } catch (Exception e) {
24.76 + e.printStackTrace();
24.77 + }
24.78 + }
24.79 + });
24.80 + toolkit.realSync();
24.81 + SwingUtilities.invokeAndWait(new Runnable() {
24.82 + public void run() {
24.83 + size = jif.getSize();
24.84 + frame.setSize(300, 300);
24.85 + }
24.86 + });
24.87 + toolkit.realSync();
24.88 + SwingUtilities.invokeAndWait(new Runnable() {
24.89 + public void run() {
24.90 + if (jif.getSize().equals(size)) {
24.91 + throw new RuntimeException("InternalFrame hasn't changed its size");
24.92 + }
24.93 + try {
24.94 + jif.setIcon(true);
24.95 + } catch (PropertyVetoException e) {
24.96 + e.printStackTrace();
24.97 + }
24.98 + location = jif.getDesktopIcon().getLocation();
24.99 + frame.setSize(400, 400);
24.100 + }
24.101 + });
24.102 + toolkit.realSync();
24.103 + SwingUtilities.invokeAndWait(new Runnable() {
24.104 + public void run() {
24.105 + if (jif.getDesktopIcon().getLocation().equals(location)) {
24.106 + throw new RuntimeException("JDesktopIcon hasn't moved");
24.107 + }
24.108 + }
24.109 + });
24.110 + }
24.111 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/test/javax/swing/JScrollPane/Test6526631.java Wed Aug 05 11:06:46 2009 -0700
25.3 @@ -0,0 +1,102 @@
25.4 +/*
25.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
25.7 + *
25.8 + * This code is free software; you can redistribute it and/or modify it
25.9 + * under the terms of the GNU General Public License version 2 only, as
25.10 + * published by the Free Software Foundation.
25.11 + *
25.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
25.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25.15 + * version 2 for more details (a copy is included in the LICENSE file that
25.16 + * accompanied this code).
25.17 + *
25.18 + * You should have received a copy of the GNU General Public License version
25.19 + * 2 along with this work; if not, write to the Free Software Foundation,
25.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25.21 + *
25.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
25.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
25.24 + * have any questions.
25.25 + */
25.26 +
25.27 +/*
25.28 + * @test
25.29 + * @bug 6526631
25.30 + * @summary Resizes right-oriented scroll pane
25.31 + * @author Sergey Malenkov
25.32 + * @library ..
25.33 + * @build SwingTest
25.34 + * @run main Test6526631
25.35 + */
25.36 +
25.37 +import java.awt.Dimension;
25.38 +import javax.swing.JFrame;
25.39 +import javax.swing.JScrollBar;
25.40 +import javax.swing.JScrollPane;
25.41 +import javax.swing.JTextArea;
25.42 +import javax.swing.JViewport;
25.43 +
25.44 +import static java.awt.ComponentOrientation.RIGHT_TO_LEFT;
25.45 +
25.46 +public class Test6526631 {
25.47 +
25.48 + private static final int COLS = 90;
25.49 + private static final int ROWS = 50;
25.50 + private static final int OFFSET = 10;
25.51 +
25.52 + public static void main(String[] args) {
25.53 + SwingTest.start(Test6526631.class);
25.54 + }
25.55 +
25.56 + private final JScrollPane pane;
25.57 + private final JFrame frame;
25.58 +
25.59 + public Test6526631(JFrame frame) {
25.60 + this.pane = new JScrollPane(new JTextArea(ROWS, COLS));
25.61 + this.pane.setComponentOrientation(RIGHT_TO_LEFT);
25.62 + this.frame = frame;
25.63 + this.frame.add(this.pane);
25.64 + }
25.65 +
25.66 + private void update(int offset) {
25.67 + Dimension size = this.frame.getSize();
25.68 + size.width += offset;
25.69 + this.frame.setSize(size);
25.70 + }
25.71 +
25.72 + public void validateFirst() {
25.73 + validateThird();
25.74 + update(OFFSET);
25.75 + }
25.76 +
25.77 + public void validateSecond() {
25.78 + validateThird();
25.79 + update(-OFFSET);
25.80 + }
25.81 +
25.82 + public void validateThird() {
25.83 + JViewport viewport = this.pane.getViewport();
25.84 + JScrollBar scroller = this.pane.getHorizontalScrollBar();
25.85 + if (!scroller.getComponentOrientation().equals(RIGHT_TO_LEFT)) {
25.86 + throw new IllegalStateException("unexpected component orientation");
25.87 + }
25.88 + int value = scroller.getValue();
25.89 + if (value != 0) {
25.90 + throw new IllegalStateException("unexpected scroll value");
25.91 + }
25.92 + int extent = viewport.getExtentSize().width;
25.93 + if (extent != scroller.getVisibleAmount()) {
25.94 + throw new IllegalStateException("unexpected visible amount");
25.95 + }
25.96 + int size = viewport.getViewSize().width;
25.97 + if (size != scroller.getMaximum()) {
25.98 + throw new IllegalStateException("unexpected maximum");
25.99 + }
25.100 + int pos = size - extent - value;
25.101 + if (pos != viewport.getViewPosition().x) {
25.102 + throw new IllegalStateException("unexpected position");
25.103 + }
25.104 + }
25.105 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/test/javax/swing/SwingTest.java Wed Aug 05 11:06:46 2009 -0700
26.3 @@ -0,0 +1,160 @@
26.4 +/*
26.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
26.7 + *
26.8 + * This code is free software; you can redistribute it and/or modify it
26.9 + * under the terms of the GNU General Public License version 2 only, as
26.10 + * published by the Free Software Foundation.
26.11 + *
26.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
26.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26.15 + * version 2 for more details (a copy is included in the LICENSE file that
26.16 + * accompanied this code).
26.17 + *
26.18 + * You should have received a copy of the GNU General Public License version
26.19 + * 2 along with this work; if not, write to the Free Software Foundation,
26.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26.21 + *
26.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
26.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
26.24 + * have any questions.
26.25 + */
26.26 +
26.27 +import java.io.PrintWriter;
26.28 +import java.lang.reflect.InvocationTargetException;
26.29 +import java.lang.reflect.Method;
26.30 +import java.lang.reflect.Modifier;
26.31 +import java.util.Comparator;
26.32 +import java.util.Iterator;
26.33 +import java.util.Set;
26.34 +import java.util.TreeSet;
26.35 +import javax.swing.JFrame;
26.36 +
26.37 +import static javax.swing.SwingUtilities.invokeLater;
26.38 +
26.39 +/**
26.40 + * SwingTestHelper is a utility class for writing regression tests
26.41 + * that require interacting with the UI.
26.42 + *
26.43 + * @author Sergey A. Malenkov
26.44 + */
26.45 +final class SwingTest implements Runnable {
26.46 +
26.47 + private static final int WIDTH = 640;
26.48 + private static final int HEIGHT = 480;
26.49 +
26.50 + public static void start(Class<?> type) {
26.51 + new SwingTest(type).start();
26.52 + }
26.53 +
26.54 + private final PrintWriter writer = new PrintWriter(System.out, true);
26.55 +
26.56 + private Class<?> type;
26.57 + private JFrame frame;
26.58 + private Iterator<Method> methods;
26.59 + private Object object;
26.60 + private Method method;
26.61 + private Throwable error;
26.62 +
26.63 + private SwingTest(Class<?> type) {
26.64 + this.type = type;
26.65 + }
26.66 +
26.67 + public void run() {
26.68 + synchronized (this.writer) {
26.69 + if (this.error != null) {
26.70 + this.frame.dispose();
26.71 + this.frame = null;
26.72 + }
26.73 + else if (this.object == null) {
26.74 + invoke();
26.75 + Set<Method> methods = new TreeSet<Method>(new Comparator<Method>() {
26.76 + public int compare(Method first, Method second) {
26.77 + return first.getName().compareTo(second.getName());
26.78 + }
26.79 + });
26.80 + for (Method method : this.type.getMethods()) {
26.81 + if (method.getDeclaringClass().equals(this.type)) {
26.82 + if (method.getReturnType().equals(void.class)) {
26.83 + if (0 == method.getParameterTypes().length) {
26.84 + methods.add(method);
26.85 + }
26.86 + }
26.87 + }
26.88 + }
26.89 + this.methods = methods.iterator();
26.90 + }
26.91 + else if (this.method != null) {
26.92 + invoke();
26.93 + }
26.94 + else if (this.methods.hasNext()) {
26.95 + this.method = this.methods.next();
26.96 + }
26.97 + else {
26.98 + this.frame.dispose();
26.99 + this.frame = null;
26.100 + this.type = null;
26.101 + }
26.102 + this.writer.notifyAll();
26.103 + }
26.104 + }
26.105 +
26.106 + private void start() {
26.107 + synchronized (this.writer) {
26.108 + while (this.type != null) {
26.109 + if ((this.method != null) && Modifier.isStatic(this.method.getModifiers())) {
26.110 + invoke();
26.111 + }
26.112 + else {
26.113 + invokeLater(this);
26.114 + try {
26.115 + this.writer.wait();
26.116 + }
26.117 + catch (InterruptedException exception) {
26.118 + exception.printStackTrace(this.writer);
26.119 + }
26.120 + }
26.121 + if ((this.frame == null) && (this.error != null)) {
26.122 + throw new Error("unexpected error", this.error);
26.123 + }
26.124 + }
26.125 + }
26.126 + }
26.127 +
26.128 + private void invoke() {
26.129 + try {
26.130 + if (this.method != null) {
26.131 + this.writer.println(this.method);
26.132 + this.method.invoke(this.object);
26.133 + this.method = null;
26.134 + }
26.135 + else {
26.136 + this.writer.println(this.type);
26.137 + this.frame = new JFrame(this.type.getSimpleName());
26.138 + this.frame.setSize(WIDTH, HEIGHT);
26.139 + this.frame.setLocationRelativeTo(null);
26.140 + this.object = this.type.getConstructor(JFrame.class).newInstance(this.frame);
26.141 + this.frame.setVisible(true);
26.142 + }
26.143 + }
26.144 + catch (NoSuchMethodException exception) {
26.145 + this.error = exception;
26.146 + }
26.147 + catch (SecurityException exception) {
26.148 + this.error = exception;
26.149 + }
26.150 + catch (IllegalAccessException exception) {
26.151 + this.error = exception;
26.152 + }
26.153 + catch (IllegalArgumentException exception) {
26.154 + this.error = exception;
26.155 + }
26.156 + catch (InstantiationException exception) {
26.157 + this.error = exception;
26.158 + }
26.159 + catch (InvocationTargetException exception) {
26.160 + this.error = exception.getTargetException();
26.161 + }
26.162 + }
26.163 +}