1 /* 2 * Copyright (c) 1997, 2006, 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 26 package com.sun.java.swing.plaf.motif; 27 28 import javax.swing.*; 29 import javax.swing.filechooser.*; 30 import javax.swing.event.*; 31 import javax.swing.plaf.*; 32 import javax.swing.plaf.basic.*; 33 import java.awt.*; 34 import java.awt.event.MouseAdapter; 35 import java.awt.event.MouseEvent; 36 import java.beans.*; 37 import java.io.File; 38 import java.io.IOException; 39 import java.util.*; 40 import sun.awt.shell.ShellFolder; 41 import sun.swing.SwingUtilities2; 42 43 /** 44 * Motif FileChooserUI. 45 * 46 * @author Jeff Dinkins 47 */ 48 public class MotifFileChooserUI extends BasicFileChooserUI { 49 50 private FilterComboBoxModel filterComboBoxModel; 51 52 protected JList directoryList = null; 53 protected JList fileList = null; 54 55 protected JTextField pathField = null; 56 protected JComboBox filterComboBox = null; 57 protected JTextField filenameTextField = null; 58 59 private static final Dimension hstrut10 = new Dimension(10, 1); 60 private static final Dimension vstrut10 = new Dimension(1, 10); 61 62 private static final Insets insets = new Insets(10, 10, 10, 10); 63 64 private static Dimension prefListSize = new Dimension(75, 150); 65 66 private static Dimension WITH_ACCELERATOR_PREF_SIZE = new Dimension(650, 450); 67 private static Dimension PREF_SIZE = new Dimension(350, 450); 68 private static Dimension MIN_SIZE = new Dimension(200, 300); 69 70 private static Dimension PREF_ACC_SIZE = new Dimension(10, 10); 71 private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1); 72 73 private static Dimension MAX_SIZE = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE); 74 75 private static final Insets buttonMargin = new Insets(3, 3, 3, 3); 76 77 private JPanel bottomPanel; 78 79 protected JButton approveButton; 80 81 private String enterFolderNameLabelText = null; 82 private int enterFolderNameLabelMnemonic = 0; 83 private String enterFileNameLabelText = null; 84 private int enterFileNameLabelMnemonic = 0; 85 86 private String filesLabelText = null; 87 private int filesLabelMnemonic = 0; 88 89 private String foldersLabelText = null; 90 private int foldersLabelMnemonic = 0; 91 92 private String pathLabelText = null; 93 private int pathLabelMnemonic = 0; 94 95 private String filterLabelText = null; 96 private int filterLabelMnemonic = 0; 97 98 private JLabel fileNameLabel; 99 100 private void populateFileNameLabel() { 101 if (getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) { 102 fileNameLabel.setText(enterFolderNameLabelText); 103 fileNameLabel.setDisplayedMnemonic(enterFolderNameLabelMnemonic); 104 } else { 105 fileNameLabel.setText(enterFileNameLabelText); 106 fileNameLabel.setDisplayedMnemonic(enterFileNameLabelMnemonic); 107 } 108 } 109 110 private String fileNameString(File file) { 111 if (file == null) { 112 return null; 113 } else { 114 JFileChooser fc = getFileChooser(); 115 if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) { 116 return file.getPath(); 117 } else { 118 return file.getName(); 119 } 120 } 121 } 122 123 private String fileNameString(File[] files) { 124 StringBuffer buf = new StringBuffer(); 125 for (int i = 0; files != null && i < files.length; i++) { 126 if (i > 0) { 127 buf.append(" "); 128 } 129 if (files.length > 1) { 130 buf.append("\""); 131 } 132 buf.append(fileNameString(files[i])); 133 if (files.length > 1) { 134 buf.append("\""); 135 } 136 } 137 return buf.toString(); 138 } 139 140 public MotifFileChooserUI(JFileChooser filechooser) { 141 super(filechooser); 142 } 143 144 public String getFileName() { 145 if(filenameTextField != null) { 146 return filenameTextField.getText(); 147 } else { 148 return null; 149 } 150 } 151 152 public void setFileName(String filename) { 153 if(filenameTextField != null) { 154 filenameTextField.setText(filename); 155 } 156 } 157 158 public String getDirectoryName() { 159 return pathField.getText(); 160 } 161 162 public void setDirectoryName(String dirname) { 163 pathField.setText(dirname); 164 } 165 166 public void ensureFileIsVisible(JFileChooser fc, File f) { 167 // PENDING(jeff) 168 } 169 170 public void rescanCurrentDirectory(JFileChooser fc) { 171 getModel().validateFileCache(); 172 } 173 174 public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) { 175 return new PropertyChangeListener() { 176 public void propertyChange(PropertyChangeEvent e) { 177 String prop = e.getPropertyName(); 178 if(prop.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) { 179 File f = (File) e.getNewValue(); 180 if(f != null) { 181 setFileName(getFileChooser().getName(f)); 182 } 183 } else if (prop.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) { 184 File[] files = (File[]) e.getNewValue(); 185 JFileChooser fc = getFileChooser(); 186 if (files != null && files.length > 0 && (files.length > 1 || fc.isDirectorySelectionEnabled() 187 || !files[0].isDirectory())) { 188 setFileName(fileNameString(files)); 189 } 190 } else if (prop.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) { 191 fileList.clearSelection(); 192 } else if(prop.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) { 193 directoryList.clearSelection(); 194 ListSelectionModel sm = directoryList.getSelectionModel(); 195 if (sm instanceof DefaultListSelectionModel) { 196 ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0); 197 sm.setAnchorSelectionIndex(0); 198 } 199 fileList.clearSelection(); 200 sm = fileList.getSelectionModel(); 201 if (sm instanceof DefaultListSelectionModel) { 202 ((DefaultListSelectionModel)sm).moveLeadSelectionIndex(0); 203 sm.setAnchorSelectionIndex(0); 204 } 205 File currentDirectory = getFileChooser().getCurrentDirectory(); 206 if(currentDirectory != null) { 207 try { 208 setDirectoryName(ShellFolder.getNormalizedFile((File)e.getNewValue()).getPath()); 209 } catch (IOException ioe) { 210 setDirectoryName(((File)e.getNewValue()).getAbsolutePath()); 211 } 212 if ((getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) && !getFileChooser().isMultiSelectionEnabled()) { 213 setFileName(getDirectoryName()); 214 } 215 } 216 } else if(prop.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) { 217 if (fileNameLabel != null) { 218 populateFileNameLabel(); 219 } 220 directoryList.clearSelection(); 221 } else if (prop.equals(JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY)) { 222 if(getFileChooser().isMultiSelectionEnabled()) { 223 fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 224 } else { 225 fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 226 fileList.clearSelection(); 227 getFileChooser().setSelectedFiles(null); 228 } 229 } else if (prop.equals(JFileChooser.ACCESSORY_CHANGED_PROPERTY)) { 230 if(getAccessoryPanel() != null) { 231 if(e.getOldValue() != null) { 232 getAccessoryPanel().remove((JComponent) e.getOldValue()); 233 } 234 JComponent accessory = (JComponent) e.getNewValue(); 235 if(accessory != null) { 236 getAccessoryPanel().add(accessory, BorderLayout.CENTER); 237 getAccessoryPanel().setPreferredSize(PREF_ACC_SIZE); 238 getAccessoryPanel().setMaximumSize(MAX_SIZE); 239 } else { 240 getAccessoryPanel().setPreferredSize(ZERO_ACC_SIZE); 241 getAccessoryPanel().setMaximumSize(ZERO_ACC_SIZE); 242 } 243 } 244 } else if (prop.equals(JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY) || 245 prop.equals(JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY) || 246 prop.equals(JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY)) { 247 approveButton.setText(getApproveButtonText(getFileChooser())); 248 approveButton.setToolTipText(getApproveButtonToolTipText(getFileChooser())); 249 } else if (prop.equals(JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY)) { 250 doControlButtonsChanged(e); 251 } else if (prop.equals("componentOrientation")) { 252 ComponentOrientation o = (ComponentOrientation)e.getNewValue(); 253 JFileChooser cc = (JFileChooser)e.getSource(); 254 if (o != (ComponentOrientation)e.getOldValue()) { 255 cc.applyComponentOrientation(o); 256 } 257 } 258 } 259 }; 260 } 261 262 // 263 // ComponentUI Interface Implementation methods 264 // 265 public static ComponentUI createUI(JComponent c) { 266 return new MotifFileChooserUI((JFileChooser)c); 267 } 268 269 public void installUI(JComponent c) { 270 super.installUI(c); 271 } 272 273 public void uninstallUI(JComponent c) { 274 getFileChooser().removeAll(); 275 super.uninstallUI(c); 276 } 277 278 public void installComponents(JFileChooser fc) { 279 fc.setLayout(new BorderLayout(10, 10)); 280 fc.setAlignmentX(JComponent.CENTER_ALIGNMENT); 281 282 JPanel interior = new JPanel() { 283 public Insets getInsets() { 284 return insets; 285 } 286 }; 287 interior.setInheritsPopupMenu(true); 288 align(interior); 289 interior.setLayout(new BoxLayout(interior, BoxLayout.PAGE_AXIS)); 290 291 fc.add(interior, BorderLayout.CENTER); 292 293 // PENDING(jeff) - I18N 294 JLabel l = new JLabel(pathLabelText); 295 l.setDisplayedMnemonic(pathLabelMnemonic); 296 align(l); 297 interior.add(l); 298 299 File currentDirectory = fc.getCurrentDirectory(); 300 String curDirName = null; 301 if(currentDirectory != null) { 302 curDirName = currentDirectory.getPath(); 303 } 304 pathField = new JTextField(curDirName) { 305 public Dimension getMaximumSize() { 306 Dimension d = super.getMaximumSize(); 307 d.height = getPreferredSize().height; 308 return d; 309 } 310 }; 311 pathField.setInheritsPopupMenu(true); 312 l.setLabelFor(pathField); 313 align(pathField); 314 315 // Change to folder on return 316 pathField.addActionListener(getUpdateAction()); 317 interior.add(pathField); 318 319 interior.add(Box.createRigidArea(vstrut10)); 320 321 322 // CENTER: left, right accessory 323 JPanel centerPanel = new JPanel(); 324 centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.LINE_AXIS)); 325 align(centerPanel); 326 327 // left panel - Filter & folderList 328 JPanel leftPanel = new JPanel(); 329 leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS)); 330 align(leftPanel); 331 332 // add the filter PENDING(jeff) - I18N 333 l = new JLabel(filterLabelText); 334 l.setDisplayedMnemonic(filterLabelMnemonic); 335 align(l); 336 leftPanel.add(l); 337 338 filterComboBox = new JComboBox() { 339 public Dimension getMaximumSize() { 340 Dimension d = super.getMaximumSize(); 341 d.height = getPreferredSize().height; 342 return d; 343 } 344 }; 345 filterComboBox.setInheritsPopupMenu(true); 346 l.setLabelFor(filterComboBox); 347 filterComboBoxModel = createFilterComboBoxModel(); 348 filterComboBox.setModel(filterComboBoxModel); 349 filterComboBox.setRenderer(createFilterComboBoxRenderer()); 350 fc.addPropertyChangeListener(filterComboBoxModel); 351 align(filterComboBox); 352 leftPanel.add(filterComboBox); 353 354 // leftPanel.add(Box.createRigidArea(vstrut10)); 355 356 // Add the Folder List PENDING(jeff) - I18N 357 l = new JLabel(foldersLabelText); 358 l.setDisplayedMnemonic(foldersLabelMnemonic); 359 align(l); 360 leftPanel.add(l); 361 JScrollPane sp = createDirectoryList(); 362 sp.getVerticalScrollBar().setFocusable(false); 363 sp.getHorizontalScrollBar().setFocusable(false); 364 sp.setInheritsPopupMenu(true); 365 l.setLabelFor(sp.getViewport().getView()); 366 leftPanel.add(sp); 367 leftPanel.setInheritsPopupMenu(true); 368 369 370 // create files list 371 JPanel rightPanel = new JPanel(); 372 align(rightPanel); 373 rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.PAGE_AXIS)); 374 rightPanel.setInheritsPopupMenu(true); 375 376 l = new JLabel(filesLabelText); 377 l.setDisplayedMnemonic(filesLabelMnemonic); 378 align(l); 379 rightPanel.add(l); 380 sp = createFilesList(); 381 l.setLabelFor(sp.getViewport().getView()); 382 rightPanel.add(sp); 383 sp.setInheritsPopupMenu(true); 384 385 centerPanel.add(leftPanel); 386 centerPanel.add(Box.createRigidArea(hstrut10)); 387 centerPanel.add(rightPanel); 388 centerPanel.setInheritsPopupMenu(true); 389 390 JComponent accessoryPanel = getAccessoryPanel(); 391 JComponent accessory = fc.getAccessory(); 392 if(accessoryPanel != null) { 393 if(accessory == null) { 394 accessoryPanel.setPreferredSize(ZERO_ACC_SIZE); 395 accessoryPanel.setMaximumSize(ZERO_ACC_SIZE); 396 } else { 397 getAccessoryPanel().add(accessory, BorderLayout.CENTER); 398 accessoryPanel.setPreferredSize(PREF_ACC_SIZE); 399 accessoryPanel.setMaximumSize(MAX_SIZE); 400 } 401 align(accessoryPanel); 402 centerPanel.add(accessoryPanel); 403 accessoryPanel.setInheritsPopupMenu(true); 404 } 405 interior.add(centerPanel); 406 interior.add(Box.createRigidArea(vstrut10)); 407 408 // add the filename field PENDING(jeff) - I18N 409 fileNameLabel = new JLabel(); 410 populateFileNameLabel(); 411 align(fileNameLabel); 412 interior.add(fileNameLabel); 413 414 filenameTextField = new JTextField() { 415 public Dimension getMaximumSize() { 416 Dimension d = super.getMaximumSize(); 417 d.height = getPreferredSize().height; 418 return d; 419 } 420 }; 421 filenameTextField.setInheritsPopupMenu(true); 422 fileNameLabel.setLabelFor(filenameTextField); 423 filenameTextField.addActionListener(getApproveSelectionAction()); 424 align(filenameTextField); 425 filenameTextField.setAlignmentX(JComponent.LEFT_ALIGNMENT); 426 interior.add(filenameTextField); 427 428 bottomPanel = getBottomPanel(); 429 bottomPanel.add(new JSeparator(), BorderLayout.NORTH); 430 431 // Add buttons 432 JPanel buttonPanel = new JPanel(); 433 align(buttonPanel); 434 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); 435 buttonPanel.add(Box.createGlue()); 436 437 approveButton = new JButton(getApproveButtonText(fc)) { 438 public Dimension getMaximumSize() { 439 return new Dimension(MAX_SIZE.width, this.getPreferredSize().height); 440 } 441 }; 442 approveButton.setMnemonic(getApproveButtonMnemonic(fc)); 443 approveButton.setToolTipText(getApproveButtonToolTipText(fc)); 444 approveButton.setInheritsPopupMenu(true); 445 align(approveButton); 446 approveButton.setMargin(buttonMargin); 447 approveButton.addActionListener(getApproveSelectionAction()); 448 buttonPanel.add(approveButton); 449 buttonPanel.add(Box.createGlue()); 450 451 JButton updateButton = new JButton(updateButtonText) { 452 public Dimension getMaximumSize() { 453 return new Dimension(MAX_SIZE.width, this.getPreferredSize().height); 454 } 455 }; 456 updateButton.setMnemonic(updateButtonMnemonic); 457 updateButton.setToolTipText(updateButtonToolTipText); 458 updateButton.setInheritsPopupMenu(true); 459 align(updateButton); 460 updateButton.setMargin(buttonMargin); 461 updateButton.addActionListener(getUpdateAction()); 462 buttonPanel.add(updateButton); 463 buttonPanel.add(Box.createGlue()); 464 465 JButton cancelButton = new JButton(cancelButtonText) { 466 public Dimension getMaximumSize() { 467 return new Dimension(MAX_SIZE.width, this.getPreferredSize().height); 468 } 469 }; 470 cancelButton.setMnemonic(cancelButtonMnemonic); 471 cancelButton.setToolTipText(cancelButtonToolTipText); 472 cancelButton.setInheritsPopupMenu(true); 473 align(cancelButton); 474 cancelButton.setMargin(buttonMargin); 475 cancelButton.addActionListener(getCancelSelectionAction()); 476 buttonPanel.add(cancelButton); 477 buttonPanel.add(Box.createGlue()); 478 479 JButton helpButton = new JButton(helpButtonText) { 480 public Dimension getMaximumSize() { 481 return new Dimension(MAX_SIZE.width, this.getPreferredSize().height); 482 } 483 }; 484 helpButton.setMnemonic(helpButtonMnemonic); 485 helpButton.setToolTipText(helpButtonToolTipText); 486 align(helpButton); 487 helpButton.setMargin(buttonMargin); 488 helpButton.setEnabled(false); 489 helpButton.setInheritsPopupMenu(true); 490 buttonPanel.add(helpButton); 491 buttonPanel.add(Box.createGlue()); 492 buttonPanel.setInheritsPopupMenu(true); 493 494 bottomPanel.add(buttonPanel, BorderLayout.SOUTH); 495 bottomPanel.setInheritsPopupMenu(true); 496 if (fc.getControlButtonsAreShown()) { 497 fc.add(bottomPanel, BorderLayout.SOUTH); 498 } 499 } 500 501 protected JPanel getBottomPanel() { 502 if (bottomPanel == null) { 503 bottomPanel = new JPanel(new BorderLayout(0, 4)); 504 } 505 return bottomPanel; 506 } 507 508 private void doControlButtonsChanged(PropertyChangeEvent e) { 509 if (getFileChooser().getControlButtonsAreShown()) { 510 getFileChooser().add(bottomPanel,BorderLayout.SOUTH); 511 } else { 512 getFileChooser().remove(getBottomPanel()); 513 } 514 } 515 516 public void uninstallComponents(JFileChooser fc) { 517 fc.removeAll(); 518 if (filterComboBoxModel != null) { 519 fc.removePropertyChangeListener(filterComboBoxModel); 520 } 521 } 522 523 protected void installStrings(JFileChooser fc) { 524 super.installStrings(fc); 525 526 Locale l = fc.getLocale(); 527 528 enterFolderNameLabelText = UIManager.getString("FileChooser.enterFolderNameLabelText",l); 529 enterFolderNameLabelMnemonic = getMnemonic("FileChooser.enterFolderNameLabelMnemonic", l); 530 enterFileNameLabelText = UIManager.getString("FileChooser.enterFileNameLabelText",l); 531 enterFileNameLabelMnemonic = getMnemonic("FileChooser.enterFileNameLabelMnemonic", l); 532 533 filesLabelText = UIManager.getString("FileChooser.filesLabelText",l); 534 filesLabelMnemonic = getMnemonic("FileChooser.filesLabelMnemonic", l); 535 536 foldersLabelText = UIManager.getString("FileChooser.foldersLabelText",l); 537 foldersLabelMnemonic = getMnemonic("FileChooser.foldersLabelMnemonic", l); 538 539 pathLabelText = UIManager.getString("FileChooser.pathLabelText",l); 540 pathLabelMnemonic = getMnemonic("FileChooser.pathLabelMnemonic", l); 541 542 filterLabelText = UIManager.getString("FileChooser.filterLabelText",l); 543 filterLabelMnemonic = getMnemonic("FileChooser.filterLabelMnemonic", l); 544 } 545 546 private Integer getMnemonic(String key, Locale l) { 547 return SwingUtilities2.getUIDefaultsInt(key, l); 548 } 549 550 protected void installIcons(JFileChooser fc) { 551 // Since motif doesn't have button icons, leave this empty 552 // which overrides the supertype icon loading 553 } 554 555 protected void uninstallIcons(JFileChooser fc) { 556 // Since motif doesn't have button icons, leave this empty 557 // which overrides the supertype icon loading 558 } 559 560 protected JScrollPane createFilesList() { 561 fileList = new JList(); 562 563 if(getFileChooser().isMultiSelectionEnabled()) { 564 fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 565 } else { 566 fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 567 } 568 569 fileList.setModel(new MotifFileListModel()); 570 fileList.getSelectionModel().removeSelectionInterval(0, 0); 571 fileList.setCellRenderer(new FileCellRenderer()); 572 fileList.addListSelectionListener(createListSelectionListener(getFileChooser())); 573 fileList.addMouseListener(createDoubleClickListener(getFileChooser(), fileList)); 574 fileList.addMouseListener(new MouseAdapter() { 575 public void mouseClicked(MouseEvent e) { 576 JFileChooser chooser = getFileChooser(); 577 if (SwingUtilities.isLeftMouseButton(e) && !chooser.isMultiSelectionEnabled()) { 578 int index = SwingUtilities2.loc2IndexFileList(fileList, e.getPoint()); 579 if (index >= 0) { 580 File file = (File) fileList.getModel().getElementAt(index); 581 setFileName(chooser.getName(file)); 582 } 583 } 584 } 585 }); 586 align(fileList); 587 JScrollPane scrollpane = new JScrollPane(fileList); 588 scrollpane.setPreferredSize(prefListSize); 589 scrollpane.setMaximumSize(MAX_SIZE); 590 align(scrollpane); 591 fileList.setInheritsPopupMenu(true); 592 scrollpane.setInheritsPopupMenu(true); 593 return scrollpane; 594 } 595 596 protected JScrollPane createDirectoryList() { 597 directoryList = new JList(); 598 align(directoryList); 599 600 directoryList.setCellRenderer(new DirectoryCellRenderer()); 601 directoryList.setModel(new MotifDirectoryListModel()); 602 directoryList.getSelectionModel().removeSelectionInterval(0, 0); 603 directoryList.addMouseListener(createDoubleClickListener(getFileChooser(), directoryList)); 604 directoryList.addListSelectionListener(createListSelectionListener(getFileChooser())); 605 directoryList.setInheritsPopupMenu(true); 606 607 JScrollPane scrollpane = new JScrollPane(directoryList); 608 scrollpane.setMaximumSize(MAX_SIZE); 609 scrollpane.setPreferredSize(prefListSize); 610 scrollpane.setInheritsPopupMenu(true); 611 align(scrollpane); 612 return scrollpane; 613 } 614 615 public Dimension getPreferredSize(JComponent c) { 616 Dimension prefSize = 617 (getFileChooser().getAccessory() != null) ? WITH_ACCELERATOR_PREF_SIZE : PREF_SIZE; 618 Dimension d = c.getLayout().preferredLayoutSize(c); 619 if (d != null) { 620 return new Dimension(d.width < prefSize.width ? prefSize.width : d.width, 621 d.height < prefSize.height ? prefSize.height : d.height); 622 } else { 623 return prefSize; 624 } 625 } 626 627 public Dimension getMinimumSize(JComponent x) { 628 return MIN_SIZE; 629 } 630 631 public Dimension getMaximumSize(JComponent x) { 632 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); 633 } 634 635 protected void align(JComponent c) { 636 c.setAlignmentX(JComponent.LEFT_ALIGNMENT); 637 c.setAlignmentY(JComponent.TOP_ALIGNMENT); 638 } 639 640 protected class FileCellRenderer extends DefaultListCellRenderer { 641 public Component getListCellRendererComponent(JList list, Object value, int index, 642 boolean isSelected, boolean cellHasFocus) { 643 644 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 645 setText(getFileChooser().getName((File) value)); 646 setInheritsPopupMenu(true); 647 return this; 648 } 649 } 650 651 protected class DirectoryCellRenderer extends DefaultListCellRenderer { 652 public Component getListCellRendererComponent(JList list, Object value, int index, 653 boolean isSelected, boolean cellHasFocus) { 654 655 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 656 setText(getFileChooser().getName((File) value)); 657 setInheritsPopupMenu(true); 658 return this; 659 } 660 } 661 662 protected class MotifDirectoryListModel extends AbstractListModel implements ListDataListener { 663 public MotifDirectoryListModel() { 664 getModel().addListDataListener(this); 665 } 666 667 public int getSize() { 668 return getModel().getDirectories().size(); 669 } 670 671 public Object getElementAt(int index) { 672 return getModel().getDirectories().elementAt(index); 673 } 674 675 public void intervalAdded(ListDataEvent e) { 676 fireIntervalAdded(this, e.getIndex0(), e.getIndex1()); 677 } 678 679 public void intervalRemoved(ListDataEvent e) { 680 fireIntervalRemoved(this, e.getIndex0(), e.getIndex1()); 681 } 682 683 // PENDING(jeff) - this is inefficient - should sent out 684 // incremental adjustment values instead of saying that the 685 // whole list has changed. 686 public void fireContentsChanged() { 687 fireContentsChanged(this, 0, getModel().getDirectories().size()-1); 688 } 689 690 // PENDING(jeff) - fire the correct interval changed - currently sending 691 // out that everything has changed 692 public void contentsChanged(ListDataEvent e) { 693 fireContentsChanged(); 694 } 695 696 } 697 698 protected class MotifFileListModel extends AbstractListModel implements ListDataListener { 699 public MotifFileListModel() { 700 getModel().addListDataListener(this); 701 } 702 703 public int getSize() { 704 return getModel().getFiles().size(); 705 } 706 707 public boolean contains(Object o) { 708 return getModel().getFiles().contains(o); 709 } 710 711 public int indexOf(Object o) { 712 return getModel().getFiles().indexOf(o); 713 } 714 715 public Object getElementAt(int index) { 716 return getModel().getFiles().elementAt(index); 717 } 718 719 public void intervalAdded(ListDataEvent e) { 720 fireIntervalAdded(this, e.getIndex0(), e.getIndex1()); 721 } 722 723 public void intervalRemoved(ListDataEvent e) { 724 fireIntervalRemoved(this, e.getIndex0(), e.getIndex1()); 725 } 726 727 // PENDING(jeff) - this is inefficient - should sent out 728 // incremental adjustment values instead of saying that the 729 // whole list has changed. 730 public void fireContentsChanged() { 731 fireContentsChanged(this, 0, getModel().getFiles().size()-1); 732 } 733 734 // PENDING(jeff) - fire the interval changed 735 public void contentsChanged(ListDataEvent e) { 736 fireContentsChanged(); 737 } 738 739 } 740 741 // 742 // DataModel for Types Comboxbox 743 // 744 protected FilterComboBoxModel createFilterComboBoxModel() { 745 return new FilterComboBoxModel(); 746 } 747 748 // 749 // Renderer for Types ComboBox 750 // 751 protected FilterComboBoxRenderer createFilterComboBoxRenderer() { 752 return new FilterComboBoxRenderer(); 753 } 754 755 756 /** 757 * Render different type sizes and styles. 758 */ 759 public class FilterComboBoxRenderer extends DefaultListCellRenderer { 760 public Component getListCellRendererComponent(JList list, 761 Object value, int index, boolean isSelected, 762 boolean cellHasFocus) { 763 764 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 765 766 if (value != null && value instanceof FileFilter) { 767 setText(((FileFilter)value).getDescription()); 768 } 769 770 return this; 771 } 772 } 773 774 /** 775 * Data model for a type-face selection combo-box. 776 */ 777 protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener { 778 protected FileFilter[] filters; 779 protected FilterComboBoxModel() { 780 super(); 781 filters = getFileChooser().getChoosableFileFilters(); 782 } 783 784 public void propertyChange(PropertyChangeEvent e) { 785 String prop = e.getPropertyName(); 786 if(prop.equals(JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY)) { 787 filters = (FileFilter[]) e.getNewValue(); 788 fireContentsChanged(this, -1, -1); 789 } else if (prop.equals(JFileChooser.FILE_FILTER_CHANGED_PROPERTY)) { 790 fireContentsChanged(this, -1, -1); 791 } 792 } 793 794 public void setSelectedItem(Object filter) { 795 if(filter != null) { 796 getFileChooser().setFileFilter((FileFilter) filter); 797 fireContentsChanged(this, -1, -1); 798 } 799 } 800 801 public Object getSelectedItem() { 802 // Ensure that the current filter is in the list. 803 // NOTE: we shouldnt' have to do this, since JFileChooser adds 804 // the filter to the choosable filters list when the filter 805 // is set. Lets be paranoid just in case someone overrides 806 // setFileFilter in JFileChooser. 807 FileFilter currentFilter = getFileChooser().getFileFilter(); 808 boolean found = false; 809 if(currentFilter != null) { 810 for (FileFilter filter : filters) { 811 if (filter == currentFilter) { 812 found = true; 813 } 814 } 815 if (!found) { 816 getFileChooser().addChoosableFileFilter(currentFilter); 817 } 818 } 819 return getFileChooser().getFileFilter(); 820 } 821 822 public int getSize() { 823 if(filters != null) { 824 return filters.length; 825 } else { 826 return 0; 827 } 828 } 829 830 public Object getElementAt(int index) { 831 if(index > getSize() - 1) { 832 // This shouldn't happen. Try to recover gracefully. 833 return getFileChooser().getFileFilter(); 834 } 835 if(filters != null) { 836 return filters[index]; 837 } else { 838 return null; 839 } 840 } 841 } 842 843 protected JButton getApproveButton(JFileChooser fc) { 844 return approveButton; 845 } 846 847 }