mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-24 04:54:40 +02:00
6840086: JFileChooser lacks icons on top right when running on Windows 7
Reviewed-by: peterz, uta
This commit is contained in:
parent
c6abcd3327
commit
c47e47b64a
5 changed files with 142 additions and 137 deletions
|
@ -57,8 +57,9 @@ class ShellFolderManager {
|
|||
* folders, such as Desktop, Documents, History, Network, Home, etc.
|
||||
* This is used in the shortcut panel of the filechooser on Windows 2000
|
||||
* and Windows Me.
|
||||
* "fileChooserIcon nn":
|
||||
* Returns an <code>Image</code> - icon nn from resource 124 in comctl32.dll (Windows only).
|
||||
* "fileChooserIcon <icon>":
|
||||
* Returns an <code>Image</code> - icon can be ListView, DetailsView, UpFolder, NewFolder or
|
||||
* ViewMenu (Windows only).
|
||||
*
|
||||
* @return An Object matching the key string.
|
||||
*/
|
||||
|
|
|
@ -922,7 +922,7 @@ final class Win32ShellFolder2 extends ShellFolder {
|
|||
// Dispose the HICON
|
||||
private static native void disposeIcon(long hIcon);
|
||||
|
||||
public static native int[] getFileChooserBitmapBits();
|
||||
static native int[] getStandardViewButton0(int iconIndex);
|
||||
|
||||
// Should be called from the COM thread
|
||||
private long getIShellIcon() {
|
||||
|
@ -933,34 +933,6 @@ final class Win32ShellFolder2 extends ShellFolder {
|
|||
return pIShellIcon;
|
||||
}
|
||||
|
||||
|
||||
static int[] fileChooserBitmapBits = null;
|
||||
static Image[] fileChooserIcons = new Image[47];
|
||||
|
||||
static Image getFileChooserIcon(int i) {
|
||||
if (fileChooserIcons[i] != null) {
|
||||
return fileChooserIcons[i];
|
||||
} else {
|
||||
if (fileChooserBitmapBits == null) {
|
||||
fileChooserBitmapBits = getFileChooserBitmapBits();
|
||||
}
|
||||
if (fileChooserBitmapBits != null) {
|
||||
int nImages = fileChooserBitmapBits.length / (16*16);
|
||||
int[] bitmapBits = new int[16 * 16];
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
bitmapBits[y * 16 + x] = fileChooserBitmapBits[y * (nImages * 16) + (i * 16) + x];
|
||||
}
|
||||
}
|
||||
BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
|
||||
img.setRGB(0, 0, 16, 16, bitmapBits, 0, 16);
|
||||
fileChooserIcons[i] = img;
|
||||
}
|
||||
}
|
||||
return fileChooserIcons[i];
|
||||
}
|
||||
|
||||
|
||||
private static Image makeIcon(long hIcon, boolean getLargeIcon) {
|
||||
if (hIcon != 0L && hIcon != -1L) {
|
||||
// Get the bits. This has the side effect of setting the imageHash value for this object.
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
|
||||
package sun.awt.shell;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -33,6 +34,7 @@ import java.io.IOException;
|
|||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import sun.security.action.LoadLibraryAction;
|
||||
|
@ -98,6 +100,29 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
|
|||
return parent;
|
||||
}
|
||||
|
||||
private static final int VIEW_LIST = 2;
|
||||
private static final int VIEW_DETAILS = 3;
|
||||
private static final int VIEW_PARENTFOLDER = 8;
|
||||
private static final int VIEW_NEWFOLDER = 11;
|
||||
|
||||
private static final Image[] STANDARD_VIEW_BUTTONS = new Image[12];
|
||||
|
||||
private static Image getStandardViewButton(int iconIndex) {
|
||||
Image result = STANDARD_VIEW_BUTTONS[iconIndex];
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
img.setRGB(0, 0, 16, 16, Win32ShellFolder2.getStandardViewButton0(iconIndex), 0, 16);
|
||||
|
||||
STANDARD_VIEW_BUTTONS[iconIndex] = img;
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
// Special folders
|
||||
private static Win32ShellFolder2 desktop;
|
||||
private static Win32ShellFolder2 drives;
|
||||
|
@ -105,12 +130,6 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
|
|||
private static Win32ShellFolder2 network;
|
||||
private static Win32ShellFolder2 personal;
|
||||
|
||||
private static final boolean USE_SHELL32_ICONS = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
public Boolean run() {
|
||||
return OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_XP) >= 0;
|
||||
}
|
||||
});
|
||||
|
||||
static Win32ShellFolder2 getDesktop() {
|
||||
if (desktop == null) {
|
||||
try {
|
||||
|
@ -206,9 +225,9 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
|
|||
* folders, such as Desktop, Documents, History, Network, Home, etc.
|
||||
* This is used in the shortcut panel of the filechooser on Windows 2000
|
||||
* and Windows Me.
|
||||
* "fileChooserIcon nn":
|
||||
* Returns an <code>Image</code> - icon nn from resource 216 in shell32.dll,
|
||||
* or if not found there from resource 124 in comctl32.dll (Windows only).
|
||||
* "fileChooserIcon <icon>":
|
||||
* Returns an <code>Image</code> - icon can be ListView, DetailsView, UpFolder, NewFolder or
|
||||
* ViewMenu (Windows only).
|
||||
* "optionPaneIcon iconName":
|
||||
* Returns an <code>Image</code> - icon from the system icon list
|
||||
*
|
||||
|
@ -303,26 +322,23 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
|
|||
}
|
||||
return folders.toArray(new File[folders.size()]);
|
||||
} else if (key.startsWith("fileChooserIcon ")) {
|
||||
int i = -1;
|
||||
String name = key.substring(key.indexOf(" ")+1);
|
||||
try {
|
||||
i = Integer.parseInt(name);
|
||||
} catch (NumberFormatException ex) {
|
||||
if (name.equals("ListView")) {
|
||||
i = (USE_SHELL32_ICONS) ? 21 : 2;
|
||||
String name = key.substring(key.indexOf(" ") + 1);
|
||||
|
||||
int iconIndex;
|
||||
|
||||
if (name.equals("ListView") || name.equals("ViewMenu")) {
|
||||
iconIndex = VIEW_LIST;
|
||||
} else if (name.equals("DetailsView")) {
|
||||
i = (USE_SHELL32_ICONS) ? 23 : 3;
|
||||
iconIndex = VIEW_DETAILS;
|
||||
} else if (name.equals("UpFolder")) {
|
||||
i = (USE_SHELL32_ICONS) ? 28 : 8;
|
||||
iconIndex = VIEW_PARENTFOLDER;
|
||||
} else if (name.equals("NewFolder")) {
|
||||
i = (USE_SHELL32_ICONS) ? 31 : 11;
|
||||
} else if (name.equals("ViewMenu")) {
|
||||
i = (USE_SHELL32_ICONS) ? 21 : 2;
|
||||
}
|
||||
}
|
||||
if (i >= 0) {
|
||||
return Win32ShellFolder2.getFileChooserIcon(i);
|
||||
iconIndex = VIEW_NEWFOLDER;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getStandardViewButton(iconIndex);
|
||||
} else if (key.startsWith("optionPaneIcon ")) {
|
||||
Win32ShellFolder2.SystemIcon iconType;
|
||||
if (key == "optionPaneIcon Error") {
|
||||
|
|
|
@ -256,7 +256,6 @@ JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolderManager2_uninitializeC
|
|||
static IShellIcon* getIShellIcon(IShellFolder* pIShellFolder) {
|
||||
// http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp
|
||||
HRESULT hres;
|
||||
HICON hIcon = NULL;
|
||||
IShellIcon* pIShellIcon;
|
||||
if (pIShellFolder != NULL) {
|
||||
hres = pIShellFolder->QueryInterface(IID_IShellIcon, (void**)&pIShellIcon);
|
||||
|
@ -965,89 +964,40 @@ JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits
|
|||
|
||||
/*
|
||||
* Class: sun_awt_shell_Win32ShellFolder2
|
||||
* Method: getFileChooserBitmapBits
|
||||
* Signature: ()[I
|
||||
* Method: getStandardViewButton0
|
||||
* Signature: (I)[I
|
||||
*/
|
||||
JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFileChooserBitmapBits
|
||||
(JNIEnv* env, jclass cls)
|
||||
JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getStandardViewButton0
|
||||
(JNIEnv* env, jclass cls, jint iconIndex)
|
||||
{
|
||||
HBITMAP hBitmap = NULL;
|
||||
BITMAP bm;
|
||||
HINSTANCE libComCtl32;
|
||||
HINSTANCE libShell32;
|
||||
jintArray result = NULL;
|
||||
|
||||
libShell32 = LoadLibrary(TEXT("shell32.dll"));
|
||||
if (libShell32 != NULL) {
|
||||
hBitmap = (HBITMAP)LoadImage(libShell32,
|
||||
IS_WINVISTA ? TEXT("IDB_TB_SH_DEF_16") : MAKEINTRESOURCE(216),
|
||||
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
|
||||
// Create a toolbar
|
||||
HWND hWndToolbar = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
|
||||
0, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL);
|
||||
|
||||
if (hBitmap == NULL) {
|
||||
// version of shell32.dll doesn't match OS version.
|
||||
// So we either are in a Vista Compatibility Mode
|
||||
// or shell32.dll was copied from OS of another version
|
||||
hBitmap = (HBITMAP)LoadImage(libShell32,
|
||||
IS_WINVISTA ? MAKEINTRESOURCE(216) : TEXT("IDB_TB_SH_DEF_16"),
|
||||
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
|
||||
}
|
||||
}
|
||||
if (hBitmap == NULL) {
|
||||
libComCtl32 = LoadLibrary(TEXT("comctl32.dll"));
|
||||
if (libComCtl32 != NULL) {
|
||||
hBitmap = (HBITMAP)LoadImage(libComCtl32, MAKEINTRESOURCE(124),
|
||||
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
|
||||
}
|
||||
}
|
||||
if (hBitmap == NULL) {
|
||||
return NULL;
|
||||
if (hWndToolbar != NULL) {
|
||||
SendMessage(hWndToolbar, TB_LOADIMAGES, (WPARAM)IDB_VIEW_SMALL_COLOR, (LPARAM)HINST_COMMCTRL);
|
||||
|
||||
HIMAGELIST hImageList = (HIMAGELIST) SendMessage(hWndToolbar, TB_GETIMAGELIST, 0, 0);
|
||||
|
||||
if (hImageList != NULL) {
|
||||
HICON hIcon = ImageList_GetIcon(hImageList, iconIndex, ILD_TRANSPARENT);
|
||||
|
||||
if (hIcon != NULL) {
|
||||
result = Java_sun_awt_shell_Win32ShellFolder2_getIconBits(env, cls, ptr_to_jlong(hIcon), 16);
|
||||
|
||||
DestroyIcon(hIcon);
|
||||
}
|
||||
|
||||
GetObject(hBitmap, sizeof(bm), (LPSTR)&bm);
|
||||
|
||||
// Get the screen DC
|
||||
HDC dc = GetDC(NULL);
|
||||
if (dc == NULL) {
|
||||
return NULL;
|
||||
ImageList_Destroy(hImageList);
|
||||
}
|
||||
|
||||
// Set up BITMAPINFO
|
||||
BITMAPINFO bmi;
|
||||
memset(&bmi, 0, sizeof(BITMAPINFO));
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi.bmiHeader.biWidth = bm.bmWidth;
|
||||
bmi.bmiHeader.biHeight = -bm.bmHeight;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
// Extract the color bitmap
|
||||
int numPixels = bm.bmWidth * bm.bmHeight;
|
||||
//long colorBits[192 * 16];
|
||||
long *colorBits = (long*)safe_Malloc(numPixels * sizeof(long));
|
||||
if (GetDIBits(dc, hBitmap, 0, bm.bmHeight, colorBits, &bmi, DIB_RGB_COLORS) == 0) {
|
||||
return NULL;
|
||||
DestroyWindow(hWndToolbar);
|
||||
}
|
||||
|
||||
// Release DC
|
||||
ReleaseDC(NULL, dc);
|
||||
|
||||
// The color of the first pixel defines the transparency, according
|
||||
// to the documentation for LR_LOADTRANSPARENT at
|
||||
// http://msdn.microsoft.com/library/psdk/winui/resource_9fhi.htm
|
||||
long transparent = colorBits[0];
|
||||
for (int i=0; i < numPixels; i++) {
|
||||
if (colorBits[i] != transparent) {
|
||||
colorBits[i] |= 0xff000000;
|
||||
}
|
||||
}
|
||||
|
||||
// Create java array
|
||||
jintArray bits = env->NewIntArray(numPixels);
|
||||
// Copy values to java array
|
||||
env->SetIntArrayRegion(bits, 0, numPixels, colorBits);
|
||||
// Fix 4745575 GDI Resource Leak
|
||||
::DeleteObject(hBitmap);
|
||||
::FreeLibrary(libComCtl32);
|
||||
return bits;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
66
jdk/test/javax/swing/JFileChooser/6840086/bug6840086.java
Normal file
66
jdk/test/javax/swing/JFileChooser/6840086/bug6840086.java
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 6840086
|
||||
@summary JFileChooser lacks icons on top right when running on Windows 7
|
||||
@author Pavel Porvatov
|
||||
@run main bug6840086
|
||||
*/
|
||||
|
||||
import sun.awt.OSInfo;
|
||||
import sun.awt.shell.ShellFolder;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class bug6840086 {
|
||||
private static final String[] KEYS = {
|
||||
"fileChooserIcon ListView",
|
||||
"fileChooserIcon ViewMenu",
|
||||
"fileChooserIcon DetailsView",
|
||||
"fileChooserIcon UpFolder",
|
||||
"fileChooserIcon NewFolder",
|
||||
};
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (OSInfo.getOSType() != OSInfo.OSType.WINDOWS) {
|
||||
System.out.println("The test was skipped because it is sensible only for Windows.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (String key : KEYS) {
|
||||
Image image = (Image) ShellFolder.get(key);
|
||||
|
||||
if (image == null) {
|
||||
throw new RuntimeException("The image '" + key + "' not found.");
|
||||
}
|
||||
|
||||
if (image != ShellFolder.get(key)) {
|
||||
throw new RuntimeException("The image '" + key + "' is not cached.");
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("The test passed.");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue