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