diff -r 78537b37b7de make/sun/xawt/FILES_c_unix.gmk --- a/make/sun/xawt/FILES_c_unix.gmk Fri Apr 30 17:03:15 2010 -0700 +++ b/make/sun/xawt/FILES_c_unix.gmk Tue May 18 23:44:14 2010 +0200 @@ -80,4 +80,5 @@ swing_GTKEngine.c \ swing_GTKStyle.c \ rect.c \ - sun_awt_X11_GtkFileDialogPeer.c + sun_awt_X11_GtkFileDialogPeer.c \ + sun_awt_X11_GtkDirectoryDialogPeer.c diff -r 78537b37b7de make/sun/xawt/FILES_export_unix.gmk --- a/make/sun/xawt/FILES_export_unix.gmk Fri Apr 30 17:03:15 2010 -0700 +++ b/make/sun/xawt/FILES_export_unix.gmk Tue May 18 23:44:14 2010 +0200 @@ -34,4 +34,5 @@ sun/awt/X11/XToolkit.java \ sun/awt/X11/XComponentPeer.java \ sun/awt/X11/XInputMethod.java \ - sun/awt/X11/GtkFileDialogPeer.java + sun/awt/X11/GtkFileDialogPeer.java \ + sun/awt/X11/GtkDirectoryDialogPeer.java diff -r 78537b37b7de make/sun/xawt/mapfile-vers --- a/make/sun/xawt/mapfile-vers Fri Apr 30 17:03:15 2010 -0700 +++ b/make/sun/xawt/mapfile-vers Tue May 18 23:44:14 2010 +0200 @@ -398,7 +398,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName; Java_sun_awt_X11_GtkFileDialogPeer_run; - Java_sun_awt_X11_GtkFileDialogPeer_quit; + Java_sun_awt_X11_GtkFileDialogPeer_quit; + Java_sun_awt_X11_GtkDirectoryDialogPeer_run; + Java_sun_awt_X11_GtkDirectoryDialogPeer_quit; Java_sun_print_CUPSPrinter_initIDs; Java_sun_print_CUPSPrinter_getCupsServer; diff -r 78537b37b7de src/share/classes/java/awt/DirectoryDialog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/awt/DirectoryDialog.java Tue May 18 23:44:14 2010 +0200 @@ -0,0 +1,202 @@ +/* + * Copyright 2010 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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. + */ +package java.awt; + +import java.awt.peer.*; +import java.io.IOException; +import java.io.ObjectInputStream; +import sun.awt.AWTAccessor; + +/** + * The DirectoryDialog class displays a dialog window from which + * the user can select a directory. + *

+ * It is a modal dialog, that blocks the rest of the application until the user + * has chosen a file. + *

+ * + * @author Costantino Cerbo (c.cerbo@gmail.com) + * @since 1.7 + */ +public class DirectoryDialog extends Dialog { + + static { + AWTAccessor + .setDirectoryDialogAccessor(new AWTAccessor.DirectoryDialogAccessor() { + + public void setDirectory(DirectoryDialog directoryDialog, + String directory) { + directoryDialog.dir = ("".equals(directory)) ? null + : directory; + } + }); + } + + static { + /* ensure that the necessary native libraries are loaded */ + Toolkit.loadLibraries(); + GraphicsEnvironment.isHeadless(); + } + /* + * The string specifying the directory to display in the file dialog. This + * variable may be null. + * + * @serial + * + * @see getDirectory() + * + * @see setDirectory() + */ + private String dir; + + /** + * Creates a dialog for selecting a directory. The title of the file dialog + * is initially empty. + * + * @param parent + * the owner of the dialog + * @since 1.7 + */ + public DirectoryDialog(Frame parent) { + super(parent, true); + } + + /** + * Creates a dialog for selecting a directory. + * + * @param parent + * the owner of the dialog + * @param title + * the title of the dialog + * @since 1.7 + */ + public DirectoryDialog(Frame parent, String title) { + super(parent, title, true); + } + + /** + * Creates a dialog for selecting a directory. The title of the file dialog + * is initially empty. + * + * @param parent + * the owner of the dialog + * @since 1.7 + */ + public DirectoryDialog(Dialog parent) { + super(parent, "", true); + } + + /** + * Creates a dialog for selecting a directory. + * + * @param parent + * the owner of the dialog + * @param title + * the title of the dialog + * @since 1.7 + */ + public DirectoryDialog(Dialog parent, String title) { + super(parent, title, true); + } + + /** + * Gets the directory of this file dialog. + * + * @return the (potentially null or invalid) directory of this + * FileDialog + * @see java.awt.FileDialog#setDirectory + */ + public String getDirectory() { + return dir; + } + + /** + * Sets the directory of this file dialog window to be the specified + * directory. Specifying a null or an invalid directory implies + * an implementation-defined default. This default will not be realized, + * however, until the user has selected a file. Until this point, + * getDirectory() will return the value passed into this + * method. + *

+ * Specifying "" as the directory is exactly equivalent to specifying + * null as the directory. + * + * @param dir + * the specified directory + * @see java.awt.DirectoryDialog#getDirectory + */ + public void setDirectory(String dir) { + this.dir = (dir != null && dir.equals("")) ? null : dir; + if (peer != null) { + ((DirectoryDialogPeer) this.peer).setDirectory(this.dir); + } + } + + /** + * Creates the file dialog's peer. The peer allows us to change the look of + * the file dialog without changing its functionality. + */ + @Override + public void addNotify() { + synchronized (getTreeLock()) { + if (parent != null && parent.getPeer() == null) { + parent.addNotify(); + } + if (peer == null) { + peer = getToolkit().createDirectoryDialog(this); + } + super.addNotify(); + } + } + + /** + * Returns a string representing the state of this FileDialog + * window. This method is intended to be used only for debugging purposes, + * and the content and format of the returned string may vary between + * implementations. The returned string may be empty but may not be + * null. + * + * @return the parameter string of this file dialog window + */ + @Override + protected String paramString() { + String str = super.paramString(); + str += ",dir= " + dir; + return str; + } + + /** + * Reads the ObjectInputStream and performs a backwards + * compatibility check by converting either a dir or a + * file equal to an empty string to null. + * + * @param s + * the ObjectInputStream to read + */ + private void readObject(ObjectInputStream s) throws ClassNotFoundException, + IOException { + s.defaultReadObject(); + } +} diff -r 78537b37b7de src/share/classes/java/awt/Toolkit.java --- a/src/share/classes/java/awt/Toolkit.java Fri Apr 30 17:03:15 2010 -0700 +++ b/src/share/classes/java/awt/Toolkit.java Tue May 18 23:44:14 2010 +0200 @@ -392,6 +392,20 @@ */ protected abstract FileDialogPeer createFileDialog(FileDialog target) throws HeadlessException; + + /** + * Creates this toolkit's implementation of DirectoryDialog using + * the specified peer interface. + * @param target the directory dialog to be implemented. + * @return this toolkit's implementation of DirectoryDialog. + * @exception HeadlessException if GraphicsEnvironment.isHeadless() + * returns true + * @see java.awt.GraphicsEnvironment#isHeadless + * @see java.awt.DirectoryDialog + * @see java.awt.peer.DirectoryDialogPeer + */ + protected abstract DirectoryDialogPeer createDirectoryDialog(DirectoryDialog target) + throws HeadlessException; /** * Creates this toolkit's implementation of CheckboxMenuItem using diff -r 78537b37b7de src/share/classes/java/awt/peer/DirectoryDialogPeer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/java/awt/peer/DirectoryDialogPeer.java Tue May 18 23:44:14 2010 +0200 @@ -0,0 +1,50 @@ +/* + * Copyright 2010 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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. + */ + +package java.awt.peer; + +/** + * The peer interface for {@link DirectoryDialog}. + * + * The peer interfaces are intended only for use in porting the AWT. They are + * not intended for use by application developers, and developers should not + * implement peers nor invoke any of the peer methods directly on the peer + * instances. + * + * @author Costantino Cerbo (c.cerbo@gmail.com) + */ +public interface DirectoryDialogPeer extends DialogPeer { + + /** + * Sets the current directory for this dialog. + * + * @param dir + * the directory to set + * + * @see DirectoryDialog#setDirectory(String) + */ + public void setDirectory(String dir); + +} diff -r 78537b37b7de src/share/classes/sun/awt/AWTAccessor.java --- a/src/share/classes/sun/awt/AWTAccessor.java Fri Apr 30 17:03:15 2010 -0700 +++ b/src/share/classes/sun/awt/AWTAccessor.java Tue May 18 23:44:14 2010 +0200 @@ -414,7 +414,17 @@ */ boolean isMultipleMode(FileDialog fileDialog); } - + + /* + * An accessor for the DirectoryDialog class + */ + public interface DirectoryDialogAccessor { + /* + * Sets the directory the user selects + */ + void setDirectory(DirectoryDialog fileDialog, String directory); + } + /* * The java.awt.Component class accessor object. */ @@ -459,6 +469,11 @@ * The java.awt.FileDialog class accessor object. */ private static FileDialogAccessor fileDialogAccessor; + + /* + * The java.awt.DirectoryDialog class accessor object. + */ + private static DirectoryDialogAccessor directoryDialogAccessor; /* * Set an accessor object for the java.awt.Component class. @@ -614,4 +629,20 @@ return fileDialogAccessor; } + /* + * Set an accessor object for the java.awt.DirectoryDialog class. + */ + public static void setDirectoryDialogAccessor(DirectoryDialogAccessor dda) { + directoryDialogAccessor = dda; + } + + /* + * Retrieve the accessor object for the java.awt.DirectoryDialog class. + */ + public static DirectoryDialogAccessor getDirectoryDialogAccessor() { + if (directoryDialogAccessor == null) { + unsafe.ensureClassInitialized(DirectoryDialog.class); + } + return directoryDialogAccessor; + } } diff -r 78537b37b7de src/share/classes/sun/awt/HeadlessToolkit.java --- a/src/share/classes/sun/awt/HeadlessToolkit.java Fri Apr 30 17:03:15 2010 -0700 +++ b/src/share/classes/sun/awt/HeadlessToolkit.java Tue May 18 23:44:14 2010 +0200 @@ -143,6 +143,11 @@ throw new HeadlessException(); } + public DirectoryDialogPeer createDirectoryDialog(DirectoryDialog target) + throws HeadlessException { + throw new HeadlessException(); + } + public MenuBarPeer createMenuBar(MenuBar target) throws HeadlessException { throw new HeadlessException(); diff -r 78537b37b7de src/solaris/classes/sun/awt/X11/GtkDirectoryDialogPeer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/solaris/classes/sun/awt/X11/GtkDirectoryDialogPeer.java Tue May 18 23:44:14 2010 +0200 @@ -0,0 +1,91 @@ +/* + * Copyright 2010 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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. + */ +package sun.awt.X11; + +import java.awt.*; +import java.awt.peer.*; +import sun.awt.AWTAccessor; + +/** + * DirectoryDialogPeer for the GtkFileChooser. + * + * @author Costantino Cerbo (c.cerbo@gmail.com) + */ +class GtkDirectoryDialogPeer extends XDialogPeer implements DirectoryDialogPeer { + + private DirectoryDialog dd; + + GtkDirectoryDialogPeer(DirectoryDialog target) { + super((Dialog) target); + this.dd = target; + } + + private native void run(String title, String dir); + + private native void quit(); + + /** + * Called exclusively by the native C code. + */ + private void setDirectoryInternal(String directory) { + AWTAccessor.DirectoryDialogAccessor accessor = AWTAccessor + .getDirectoryDialogAccessor(); + accessor.setDirectory(dd, directory); + } + + @Override + public void setVisible(boolean b) { + XToolkit.awtLock(); + try { + if (b) { + Thread t = new Thread() { + public void run() { + GtkDirectoryDialogPeer.this.run(dd.getTitle(), + dd.getDirectory()); + dd.setVisible(false); + } + }; + t.start(); + } else { + quit(); + dd.setVisible(false); + } + } finally { + XToolkit.awtUnlock(); + } + } + + @Override + public void dispose() { + quit(); + super.dispose(); + } + + @Override + public void setDirectory(String dir) { + // We do not implement this method because we + // have delegated to FileDialog#setDirectory + } +} diff -r 78537b37b7de src/solaris/classes/sun/awt/X11/Separator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/solaris/classes/sun/awt/X11/Separator.java Tue May 18 23:44:14 2010 +0200 @@ -0,0 +1,83 @@ +/* + * Copyright 2010 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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. + */ +package sun.awt.X11; + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Rectangle; + +/** + * Horizontal or vertical dividing line. Used in {@link XFileDialogPeer) and + * {@link XDirectoryDialogPeer). + * + * @author c.cerbo + */ +class Separator extends Canvas { + + public final static int HORIZONTAL = 0; + public final static int VERTICAL = 1; + int orientation; + + public Separator(int length, int thickness, int orient) { + super(); + orientation = orient; + if (orient == HORIZONTAL) { + resize(length, thickness); + } else { + // VERTICAL + resize(thickness, length); + } + } + + @Override + public void paint(Graphics g) { + int x1, y1, x2, y2; + Rectangle bbox = bounds(); + Color c = getBackground(); + Color brighter = c.brighter(); + Color darker = c.darker(); + + if (orientation == HORIZONTAL) { + x1 = 0; + x2 = bbox.width - 1; + y1 = y2 = bbox.height / 2 - 1; + + } else { + // VERTICAL + x1 = x2 = bbox.width / 2 - 1; + y1 = 0; + y2 = bbox.height - 1; + } + g.setColor(darker); + g.drawLine(x1, y2, x2, y2); + g.setColor(brighter); + if (orientation == HORIZONTAL) { + g.drawLine(x1, y2 + 1, x2, y2 + 1); + } else { + g.drawLine(x1 + 1, y2, x2 + 1, y2); + } + } +} diff -r 78537b37b7de src/solaris/classes/sun/awt/X11/XDirectoryDialogPeer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/solaris/classes/sun/awt/X11/XDirectoryDialogPeer.java Tue May 18 23:44:14 2010 +0200 @@ -0,0 +1,468 @@ +/* + * Copyright 2010 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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. + */ +package sun.awt.X11; + +import java.awt.*; +import javax.swing.*; +import java.awt.event.*; +import java.awt.peer.*; +import java.io.*; +import java.util.Locale; +import sun.util.logging.PlatformLogger; +import sun.awt.AWTAccessor; + +/** + * DirectoryDialogPeer for X-Windows. + * + * @author Costantino Cerbo (c.cerbo@gmail.com) + */ +class XDirectoryDialogPeer extends XDialogPeer implements DirectoryDialogPeer, + ActionListener, ItemListener, KeyEventDispatcher, XChoicePeerListener { + + private static final PlatformLogger log = PlatformLogger + .getLogger("sun.awt.X11.XFileDialogPeer"); + private static final int PATH_CHOICE_WIDTH = 20; + + private DirectoryDialog directoryDialog; + + // ************** Components in the fileDialogWindow *************** + private List directoryList; + private Choice pathChoice; + private TextField pathField; + private String dir; + + XDirectoryDialogPeer(DirectoryDialog directoryDialog) { + super((Dialog) directoryDialog); + this.directoryDialog = directoryDialog; + if (directoryDialog.getDirectory() == null) { + AWTAccessor.getDirectoryDialogAccessor().setDirectory( + directoryDialog, System.getProperty("user.dir")); + } + this.dir = directoryDialog.getDirectory(); + + Locale l = directoryDialog.getLocale(); + UIDefaults uid = XToolkit.getUIDefaults(); + + GridBagLayout gbl = new GridBagLayout(); + GridBagLayout gblButtons = new GridBagLayout(); + GridBagConstraints gbc = new GridBagConstraints(); + directoryDialog.setLayout(gbl); + directoryDialog.setMinimumSize(new Dimension(400, 400)); + + // create components + Panel buttons = new Panel(); + buttons.setLayout(gblButtons); + Button openButton = new Button(uid.getString( + "FileChooser.openButtonText", l)); + openButton.setActionCommand("openButton"); + + Button cancelButton = new Button(uid.getString( + "FileChooser.cancelButtonText", l)); + cancelButton.setActionCommand("cancelButton"); + + directoryList = new List(); + + // the insets used by the components in the dialog + Insets noInset = new Insets(0, 0, 0, 0); + Insets textFieldInset = new Insets(0, 8, 0, 8); + Insets leftListInset = new Insets(0, 8, 0, 4); + Insets separatorInset = new Insets(8, 0, 0, 0); + Insets labelInset = new Insets(0, 8, 0, 0); + Insets buttonsInset = new Insets(10, 8, 10, 8); + + // add components to GridBagLayout "gbl" + + Font f = new Font(Font.DIALOG, Font.PLAIN, 12); + + Label label = new Label(uid.getString("FileChooser.pathLabelText", l)); + label.setFont(f); + addComponent(label, gbl, gbc, 0, 0, 1, GridBagConstraints.WEST, + (Container) directoryDialog, 1, 0, GridBagConstraints.NONE, + labelInset); + + pathField = new TextField(dir); + listFolders(dir); + + pathChoice = new Choice() { + + @Override + public Dimension getPreferredSize() { + return new Dimension(PATH_CHOICE_WIDTH, pathField + .getPreferredSize().height); + } + }; + Panel pathPanel = new Panel(); + pathPanel.setLayout(new BorderLayout()); + + pathPanel.add(pathField, BorderLayout.CENTER); + pathPanel.add(pathChoice, BorderLayout.EAST); + addComponent(pathPanel, gbl, gbc, 0, 1, 2, GridBagConstraints.WEST, + (Container) directoryDialog, 1, 0, + GridBagConstraints.HORIZONTAL, textFieldInset); + + label = new Label(uid.getString("FileChooser.foldersLabelText", l)); + + label.setFont(f); + addComponent(label, gbl, gbc, 0, 4, 1, GridBagConstraints.WEST, + (Container) directoryDialog, 1, 0, GridBagConstraints.NONE, + labelInset); + addComponent(directoryList, gbl, gbc, 0, 5, 1, GridBagConstraints.WEST, + (Container) directoryDialog, 1, 1, GridBagConstraints.BOTH, + leftListInset); + + // Separator + addComponent(new Separator(directoryDialog.getSize().width, 2, + Separator.HORIZONTAL), gbl, gbc, 0, 8, 15, + GridBagConstraints.WEST, (Container) directoryDialog, 1, 0, + GridBagConstraints.HORIZONTAL, separatorInset); + + // add buttons to GridBagLayout Buttons + addComponent(openButton, gblButtons, gbc, 0, 0, 1, + GridBagConstraints.WEST, (Container) buttons, 1, 0, + GridBagConstraints.NONE, noInset); + addComponent(cancelButton, gblButtons, gbc, 2, 0, 1, + GridBagConstraints.EAST, (Container) buttons, 1, 0, + GridBagConstraints.NONE, noInset); + + // add ButtonPanel to the GridBagLayout of this class + addComponent(buttons, gbl, gbc, 0, 9, 2, GridBagConstraints.WEST, + (Container) directoryDialog, 1, 0, + GridBagConstraints.HORIZONTAL, buttonsInset); + + directoryList.addActionListener(this); + openButton.addActionListener(this); + cancelButton.addActionListener(this); + pathChoice.addItemListener(this); + pathField.addActionListener(this); + + // b6227750 FileDialog is not disposed when clicking the 'close' (X) + // button on the top right corner, XToolkit + directoryDialog.addWindowListener(new WindowAdapter() { + + @Override + public void windowClosing(WindowEvent e) { + handleCancel(); + } + }); + } + + @Override + public void updateIconImages() { + if (winAttr.icons == null) { + winAttr.iconsInherited = false; + winAttr.icons = getDefaultIconInfo(); + setIconHints(winAttr.icons); + } + } + + /** + * add Component comp to the container cont. add the component to the + * correct GridBagLayout + */ + private void addComponent(Component comp, GridBagLayout gb, + GridBagConstraints c, int gridx, int gridy, int gridwidth, + int anchor, Container cont, int weightx, int weighty, int fill, + Insets in) { + c.gridx = gridx; + c.gridy = gridy; + c.gridwidth = gridwidth; + c.anchor = anchor; + c.weightx = weightx; + c.weighty = weighty; + c.fill = fill; + c.insets = in; + gb.setConstraints(comp, c); + cont.add(comp); + } + + /** + * handle the selection event + */ + private void handleSelection() { + String newDir = pathField.getText() + File.separator; + if (directoryList.getSelectedItem() != null) { + if (!newDir.endsWith(File.separator)) { + newDir += File.separator; + } + newDir += directoryList.getSelectedItem(); + } + + if (newDir.equals(dir)) { + return; + } + + listFolders(newDir); + setDirectory(newDir); + } + + @Override + public void setDirectory(String dir) { + if (dir == null) { + this.dir = null; + return; + } + + if (dir.equals(this.dir)) { + return; + } + + int i; + if ((i = dir.indexOf("~")) != -1) { + dir = dir.substring(0, i) + System.getProperty("user.home") + + dir.substring(i + 1, dir.length()); + } + + File fe = new File(dir).getAbsoluteFile(); + log.fine("Current directory : " + fe); + + if (!fe.isDirectory()) { + dir = "./"; + fe = new File(dir).getAbsoluteFile(); + + if (!fe.isDirectory()) { + return; + } + } + try { + dir = this.dir = fe.getCanonicalPath(); + } catch (java.io.IOException ie) { + dir = this.dir = fe.getAbsolutePath(); + } + pathField.setText(this.dir); + + if (dir.endsWith("/")) { + this.dir = dir; + } else { + this.dir = dir + "/"; + } + + AWTAccessor.getDirectoryDialogAccessor().setDirectory(directoryDialog, + this.dir); + } + + private void listFolders(String folder) { + File[] files = new File(folder).listFiles(); + java.util.Arrays.sort(files); + directoryList.clear(); + directoryList.addItem(".."); + for (File file : files) { + if (file.isDirectory()) { + directoryList.addItem(file.getName() + "/"); + } + } + } + + /** + * handle the cancel event + */ + private void handleCancel() { + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .removeKeyEventDispatcher(this); + + directoryList.clear(); + + AWTAccessor.getDirectoryDialogAccessor().setDirectory(directoryDialog, + null); + + handleQuitButton(); + } + + /** + * handle the quit event + */ + private void handleQuitButton() { + dir = null; + directoryDialog.setVisible(false); + } + + private String[] getDirList(String dir) { + if (!dir.endsWith("/")) { + dir = dir + "/"; + } + char[] charr = dir.toCharArray(); + int numSlashes = 0; + for (int i = 0; i < charr.length; i++) { + if (charr[i] == '/') { + numSlashes++; + } + } + String[] starr = new String[numSlashes]; + int j = 0; + for (int i = charr.length - 1; i >= 0; i--) { + if (charr[i] == '/') { + starr[j++] = new String(charr, 0, i + 1); + } + } + return starr; + } + + /** + * + * @see java.awt.event.ItemEvent ItemEvent.ITEM_STATE_CHANGED + */ + public void itemStateChanged(ItemEvent itemEvent) { + if (itemEvent.getID() != ItemEvent.ITEM_STATE_CHANGED + || itemEvent.getStateChange() == ItemEvent.DESELECTED) { + return; + } + + Object source = itemEvent.getSource(); + if (source == pathChoice) { + /* + * Update the selection ('folder name' text field) after the current + * item changing in the unfurled choice by the arrow keys. See + * 6259434, 6240074 for more information + */ + + String selectedDir = pathChoice.getSelectedItem(); + pathField.setText(selectedDir); + handleSelection(); + } + } + + public void actionPerformed(ActionEvent actionEvent) { + String actionCommand = actionEvent.getActionCommand(); + Object source = actionEvent.getSource(); + + if (actionCommand.equals("openButton")) { + handleQuitButton(); + } else if (actionCommand.equals("cancelButton")) { + handleCancel(); + } else if (source == pathField || source == directoryList) { + handleSelection(); + } + } + + public boolean dispatchKeyEvent(KeyEvent keyEvent) { + int id = keyEvent.getID(); + int keyCode = keyEvent.getKeyCode(); + + if (id == KeyEvent.KEY_PRESSED && keyCode == KeyEvent.VK_ESCAPE) { + synchronized (directoryDialog.getTreeLock()) { + Component comp = (Component) keyEvent.getSource(); + while (comp != null) { + // Fix for 6240084 Disposing a file dialog when the + // drop-down is active does not dispose the dropdown menu, + // on Xtoolkit + // See also 6259493 + if (comp == pathChoice) { + XChoicePeer choicePeer = (XChoicePeer) pathChoice + .getPeer(); + if (choicePeer.isUnfurled()) { + return false; + } + } + if (comp.getPeer() == this) { + handleCancel(); + return true; + } + comp = comp.getParent(); + } + } + } + + return false; + } + + @Override + public void dispose() { + if (directoryDialog != null) { + directoryDialog.removeAll(); + } + if (target != null) { + ((Dialog) target).removeAll(); + } + super.dispose(); + } + + // 03/02/2005 b5097243 Pressing 'ESC' on a file dlg does not dispose the dlg + // on Xtoolkit + @Override + public void setVisible(boolean b) { + super.setVisible(b); + if (b == true) { + // See 6240074 for more information + XChoicePeer choicePeer = (XChoicePeer) pathChoice.getPeer(); + choicePeer.setDrawSelectedItem(false); + choicePeer.setAlignUnder(pathField); + choicePeer.addXChoicePeerListener(this); + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .addKeyEventDispatcher(this); + } else { + // See 6240074 for more information + XChoicePeer choicePeer = (XChoicePeer) pathChoice.getPeer(); + choicePeer.removeXChoicePeerListener(); + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .removeKeyEventDispatcher(this); + } + } + + /* + * Adding items to the path choice based on the text string See 6240074 for + * more information + */ + public void addItemsToPathChoice(String text) { + String dirList[] = getDirList(text); + for (int i = 0; i < dirList.length; i++) { + pathChoice.addItem(dirList[i]); + } + } + + /* + * Refresh the unfurled choice at the time of the opening choice according + * to the text of the path field See 6240074 for more information + */ + public void unfurledChoiceOpening(ListHelper choiceHelper) { + + // When the unfurled choice is opening the first time, we need only to + // add elements, otherwise we've got exception + if (choiceHelper.getItemCount() == 0) { + addItemsToPathChoice(pathField.getText()); + return; + } + + // If the set of the directories the exactly same as the used to be then + // dummy + if (pathChoice.getItem(0).equals(pathField.getText())) { + return; + } + + pathChoice.removeAll(); + addItemsToPathChoice(pathField.getText()); + } + + /* + * Refresh the file dialog at the time of the closing choice according to + * the selected item of the choice See 6240074 for more information + */ + public void unfurledChoiceClosing() { + // This is the exactly same code as invoking later at the time of the + // itemStateChanged + // Here is we restore Windows behaviour: change current directory if + // user press 'ESC' + String selectedDir = pathChoice.getSelectedItem(); + directoryDialog.setDirectory(selectedDir); + } +} diff -r 78537b37b7de src/solaris/classes/sun/awt/X11/XFileDialogPeer.java --- a/src/solaris/classes/sun/awt/X11/XFileDialogPeer.java Fri Apr 30 17:03:15 2010 -0700 +++ b/src/solaris/classes/sun/awt/X11/XFileDialogPeer.java Tue May 18 23:44:14 2010 +0200 @@ -836,50 +836,6 @@ } } -class Separator extends Canvas { - public final static int HORIZONTAL = 0; - public final static int VERTICAL = 1; - int orientation; - - public Separator(int length, int thickness, int orient) { - super(); - orientation = orient; - if (orient == HORIZONTAL) { - resize(length, thickness); - } else { - // VERTICAL - resize(thickness, length); - } - } - - public void paint(Graphics g) { - int x1, y1, x2, y2; - Rectangle bbox = bounds(); - Color c = getBackground(); - Color brighter = c.brighter(); - Color darker = c.darker(); - - if (orientation == HORIZONTAL) { - x1 = 0; - x2 = bbox.width - 1; - y1 = y2 = bbox.height/2 - 1; - - } else { - // VERTICAL - x1 = x2 = bbox.width/2 - 1; - y1 = 0; - y2 = bbox.height - 1; - } - g.setColor(darker); - g.drawLine(x1, y2, x2, y2); - g.setColor(brighter); - if (orientation == HORIZONTAL) - g.drawLine(x1, y2+1, x2, y2+1); - else - g.drawLine(x1+1, y2, x2+1, y2); - } -} - /* * Motif file dialogs let the user specify a filter that controls the files that * are displayed in the dialog. This filter is generally specified as a regular diff -r 78537b37b7de src/solaris/classes/sun/awt/X11/XToolkit.java --- a/src/solaris/classes/sun/awt/X11/XToolkit.java Fri Apr 30 17:03:15 2010 -0700 +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java Tue May 18 23:44:14 2010 +0200 @@ -1060,6 +1060,14 @@ targetCreatedPeer(target, peer); return peer; } + + public DirectoryDialogPeer createDirectoryDialog(DirectoryDialog target) { + DirectoryDialogPeer peer = checkGtkVersion(2, 4, 0) ? + new GtkDirectoryDialogPeer(target) + : new XDirectoryDialogPeer(target); + targetCreatedPeer(target, peer); + return peer; + } public MenuBarPeer createMenuBar(MenuBar target) { XMenuBarPeer peer = new XMenuBarPeer(target); diff -r 78537b37b7de src/solaris/classes/sun/awt/motif/MToolkit.java --- a/src/solaris/classes/sun/awt/motif/MToolkit.java Fri Apr 30 17:03:15 2010 -0700 +++ b/src/solaris/classes/sun/awt/motif/MToolkit.java Tue May 18 23:44:14 2010 +0200 @@ -302,6 +302,10 @@ return null; } + public DirectoryDialogPeer createDirectoryDialog(DirectoryDialog target) { + return null; + } + public MenuBarPeer createMenuBar(MenuBar target) { //MenuBarPeer peer = new MMenuBarPeer(target); //targetCreatedPeer(target, peer); diff -r 78537b37b7de src/solaris/native/sun/awt/sun_awt_X11_GtkDirectoryDialogPeer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/solaris/native/sun/awt/sun_awt_X11_GtkDirectoryDialogPeer.c Tue May 18 23:44:14 2010 +0200 @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include "gtk2_interface.h" +#include "sun_awt_X11_GtkDirectoryDialogPeer.h" + +static JavaVM *jvm; +static GtkWidget *dialog = NULL; + +/* To cache some method IDs */ +static jmethodID setDirectoryInternalMethodID = NULL; + +/* + * Class: sun_awt_X11_GtkDirectoryDialogPeer + * Method: quit + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_GtkDirectoryDialogPeer_quit +(JNIEnv * env, jobject jpeer) +{ + if (dialog != NULL) + { + fp_gtk_widget_hide (dialog); + fp_gtk_widget_destroy (dialog); + + fp_gtk_main_quit (); + dialog = NULL; + } +} + +static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj) +{ + JNIEnv *env; + char *current_folder; + jclass cx; + jstring jcurrent_folder; + + env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); + current_folder = NULL; + + if (responseId == GTK_RESPONSE_ACCEPT) { + current_folder = fp_gtk_file_chooser_get_current_folder( + GTK_FILE_CHOOSER(dialog)); + } + + if (setDirectoryInternalMethodID == NULL) { + cx = (*env)->GetObjectClass(env, (jobject) obj); + if (cx == NULL) { + JNU_ThrowInternalError(env, "Could not get GTK peer class"); + return; + } + + setDirectoryInternalMethodID = (*env)->GetMethodID(env, cx, + "setDirectoryInternal", "(Ljava/lang/String;)V"); + if (setDirectoryInternalMethodID == NULL) { + JNU_ThrowInternalError(env, + "Could not get setDirectoryInternalMethodID method id"); + return; + } + } + + jcurrent_folder = (*env)->NewStringUTF(env, current_folder); + + (*env)->CallVoidMethod(env, obj, setDirectoryInternalMethodID, jcurrent_folder); + fp_g_free(current_folder); + + Java_sun_awt_X11_GtkDirectoryDialogPeer_quit(NULL, NULL); +} + +/* + * Class: sun_awt_X11_GtkDirectoryDialogPeer + * Method: run + * Signature: (Ljava/lang/String;ILjava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_sun_awt_X11_GtkDirectoryDialogPeer_run(JNIEnv * env, jobject jpeer, + jstring jtitle, jstring jdir) +{ + if (jvm == NULL) { + (*env)->GetJavaVM(env, &jvm); + } + + fp_gdk_threads_init(); + fp_gdk_threads_enter(); + + const char *title = (*env)->GetStringUTFChars(env, jtitle, 0); + + /* Action SELECT_FOLDER */ + dialog = fp_gtk_file_chooser_dialog_new(title, NULL, + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + + (*env)->ReleaseStringUTFChars(env, jtitle, title); + + /* Set the directory */ + if (jdir != NULL) { + const char *dir = (*env)->GetStringUTFChars(env, jdir, 0); + fp_gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir); + (*env)->ReleaseStringUTFChars(env, jdir, dir); + } + + fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK( + handle_response), jpeer); + fp_gtk_widget_show(dialog); + + fp_gtk_main(); + fp_gdk_threads_leave(); +} diff -r 78537b37b7de src/solaris/native/sun/awt/sun_awt_X11_GtkDirectoryDialogPeer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/solaris/native/sun/awt/sun_awt_X11_GtkDirectoryDialogPeer.h Tue May 18 23:44:14 2010 +0200 @@ -0,0 +1,31 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class sun_awt_X11_GtkDirectoryDialogPeer */ + +#ifndef _Included_sun_awt_X11_GtkDirectoryDialogPeer +#define _Included_sun_awt_X11_GtkDirectoryDialogPeer +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * Class: sun_awt_X11_GtkDirectoryDialogPeer + * Method: run + * Signature: (Ljava/lang/String;ILjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_GtkDirectoryDialogPeer_run +(JNIEnv *, jobject, jstring, jstring); + +/* + * Class: sun_awt_X11_GtkDirectoryDialogPeer + * Method: quit + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_GtkDirectoryDialogPeer_quit +(JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif