1 /* 2 * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package com.sun.java.swing.plaf.gtk; 26 27 import java.awt.*; 28 import java.awt.event.*; 29 import java.beans.*; 30 import java.io.File; 31 import java.io.IOException; 32 import java.text.MessageFormat; 33 import java.util.*; 34 35 import javax.swing.*; 36 import javax.swing.border.*; 37 import javax.swing.filechooser.*; 38 import javax.swing.event.*; 39 import javax.swing.plaf.*; 40 import javax.swing.plaf.basic.BasicDirectoryModel; 41 import javax.swing.table.*; 42 import javax.accessibility.*; 43 44 import sun.swing.AbstractFilterComboBoxModel; 45 import sun.swing.SwingUtilities2; 46 47 import sun.swing.plaf.synth.*; 48 import sun.swing.FilePane; 49 import sun.awt.shell.ShellFolder; 50 51 /** 52 * GTK FileChooserUI. 53 * 54 * @author Leif Samuelsson 55 * @author Jeff Dinkins 56 */ 57 class GTKFileChooserUI extends SynthFileChooserUI { 58 59 // The accessoryPanel is a container to place the JFileChooser accessory component 60 private JPanel accessoryPanel = null; 61 62 private String newFolderButtonText = null; 63 private String newFolderErrorSeparator = null; 64 private String newFolderErrorText = null; 65 private String newFolderDialogText = null; 66 private String newFolderNoDirectoryErrorTitleText = null; 67 private String newFolderNoDirectoryErrorText = null; 68 69 private String deleteFileButtonText = null; 70 private String renameFileButtonText = null; 71 72 private String newFolderButtonToolTipText = null; 73 private String deleteFileButtonToolTipText = null; 74 private String renameFileButtonToolTipText = null; 75 76 private int newFolderButtonMnemonic = 0; 77 private int deleteFileButtonMnemonic = 0; 78 private int renameFileButtonMnemonic = 0; 79 private int foldersLabelMnemonic = 0; 80 private int filesLabelMnemonic = 0; 81 82 private String renameFileDialogText = null; 83 private String renameFileErrorTitle = null; 84 private String renameFileErrorText = null; 85 86 private JComboBox filterComboBox; 87 private FilterComboBoxModel filterComboBoxModel; 88 89 // From Motif 90 91 private JPanel rightPanel; 92 private JList directoryList; 93 private JList fileList; 94 95 private JLabel pathField; 96 private JTextField fileNameTextField; 97 98 private static final Dimension hstrut3 = new Dimension(3, 1); 99 private static final Dimension vstrut10 = new Dimension(1, 10); 100 101 private static Dimension prefListSize = new Dimension(75, 150); 102 103 private static Dimension PREF_SIZE = new Dimension(435, 360); 104 private static Dimension MIN_SIZE = new Dimension(200, 300); 105 106 private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1); 107 108 private static Dimension MAX_SIZE = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE); 109 110 private static final Insets buttonMargin = new Insets(3, 3, 3, 3); 111 112 private String filesLabelText = null; 113 private String foldersLabelText = null; 114 private String pathLabelText = null; 115 private String filterLabelText = null; 116 117 private int pathLabelMnemonic = 0; 118 private int filterLabelMnemonic = 0; 119 120 private JComboBox directoryComboBox; 121 private DirectoryComboBoxModel directoryComboBoxModel; 122 private Action directoryComboBoxAction = new DirectoryComboBoxAction(); 123 private JPanel bottomButtonPanel; 124 private GTKDirectoryModel model = null; 125 private Action newFolderAction; 126 private boolean readOnly; 127 private boolean showDirectoryIcons; 128 private boolean showFileIcons; 129 private GTKFileView fileView = new GTKFileView(); 130 private PropertyChangeListener gtkFCPropertyChangeListener; 131 private Action approveSelectionAction = new GTKApproveSelectionAction(); 132 private GTKDirectoryListModel directoryListModel; 133 134 public GTKFileChooserUI(JFileChooser filechooser) { 135 super(filechooser); 136 } 137 138 protected ActionMap createActionMap() { 139 ActionMap map = new ActionMapUIResource(); 140 map.put("approveSelection", getApproveSelectionAction()); 141 map.put("cancelSelection", getCancelSelectionAction()); 142 map.put("Go Up", getChangeToParentDirectoryAction()); 143 map.put("fileNameCompletion", getFileNameCompletionAction()); 144 return map; 145 } 146 147 public String getFileName() { 148 JFileChooser fc = getFileChooser(); 149 String typedInName = fileNameTextField != null ? 150 fileNameTextField.getText() : null; 151 152 if (!fc.isMultiSelectionEnabled()) { 153 return typedInName; 154 } 155 156 int mode = fc.getFileSelectionMode(); 157 JList list = mode == JFileChooser.DIRECTORIES_ONLY ? 158 directoryList : fileList; 159 Object[] files = list.getSelectedValues(); 160 int len = files.length; 161 Vector<String> result = new Vector<String>(len + 1); 162 163 // we return all selected file names 164 for (int i = 0; i < len; i++) { 165 File file = (File)files[i]; 166 result.add(file.getName()); 167 } 168 // plus the file name typed into the text field, if not already there 169 if (typedInName != null && !result.contains(typedInName)) { 170 result.add(typedInName); 171 } 172 173 StringBuffer buf = new StringBuffer(); 174 len = result.size(); 175 176 // construct the resulting string 177 for (int i=0; i<len; i++) { 178 if (i > 0) { 179 buf.append(" "); 180 } 181 if (len > 1) { 182 buf.append("\""); 183 } 184 buf.append(result.get(i)); 185 if (len > 1) { 186 buf.append("\""); 187 } 188 } 189 return buf.toString(); 190 } 191 192 public void setFileName(String fileName) { 193 if (fileNameTextField != null) { 194 fileNameTextField.setText(fileName); 195 } 196 } 197 198 // public String getDirectoryName() { 199 // return pathField.getText(); 200 // } 201 202 public void setDirectoryName(String dirname) { 203 pathField.setText(dirname); 204 } 205 206 public void ensureFileIsVisible(JFileChooser fc, File f) { 207 // PENDING 208 } 209 210 public void rescanCurrentDirectory(JFileChooser fc) { 211 getModel().validateFileCache(); 212 } 213 214 public JPanel getAccessoryPanel() { 215 return accessoryPanel; 216 } 217 218 // *********************** 219 // * FileView operations * 220 // *********************** 221 222 public FileView getFileView(JFileChooser fc) { 223 return fileView; 224 } 225 226 private class GTKFileView extends BasicFileView { 227 public GTKFileView() { 228 iconCache = null; 229 } 230 231 public void clearIconCache() { 232 } 233 234 public Icon getCachedIcon(File f) { 235 return null; 236 } 237 238 public void cacheIcon(File f, Icon i) { 239 } 240 241 public Icon getIcon(File f) { 242 return (f != null && f.isDirectory()) ? directoryIcon : fileIcon; 243 } 244 } 245 246 247 private void updateDefaultButton() { 248 JFileChooser filechooser = getFileChooser(); 249 JRootPane root = SwingUtilities.getRootPane(filechooser); 250 if (root == null) { 251 return; 252 } 253 254 if (filechooser.getControlButtonsAreShown()) { 255 if (root.getDefaultButton() == null) { 256 root.setDefaultButton(getApproveButton(filechooser)); 257 getCancelButton(filechooser).setDefaultCapable(false); 258 } 259 } else { 260 if (root.getDefaultButton() == getApproveButton(filechooser)) { 261 root.setDefaultButton(null); 262 } 263 } 264 } 265 266 protected void doSelectedFileChanged(PropertyChangeEvent e) { 267 super.doSelectedFileChanged(e); 268 File f = (File) e.getNewValue(); 269 if (f != null) { 270 setFileName(getFileChooser().getName(f)); 271 } 272 } 273 274 protected void doDirectoryChanged(PropertyChangeEvent e) { 275 directoryList.clearSelection(); 276 ListSelectionModel sm = directoryList.getSelectionModel(); 277 if (sm instanceof DefaultListSelectionModel) { 278 ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0); 279 sm.setAnchorSelectionIndex(0); 280 } 281 fileList.clearSelection(); 282 sm = fileList.getSelectionModel(); 283 if (sm instanceof DefaultListSelectionModel) { 284 ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0); 285 sm.setAnchorSelectionIndex(0); 286 } 287 288 File currentDirectory = getFileChooser().getCurrentDirectory(); 289 if (currentDirectory != null) { 290 try { 291 setDirectoryName(ShellFolder.getNormalizedFile((File)e.getNewValue()).getPath()); 292 } catch (IOException ioe) { 293 setDirectoryName(((File)e.getNewValue()).getAbsolutePath()); 294 } 295 if ((getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) && !getFileChooser().isMultiSelectionEnabled()) { 296 setFileName(pathField.getText()); 297 } 298 directoryComboBoxModel.addItem(currentDirectory); 299 directoryListModel.directoryChanged(); 300 } 301 super.doDirectoryChanged(e); 302 } 303 304 protected void doAccessoryChanged(PropertyChangeEvent e) { 305 if (getAccessoryPanel() != null) { 306 if (e.getOldValue() != null) { 307 getAccessoryPanel().remove((JComponent)e.getOldValue()); 308 } 309 JComponent accessory = (JComponent)e.getNewValue(); 310 if (accessory != null) { 311 getAccessoryPanel().add(accessory, BorderLayout.CENTER); 312 getAccessoryPanel().setPreferredSize(accessory.getPreferredSize()); 313 getAccessoryPanel().setMaximumSize(MAX_SIZE); 314 } else { 315 getAccessoryPanel().setPreferredSize(ZERO_ACC_SIZE); 316 getAccessoryPanel().setMaximumSize(ZERO_ACC_SIZE); 317 } 318 } 319 } 320 321 protected void doFileSelectionModeChanged(PropertyChangeEvent e) { 322 directoryList.clearSelection(); 323 rightPanel.setVisible(((Integer)e.getNewValue()).intValue() != JFileChooser.DIRECTORIES_ONLY); 324 325 super.doFileSelectionModeChanged(e); 326 } 327 328 protected void doMultiSelectionChanged(PropertyChangeEvent e) { 329 if (getFileChooser().isMultiSelectionEnabled()) { 330 fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 331 } else { 332 fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 333 fileList.clearSelection(); 334 } 335 336 super.doMultiSelectionChanged(e); 337 } 338 339 protected void doControlButtonsChanged(PropertyChangeEvent e) { 340 super.doControlButtonsChanged(e); 341 342 JFileChooser filechooser = getFileChooser(); 343 if (filechooser.getControlButtonsAreShown()) { 344 filechooser.add(bottomButtonPanel, BorderLayout.SOUTH); 345 } else { 346 filechooser.remove(bottomButtonPanel); 347 } 348 updateDefaultButton(); 349 } 350 351 protected void doAncestorChanged(PropertyChangeEvent e) { 352 if (e.getOldValue() == null && e.getNewValue() != null) { 353 // Ancestor was added, set initial focus 354 fileNameTextField.selectAll(); 355 fileNameTextField.requestFocus(); 356 updateDefaultButton(); 357 } 358 359 super.doAncestorChanged(e); 360 } 361 362 363 364 // ******************************************** 365 // ************ Create Listeners ************** 366 // ******************************************** 367 368 public ListSelectionListener createListSelectionListener(JFileChooser fc) { 369 return new SelectionListener(); 370 } 371 372 class DoubleClickListener extends MouseAdapter { 373 JList list; 374 public DoubleClickListener(JList list) { 375 this.list = list; 376 } 377 378 public void mouseClicked(MouseEvent e) { 379 if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) { 380 int index = list.locationToIndex(e.getPoint()); 381 if (index >= 0) { 382 File f = (File) list.getModel().getElementAt(index); 383 try { 384 // Strip trailing ".." 385 f = ShellFolder.getNormalizedFile(f); 386 } catch (IOException ex) { 387 // That's ok, we'll use f as is 388 } 389 if (getFileChooser().isTraversable(f)) { 390 list.clearSelection(); 391 if (getFileChooser().getCurrentDirectory().equals(f)){ 392 rescanCurrentDirectory(getFileChooser()); 393 } else { 394 getFileChooser().setCurrentDirectory(f); 395 } 396 } else { 397 getFileChooser().approveSelection(); 398 } 399 } 400 } 401 } 402 403 public void mouseEntered(MouseEvent evt) { 404 if (list != null) { 405 TransferHandler th1 = getFileChooser().getTransferHandler(); 406 TransferHandler th2 = list.getTransferHandler(); 407 if (th1 != th2) { 408 list.setTransferHandler(th1); 409 } 410 if (getFileChooser().getDragEnabled() != list.getDragEnabled()) { 411 list.setDragEnabled(getFileChooser().getDragEnabled()); 412 } 413 } 414 } 415 } 416 417 protected MouseListener createDoubleClickListener(JFileChooser fc, JList list) { 418 return new DoubleClickListener(list); 419 } 420 421 422 423 protected class SelectionListener implements ListSelectionListener { 424 public void valueChanged(ListSelectionEvent e) { 425 if (!e.getValueIsAdjusting()) { 426 JFileChooser chooser = getFileChooser(); 427 JList list = (JList) e.getSource(); 428 429 if (chooser.isMultiSelectionEnabled()) { 430 File[] files = null; 431 Object[] objects = list.getSelectedValues(); 432 if (objects != null) { 433 if (objects.length == 1 434 && ((File)objects[0]).isDirectory() 435 && chooser.isTraversable(((File)objects[0])) 436 && (chooser.getFileSelectionMode() != chooser.DIRECTORIES_ONLY 437 || !chooser.getFileSystemView().isFileSystem(((File)objects[0])))) { 438 setDirectorySelected(true); 439 setDirectory(((File)objects[0])); 440 } else { 441 ArrayList<File> fList = new ArrayList<File>(objects.length); 442 for (Object object : objects) { 443 File f = (File) object; 444 if ((chooser.isFileSelectionEnabled() && f.isFile()) 445 || (chooser.isDirectorySelectionEnabled() && f.isDirectory())) { 446 fList.add(f); 447 } 448 } 449 if (fList.size() > 0) { 450 files = fList.toArray(new File[fList.size()]); 451 } 452 setDirectorySelected(false); 453 } 454 } 455 chooser.setSelectedFiles(files); 456 } else { 457 File file = (File)list.getSelectedValue(); 458 if (file != null 459 && file.isDirectory() 460 && chooser.isTraversable(file) 461 && (chooser.getFileSelectionMode() == chooser.FILES_ONLY 462 || !chooser.getFileSystemView().isFileSystem(file))) { 463 464 setDirectorySelected(true); 465 setDirectory(file); 466 } else { 467 setDirectorySelected(false); 468 if (file != null) { 469 chooser.setSelectedFile(file); 470 } 471 } 472 } 473 } 474 } 475 } 476 477 478 // 479 // ComponentUI Interface Implementation methods 480 // 481 public static ComponentUI createUI(JComponent c) { 482 return new GTKFileChooserUI((JFileChooser)c); 483 } 484 485 public void installUI(JComponent c) { 486 accessoryPanel = new JPanel(new BorderLayout(10, 10)); 487 accessoryPanel.setName("GTKFileChooser.accessoryPanel"); 488 489 super.installUI(c); 490 } 491 492 public void uninstallUI(JComponent c) { 493 c.removePropertyChangeListener(filterComboBoxModel); 494 super.uninstallUI(c); 495 496 if (accessoryPanel != null) { 497 accessoryPanel.removeAll(); 498 } 499 accessoryPanel = null; 500 getFileChooser().removeAll(); 501 } 502 503 public void installComponents(JFileChooser fc) { 504 super.installComponents(fc); 505 506 boolean leftToRight = fc.getComponentOrientation().isLeftToRight(); 507 508 fc.setLayout(new BorderLayout()); 509 fc.setAlignmentX(JComponent.CENTER_ALIGNMENT); 510 511 // Top row of buttons 512 JPanel topButtonPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0)); 513 topButtonPanel.setBorder(new EmptyBorder(10, 10, 0, 10)); 514 topButtonPanel.setName("GTKFileChooser.topButtonPanel"); 515 516 if (!UIManager.getBoolean("FileChooser.readOnly")) { 517 JButton newFolderButton = new JButton(getNewFolderAction()); 518 newFolderButton.setName("GTKFileChooser.newFolderButton"); 519 newFolderButton.setMnemonic(newFolderButtonMnemonic); 520 newFolderButton.setToolTipText(newFolderButtonToolTipText); 521 newFolderButton.setText(newFolderButtonText); 522 topButtonPanel.add(newFolderButton); 523 } 524 JButton deleteFileButton = new JButton(deleteFileButtonText); 525 deleteFileButton.setName("GTKFileChooser.deleteFileButton"); 526 deleteFileButton.setMnemonic(deleteFileButtonMnemonic); 527 deleteFileButton.setToolTipText(deleteFileButtonToolTipText); 528 deleteFileButton.setEnabled(false); 529 topButtonPanel.add(deleteFileButton); 530 531 RenameFileAction rfa = new RenameFileAction(); 532 JButton renameFileButton = new JButton(rfa); 533 if (readOnly) { 534 rfa.setEnabled(false); 535 } 536 renameFileButton.setText(renameFileButtonText); 537 renameFileButton.setName("GTKFileChooser.renameFileButton"); 538 renameFileButton.setMnemonic(renameFileButtonMnemonic); 539 renameFileButton.setToolTipText(renameFileButtonToolTipText); 540 topButtonPanel.add(renameFileButton); 541 542 fc.add(topButtonPanel, BorderLayout.NORTH); 543 544 545 JPanel interior = new JPanel(); 546 interior.setBorder(new EmptyBorder(0, 10, 10, 10)); 547 interior.setName("GTKFileChooser.interiorPanel"); 548 align(interior); 549 interior.setLayout(new BoxLayout(interior, BoxLayout.PAGE_AXIS)); 550 551 fc.add(interior, BorderLayout.CENTER); 552 553 JPanel comboBoxPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 554 0, 0) { 555 public void layoutContainer(Container target) { 556 super.layoutContainer(target); 557 JComboBox comboBox = directoryComboBox; 558 if (comboBox.getWidth() > target.getWidth()) { 559 comboBox.setBounds(0, comboBox.getY(), target.getWidth(), 560 comboBox.getHeight()); 561 } 562 } 563 }); 564 comboBoxPanel.setBorder(new EmptyBorder(0, 0, 4, 0)); 565 comboBoxPanel.setName("GTKFileChooser.directoryComboBoxPanel"); 566 // CurrentDir ComboBox 567 directoryComboBoxModel = createDirectoryComboBoxModel(fc); 568 directoryComboBox = new JComboBox(directoryComboBoxModel); 569 directoryComboBox.setName("GTKFileChooser.directoryComboBox"); 570 directoryComboBox.putClientProperty( "JComboBox.lightweightKeyboardNavigation", "Lightweight" ); 571 directoryComboBox.addActionListener(directoryComboBoxAction); 572 directoryComboBox.setMaximumRowCount(8); 573 comboBoxPanel.add(directoryComboBox); 574 interior.add(comboBoxPanel); 575 576 577 // CENTER: left, right, accessory 578 JPanel centerPanel = new JPanel(new BorderLayout()); 579 centerPanel.setName("GTKFileChooser.centerPanel"); 580 581 // SPLIT PANEL: left, right 582 JSplitPane splitPanel = new JSplitPane(); 583 splitPanel.setName("GTKFileChooser.splitPanel"); 584 splitPanel.setDividerLocation((PREF_SIZE.width-8)/2); 585 586 // left panel - Filter & directoryList 587 JPanel leftPanel = new JPanel(new GridBagLayout()); 588 leftPanel.setName("GTKFileChooser.directoryListPanel"); 589 590 // Add the Directory List 591 // Create a label that looks like button (should be a table header) 592 TableCellRenderer headerRenderer = new JTableHeader().getDefaultRenderer(); 593 JLabel directoryListLabel = 594 (JLabel)headerRenderer.getTableCellRendererComponent(null, foldersLabelText, 595 false, false, 0, 0); 596 directoryListLabel.setName("GTKFileChooser.directoryListLabel"); 597 leftPanel.add(directoryListLabel, new GridBagConstraints( 598 0, 0, 1, 1, 1, 0, GridBagConstraints.WEST, 599 GridBagConstraints.HORIZONTAL, 600 new Insets(0, 0, 0, 0), 0, 0)); 601 leftPanel.add(createDirectoryList(), new GridBagConstraints( 602 0, 1, 1, 1, 1, 1, GridBagConstraints.EAST, 603 GridBagConstraints.BOTH, 604 new Insets(0, 0, 0, 0), 0, 0)); 605 directoryListLabel.setDisplayedMnemonic(foldersLabelMnemonic); 606 directoryListLabel.setLabelFor(directoryList); 607 608 // create files list 609 rightPanel = new JPanel(new GridBagLayout()); 610 rightPanel.setName("GTKFileChooser.fileListPanel"); 611 612 headerRenderer = new JTableHeader().getDefaultRenderer(); 613 JLabel fileListLabel = 614 (JLabel)headerRenderer.getTableCellRendererComponent(null, filesLabelText, 615 false, false, 0, 0); 616 fileListLabel.setName("GTKFileChooser.fileListLabel"); 617 rightPanel.add(fileListLabel, new GridBagConstraints( 618 0, 0, 1, 1, 1, 0, GridBagConstraints.WEST, 619 GridBagConstraints.HORIZONTAL, 620 new Insets(0, 0, 0, 0), 0, 0)); 621 rightPanel.add(createFilesList(), new GridBagConstraints( 622 0, 1, 1, 1, 1, 1, GridBagConstraints.EAST, 623 GridBagConstraints.BOTH, 624 new Insets(0, 0, 0, 0), 0, 0)); 625 fileListLabel.setDisplayedMnemonic(filesLabelMnemonic); 626 fileListLabel.setLabelFor(fileList); 627 628 splitPanel.add(leftPanel, leftToRight ? JSplitPane.LEFT : JSplitPane.RIGHT); 629 splitPanel.add(rightPanel, leftToRight ? JSplitPane.RIGHT : JSplitPane.LEFT); 630 centerPanel.add(splitPanel, BorderLayout.CENTER); 631 632 JComponent accessoryPanel = getAccessoryPanel(); 633 JComponent accessory = fc.getAccessory(); 634 if (accessoryPanel != null) { 635 if (accessory == null) { 636 accessoryPanel.setPreferredSize(ZERO_ACC_SIZE); 637 accessoryPanel.setMaximumSize(ZERO_ACC_SIZE); 638 } else { 639 getAccessoryPanel().add(accessory, BorderLayout.CENTER); 640 accessoryPanel.setPreferredSize(accessory.getPreferredSize()); 641 accessoryPanel.setMaximumSize(MAX_SIZE); 642 } 643 align(accessoryPanel); 644 centerPanel.add(accessoryPanel, BorderLayout.AFTER_LINE_ENDS); 645 } 646 interior.add(centerPanel); 647 interior.add(Box.createRigidArea(vstrut10)); 648 649 JPanel pathFieldPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 650 0, 0)); 651 pathFieldPanel.setBorder(new EmptyBorder(0, 0, 4, 0)); 652 JLabel pathFieldLabel = new JLabel(pathLabelText); 653 pathFieldLabel.setName("GTKFileChooser.pathFieldLabel"); 654 pathFieldLabel.setDisplayedMnemonic(pathLabelMnemonic); 655 align(pathFieldLabel); 656 pathFieldPanel.add(pathFieldLabel); 657 pathFieldPanel.add(Box.createRigidArea(hstrut3)); 658 659 File currentDirectory = fc.getCurrentDirectory(); 660 String curDirName = null; 661 if (currentDirectory != null) { 662 curDirName = currentDirectory.getPath(); 663 } 664 pathField = new JLabel(curDirName) { 665 public Dimension getMaximumSize() { 666 Dimension d = super.getMaximumSize(); 667 d.height = getPreferredSize().height; 668 return d; 669 } 670 }; 671 pathField.setName("GTKFileChooser.pathField"); 672 align(pathField); 673 pathFieldPanel.add(pathField); 674 interior.add(pathFieldPanel); 675 676 // add the fileName field 677 fileNameTextField = new JTextField() { 678 public Dimension getMaximumSize() { 679 Dimension d = super.getMaximumSize(); 680 d.height = getPreferredSize().height; 681 return d; 682 } 683 }; 684 685 pathFieldLabel.setLabelFor(fileNameTextField); 686 687 Set<AWTKeyStroke> forwardTraversalKeys = fileNameTextField.getFocusTraversalKeys( 688 KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); 689 forwardTraversalKeys = new HashSet<AWTKeyStroke>(forwardTraversalKeys); 690 forwardTraversalKeys.remove(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0)); 691 fileNameTextField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardTraversalKeys); 692 693 fileNameTextField.setName("GTKFileChooser.fileNameTextField"); 694 fileNameTextField.getActionMap().put("fileNameCompletionAction", getFileNameCompletionAction()); 695 fileNameTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "fileNameCompletionAction"); 696 interior.add(fileNameTextField); 697 698 // Add the filter combo box 699 JPanel panel = new JPanel(); 700 panel.setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0)); 701 panel.setBorder(new EmptyBorder(0, 0, 4, 0)); 702 JLabel filterLabel = new JLabel(filterLabelText); 703 filterLabel.setName("GTKFileChooser.filterLabel"); 704 filterLabel.setDisplayedMnemonic(filterLabelMnemonic); 705 panel.add(filterLabel); 706 707 filterComboBoxModel = createFilterComboBoxModel(); 708 fc.addPropertyChangeListener(filterComboBoxModel); 709 filterComboBox = new JComboBox(filterComboBoxModel); 710 filterComboBox.setRenderer(createFilterComboBoxRenderer()); 711 filterLabel.setLabelFor(filterComboBox); 712 713 interior.add(Box.createRigidArea(vstrut10)); 714 interior.add(panel); 715 interior.add(filterComboBox); 716 717 // Add buttons 718 bottomButtonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING)); 719 bottomButtonPanel.setName("GTKFileChooser.bottomButtonPanel"); 720 align(bottomButtonPanel); 721 722 JPanel pnButtons = new JPanel(new GridLayout(1, 2, 5, 0)); 723 724 JButton cancelButton = getCancelButton(fc); 725 align(cancelButton); 726 cancelButton.setMargin(buttonMargin); 727 pnButtons.add(cancelButton); 728 729 JButton approveButton = getApproveButton(fc); 730 align(approveButton); 731 approveButton.setMargin(buttonMargin); 732 pnButtons.add(approveButton); 733 734 bottomButtonPanel.add(pnButtons); 735 736 if (fc.getControlButtonsAreShown()) { 737 fc.add(bottomButtonPanel, BorderLayout.SOUTH); 738 } 739 } 740 741 protected void installListeners(JFileChooser fc) { 742 super.installListeners(fc); 743 744 gtkFCPropertyChangeListener = new GTKFCPropertyChangeListener(); 745 fc.addPropertyChangeListener(gtkFCPropertyChangeListener); 746 } 747 748 private int getMnemonic(String key, Locale l) { 749 return SwingUtilities2.getUIDefaultsInt(key, l); 750 } 751 752 protected void uninstallListeners(JFileChooser fc) { 753 super.uninstallListeners(fc); 754 755 if (gtkFCPropertyChangeListener != null) { 756 fc.removePropertyChangeListener(gtkFCPropertyChangeListener); 757 } 758 } 759 760 private class GTKFCPropertyChangeListener implements PropertyChangeListener { 761 public void propertyChange(PropertyChangeEvent e) { 762 String prop = e.getPropertyName(); 763 if (prop.equals("GTKFileChooser.showDirectoryIcons")) { 764 showDirectoryIcons = Boolean.TRUE.equals(e.getNewValue()); 765 } else if (prop.equals("GTKFileChooser.showFileIcons")) { 766 showFileIcons = Boolean.TRUE.equals(e.getNewValue()); 767 } 768 } 769 } 770 771 protected void installDefaults(JFileChooser fc) { 772 super.installDefaults(fc); 773 readOnly = UIManager.getBoolean("FileChooser.readOnly"); 774 showDirectoryIcons = 775 Boolean.TRUE.equals(fc.getClientProperty("GTKFileChooser.showDirectoryIcons")); 776 showFileIcons = 777 Boolean.TRUE.equals(fc.getClientProperty("GTKFileChooser.showFileIcons")); 778 } 779 780 protected void installIcons(JFileChooser fc) { 781 directoryIcon = UIManager.getIcon("FileView.directoryIcon"); 782 fileIcon = UIManager.getIcon("FileView.fileIcon"); 783 } 784 785 protected void installStrings(JFileChooser fc) { 786 super.installStrings(fc); 787 788 Locale l = fc.getLocale(); 789 790 newFolderDialogText = UIManager.getString("FileChooser.newFolderDialogText", l); 791 newFolderErrorText = UIManager.getString("FileChooser.newFolderErrorText",l); 792 newFolderErrorSeparator = UIManager.getString("FileChooser.newFolderErrorSeparator",l); 793 newFolderButtonText = UIManager.getString("FileChooser.newFolderButtonText", l); 794 newFolderNoDirectoryErrorTitleText = UIManager.getString("FileChooser.newFolderNoDirectoryErrorTitleText", l); 795 newFolderNoDirectoryErrorText = UIManager.getString("FileChooser.newFolderNoDirectoryErrorText", l); 796 deleteFileButtonText = UIManager.getString("FileChooser.deleteFileButtonText", l); 797 renameFileButtonText = UIManager.getString("FileChooser.renameFileButtonText", l); 798 799 newFolderButtonMnemonic = getMnemonic("FileChooser.newFolderButtonMnemonic", l); 800 deleteFileButtonMnemonic = getMnemonic("FileChooser.deleteFileButtonMnemonic", l); 801 renameFileButtonMnemonic = getMnemonic("FileChooser.renameFileButtonMnemonic", l); 802 803 newFolderButtonToolTipText = UIManager.getString("FileChooser.newFolderButtonToolTipText", l); 804 deleteFileButtonToolTipText = UIManager.getString("FileChooser.deleteFileButtonToolTipText", l); 805 renameFileButtonToolTipText = UIManager.getString("FileChooser.renameFileButtonToolTipText", l); 806 807 renameFileDialogText = UIManager.getString("FileChooser.renameFileDialogText", l); 808 renameFileErrorTitle = UIManager.getString("FileChooser.renameFileErrorTitle", l); 809 renameFileErrorText = UIManager.getString("FileChooser.renameFileErrorText", l); 810 811 foldersLabelText = UIManager.getString("FileChooser.foldersLabelText",l); 812 foldersLabelMnemonic = getMnemonic("FileChooser.foldersLabelMnemonic", l); 813 814 filesLabelText = UIManager.getString("FileChooser.filesLabelText",l); 815 filesLabelMnemonic = getMnemonic("FileChooser.filesLabelMnemonic", l); 816 817 pathLabelText = UIManager.getString("FileChooser.pathLabelText",l); 818 pathLabelMnemonic = getMnemonic("FileChooser.pathLabelMnemonic", l); 819 820 filterLabelText = UIManager.getString("FileChooser.filterLabelText", l); 821 filterLabelMnemonic = UIManager.getInt("FileChooser.filterLabelMnemonic"); 822 } 823 824 protected void uninstallStrings(JFileChooser fc) { 825 super.uninstallStrings(fc); 826 827 newFolderButtonText = null; 828 deleteFileButtonText = null; 829 renameFileButtonText = null; 830 831 newFolderButtonToolTipText = null; 832 deleteFileButtonToolTipText = null; 833 renameFileButtonToolTipText = null; 834 835 renameFileDialogText = null; 836 renameFileErrorTitle = null; 837 renameFileErrorText = null; 838 839 foldersLabelText = null; 840 filesLabelText = null; 841 842 pathLabelText = null; 843 844 newFolderDialogText = null; 845 newFolderErrorText = null; 846 newFolderErrorSeparator = null; 847 } 848 849 protected JScrollPane createFilesList() { 850 fileList = new JList(); 851 fileList.setName("GTKFileChooser.fileList"); 852 fileList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesLabelText); 853 854 if (getFileChooser().isMultiSelectionEnabled()) { 855 fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 856 } else { 857 fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 858 } 859 860 fileList.setModel(new GTKFileListModel()); 861 fileList.getSelectionModel().removeSelectionInterval(0, 0); 862 fileList.setCellRenderer(new FileCellRenderer()); 863 fileList.addListSelectionListener(createListSelectionListener(getFileChooser())); 864 fileList.addMouseListener(createDoubleClickListener(getFileChooser(), fileList)); 865 align(fileList); 866 JScrollPane scrollpane = new JScrollPane(fileList); 867 scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 868 scrollpane.setName("GTKFileChooser.fileListScrollPane"); 869 scrollpane.setPreferredSize(prefListSize); 870 scrollpane.setMaximumSize(MAX_SIZE); 871 align(scrollpane); 872 return scrollpane; 873 } 874 875 protected JScrollPane createDirectoryList() { 876 directoryList = new JList(); 877 directoryList.setName("GTKFileChooser.directoryList"); 878 directoryList.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, foldersLabelText); 879 align(directoryList); 880 881 directoryList.setCellRenderer(new DirectoryCellRenderer()); 882 directoryListModel = new GTKDirectoryListModel(); 883 directoryList.getSelectionModel().removeSelectionInterval(0, 0); 884 directoryList.setModel(directoryListModel); 885 directoryList.addMouseListener(createDoubleClickListener(getFileChooser(), directoryList)); 886 directoryList.addListSelectionListener(createListSelectionListener(getFileChooser())); 887 888 JScrollPane scrollpane = new JScrollPane(directoryList); 889 scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 890 scrollpane.setName("GTKFileChooser.directoryListScrollPane"); 891 scrollpane.setMaximumSize(MAX_SIZE); 892 scrollpane.setPreferredSize(prefListSize); 893 align(scrollpane); 894 return scrollpane; 895 } 896 897 protected void createModel() { 898 model = new GTKDirectoryModel(); 899 } 900 901 public BasicDirectoryModel getModel() { 902 return model; 903 } 904 905 public Action getApproveSelectionAction() { 906 return approveSelectionAction; 907 } 908 909 private class GTKDirectoryModel extends BasicDirectoryModel { 910 FileSystemView fsv; 911 private Comparator<File> fileComparator = new Comparator<File>() { 912 public int compare(File o, File o1) { 913 return fsv.getSystemDisplayName(o).compareTo(fsv.getSystemDisplayName(o1)); 914 } 915 }; 916 917 public GTKDirectoryModel() { 918 super(getFileChooser()); 919 } 920 921 protected void sort(Vector<? extends File> v) { 922 fsv = getFileChooser().getFileSystemView(); 923 Collections.sort(v, fileComparator); 924 } 925 } 926 927 protected class GTKDirectoryListModel extends AbstractListModel implements ListDataListener { 928 File curDir; 929 public GTKDirectoryListModel() { 930 getModel().addListDataListener(this); 931 directoryChanged(); 932 } 933 934 public int getSize() { 935 return getModel().getDirectories().size() + 1; 936 } 937 938 public Object getElementAt(int index) { 939 return index > 0 ? getModel().getDirectories().elementAt(index - 1): 940 curDir; 941 } 942 943 public void intervalAdded(ListDataEvent e) { 944 fireIntervalAdded(this, e.getIndex0(), e.getIndex1()); 945 } 946 947 public void intervalRemoved(ListDataEvent e) { 948 fireIntervalRemoved(this, e.getIndex0(), e.getIndex1()); 949 } 950 951 // PENDING - this is inefficient - should sent out 952 // incremental adjustment values instead of saying that the 953 // whole list has changed. 954 public void fireContentsChanged() { 955 fireContentsChanged(this, 0, getModel().getDirectories().size()-1); 956 } 957 958 // PENDING - fire the correct interval changed - currently sending 959 // out that everything has changed 960 public void contentsChanged(ListDataEvent e) { 961 fireContentsChanged(); 962 } 963 964 private void directoryChanged() { 965 curDir = getFileChooser().getFileSystemView().createFileObject( 966 getFileChooser().getCurrentDirectory(), "."); 967 } 968 } 969 970 protected class GTKFileListModel extends AbstractListModel implements ListDataListener { 971 public GTKFileListModel() { 972 getModel().addListDataListener(this); 973 } 974 975 public int getSize() { 976 return getModel().getFiles().size(); 977 } 978 979 public boolean contains(Object o) { 980 return getModel().getFiles().contains(o); 981 } 982 983 public int indexOf(Object o) { 984 return getModel().getFiles().indexOf(o); 985 } 986 987 public Object getElementAt(int index) { 988 return getModel().getFiles().elementAt(index); 989 } 990 991 public void intervalAdded(ListDataEvent e) { 992 fireIntervalAdded(this, e.getIndex0(), e.getIndex1()); 993 } 994 995 public void intervalRemoved(ListDataEvent e) { 996 fireIntervalRemoved(this, e.getIndex0(), e.getIndex1()); 997 } 998 999 // PENDING - this is inefficient - should sent out 1000 // incremental adjustment values instead of saying that the 1001 // whole list has changed. 1002 public void fireContentsChanged() { 1003 fireContentsChanged(this, 0, getModel().getFiles().size()-1); 1004 } 1005 1006 // PENDING - fire the interval changed 1007 public void contentsChanged(ListDataEvent e) { 1008 fireContentsChanged(); 1009 } 1010 } 1011 1012 1013 protected class FileCellRenderer extends DefaultListCellRenderer { 1014 public Component getListCellRendererComponent(JList list, Object value, int index, 1015 boolean isSelected, boolean cellHasFocus) { 1016 1017 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 1018 setText(getFileChooser().getName((File) value)); 1019 if (showFileIcons) { 1020 setIcon(getFileChooser().getIcon((File)value)); 1021 } 1022 return this; 1023 } 1024 } 1025 1026 protected class DirectoryCellRenderer extends DefaultListCellRenderer { 1027 public Component getListCellRendererComponent(JList list, Object value, int index, 1028 boolean isSelected, boolean cellHasFocus) { 1029 1030 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 1031 1032 if (showDirectoryIcons) { 1033 setIcon(getFileChooser().getIcon((File)value)); 1034 setText(getFileChooser().getName((File)value)); 1035 } else { 1036 setText(getFileChooser().getName((File)value) + "/"); 1037 } 1038 return this; 1039 } 1040 } 1041 1042 public Dimension getPreferredSize(JComponent c) { 1043 Dimension prefSize = new Dimension(PREF_SIZE); 1044 JComponent accessory = getFileChooser().getAccessory(); 1045 if (accessory != null) { 1046 prefSize.width += accessory.getPreferredSize().width + 20; 1047 } 1048 Dimension d = c.getLayout().preferredLayoutSize(c); 1049 if (d != null) { 1050 return new Dimension(d.width < prefSize.width ? prefSize.width : d.width, 1051 d.height < prefSize.height ? prefSize.height : d.height); 1052 } else { 1053 return prefSize; 1054 } 1055 } 1056 1057 public Dimension getMinimumSize(JComponent x) { 1058 return new Dimension(MIN_SIZE); 1059 } 1060 1061 public Dimension getMaximumSize(JComponent x) { 1062 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); 1063 } 1064 1065 protected void align(JComponent c) { 1066 c.setAlignmentX(JComponent.LEFT_ALIGNMENT); 1067 c.setAlignmentY(JComponent.TOP_ALIGNMENT); 1068 } 1069 1070 public Action getNewFolderAction() { 1071 if (newFolderAction == null) { 1072 newFolderAction = new NewFolderAction(); 1073 newFolderAction.setEnabled(!readOnly); 1074 } 1075 return newFolderAction; 1076 } 1077 1078 // 1079 // DataModel for DirectoryComboxbox 1080 // 1081 protected DirectoryComboBoxModel createDirectoryComboBoxModel(JFileChooser fc) { 1082 return new DirectoryComboBoxModel(); 1083 } 1084 1085 /** 1086 * Data model for a type-face selection combo-box. 1087 */ 1088 protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel { 1089 Vector<File> directories = new Vector<File>(); 1090 File selectedDirectory = null; 1091 JFileChooser chooser = getFileChooser(); 1092 FileSystemView fsv = chooser.getFileSystemView(); 1093 1094 public DirectoryComboBoxModel() { 1095 // Add the current directory to the model, and make it the 1096 // selectedDirectory 1097 File dir = getFileChooser().getCurrentDirectory(); 1098 if (dir != null) { 1099 addItem(dir); 1100 } 1101 } 1102 1103 /** 1104 * Adds the directory to the model and sets it to be selected, 1105 * additionally clears out the previous selected directory and 1106 * the paths leading up to it, if any. 1107 */ 1108 private void addItem(File directory) { 1109 1110 if (directory == null) { 1111 return; 1112 } 1113 1114 int oldSize = directories.size(); 1115 directories.clear(); 1116 if (oldSize > 0) { 1117 fireIntervalRemoved(this, 0, oldSize); 1118 } 1119 1120 // Get the canonical (full) path. This has the side 1121 // benefit of removing extraneous chars from the path, 1122 // for example /foo/bar/ becomes /foo/bar 1123 File canonical; 1124 try { 1125 canonical = fsv.createFileObject(ShellFolder.getNormalizedFile(directory).getPath()); 1126 } catch (IOException e) { 1127 // Maybe drive is not ready. Can't abort here. 1128 canonical = directory; 1129 } 1130 1131 // create File instances of each directory leading up to the top 1132 File f = canonical; 1133 do { 1134 directories.add(f); 1135 } while ((f = f.getParentFile()) != null); 1136 int newSize = directories.size(); 1137 if (newSize > 0) { 1138 fireIntervalAdded(this, 0, newSize); 1139 } 1140 setSelectedItem(canonical); 1141 } 1142 1143 public void setSelectedItem(Object selectedDirectory) { 1144 this.selectedDirectory = (File)selectedDirectory; 1145 fireContentsChanged(this, -1, -1); 1146 } 1147 1148 public Object getSelectedItem() { 1149 return selectedDirectory; 1150 } 1151 1152 public int getSize() { 1153 return directories.size(); 1154 } 1155 1156 public Object getElementAt(int index) { 1157 return directories.elementAt(index); 1158 } 1159 } 1160 1161 /** 1162 * Acts when DirectoryComboBox has changed the selected item. 1163 */ 1164 protected class DirectoryComboBoxAction extends AbstractAction { 1165 protected DirectoryComboBoxAction() { 1166 super("DirectoryComboBoxAction"); 1167 } 1168 1169 public void actionPerformed(ActionEvent e) { 1170 File f = (File)directoryComboBox.getSelectedItem(); 1171 getFileChooser().setCurrentDirectory(f); 1172 } 1173 } 1174 1175 /** 1176 * Creates a new folder. 1177 */ 1178 private class NewFolderAction extends AbstractAction { 1179 protected NewFolderAction() { 1180 super(FilePane.ACTION_NEW_FOLDER); 1181 } 1182 public void actionPerformed(ActionEvent e) { 1183 if (readOnly) { 1184 return; 1185 } 1186 JFileChooser fc = getFileChooser(); 1187 File currentDirectory = fc.getCurrentDirectory(); 1188 String dirName = JOptionPane.showInputDialog(fc, 1189 newFolderDialogText, newFolderButtonText, 1190 JOptionPane.PLAIN_MESSAGE); 1191 1192 if (dirName != null) { 1193 if (!currentDirectory.exists()) { 1194 JOptionPane.showMessageDialog(fc, 1195 MessageFormat.format(newFolderNoDirectoryErrorText, dirName), 1196 newFolderNoDirectoryErrorTitleText, JOptionPane.ERROR_MESSAGE); 1197 return; 1198 } 1199 1200 File newDir = fc.getFileSystemView().createFileObject 1201 (currentDirectory, dirName); 1202 if (newDir == null || !newDir.mkdir()) { 1203 JOptionPane.showMessageDialog(fc, 1204 newFolderErrorText + newFolderErrorSeparator + " \"" + 1205 dirName + "\"", 1206 newFolderErrorText, JOptionPane.ERROR_MESSAGE); 1207 } 1208 fc.rescanCurrentDirectory(); 1209 } 1210 } 1211 } 1212 1213 private class GTKApproveSelectionAction extends ApproveSelectionAction { 1214 public void actionPerformed(ActionEvent e) { 1215 if (isDirectorySelected()) { 1216 File dir = getDirectory(); 1217 try { 1218 // Strip trailing ".." 1219 if (dir != null) { 1220 dir = ShellFolder.getNormalizedFile(dir); 1221 } 1222 } catch (IOException ex) { 1223 // Ok, use f as is 1224 } 1225 if (getFileChooser().getCurrentDirectory().equals(dir)) { 1226 directoryList.clearSelection(); 1227 fileList.clearSelection(); 1228 ListSelectionModel sm = fileList.getSelectionModel(); 1229 if (sm instanceof DefaultListSelectionModel) { 1230 ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0); 1231 sm.setAnchorSelectionIndex(0); 1232 } 1233 rescanCurrentDirectory(getFileChooser()); 1234 return; 1235 } 1236 } 1237 super.actionPerformed(e); 1238 } 1239 } 1240 1241 /** 1242 * Renames file 1243 */ 1244 private class RenameFileAction extends AbstractAction { 1245 protected RenameFileAction() { 1246 super(FilePane.ACTION_EDIT_FILE_NAME); 1247 } 1248 public void actionPerformed(ActionEvent e) { 1249 if (getFileName().equals("")) { 1250 return; 1251 } 1252 JFileChooser fc = getFileChooser(); 1253 File currentDirectory = fc.getCurrentDirectory(); 1254 String newFileName = (String) JOptionPane.showInputDialog 1255 (fc, new MessageFormat(renameFileDialogText).format 1256 (new Object[] { getFileName() }), 1257 renameFileButtonText, JOptionPane.PLAIN_MESSAGE, null, null, 1258 getFileName()); 1259 1260 if (newFileName != null) { 1261 File oldFile = fc.getFileSystemView().createFileObject 1262 (currentDirectory, getFileName()); 1263 File newFile = fc.getFileSystemView().createFileObject 1264 (currentDirectory, newFileName); 1265 if (oldFile == null || newFile == null || 1266 !getModel().renameFile(oldFile, newFile)) { 1267 JOptionPane.showMessageDialog(fc, 1268 new MessageFormat(renameFileErrorText). 1269 format(new Object[] { getFileName(), newFileName}), 1270 renameFileErrorTitle, JOptionPane.ERROR_MESSAGE); 1271 } else { 1272 setFileName(getFileChooser().getName(newFile)); 1273 fc.rescanCurrentDirectory(); 1274 } 1275 } 1276 } 1277 } 1278 1279 // 1280 // Renderer for Filter ComboBox 1281 // 1282 protected FilterComboBoxRenderer createFilterComboBoxRenderer() { 1283 return new FilterComboBoxRenderer(); 1284 } 1285 1286 /** 1287 * Render different filters 1288 */ 1289 public class FilterComboBoxRenderer extends DefaultListCellRenderer implements UIResource { 1290 public String getName() { 1291 // As SynthComboBoxRenderer's are asked for a size BEFORE they 1292 // are parented getName is overriden to force the name to be 1293 // ComboBox.renderer if it isn't set. If we didn't do this the 1294 // wrong style could be used for size calculations. 1295 String name = super.getName(); 1296 if (name == null) { 1297 return "ComboBox.renderer"; 1298 } 1299 return name; 1300 } 1301 1302 public Component getListCellRendererComponent(JList list, Object value, 1303 int index, boolean isSelected, 1304 boolean cellHasFocus) { 1305 1306 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 1307 1308 setName("ComboBox.listRenderer"); 1309 1310 if (value != null) { 1311 if (value instanceof FileFilter) { 1312 setText(((FileFilter) value).getDescription()); 1313 } 1314 } else { 1315 setText(""); 1316 } 1317 1318 return this; 1319 } 1320 } 1321 1322 // 1323 // DataModel for Filter Combobox 1324 // 1325 protected FilterComboBoxModel createFilterComboBoxModel() { 1326 return new FilterComboBoxModel(); 1327 } 1328 1329 /** 1330 * Data model for filter combo-box. 1331 */ 1332 protected class FilterComboBoxModel extends AbstractFilterComboBoxModel { 1333 protected JFileChooser getFileChooser() { 1334 return GTKFileChooserUI.this.getFileChooser(); 1335 } 1336 } 1337 }