1. /*
  2. * @(#)MotifFileChooserUI.java 1.39 04/01/13
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.motif;
  8. import javax.swing.*;
  9. import javax.swing.filechooser.*;
  10. import javax.swing.event.*;
  11. import javax.swing.plaf.*;
  12. import javax.swing.plaf.basic.*;
  13. import java.awt.*;
  14. import java.awt.event.*;
  15. import java.beans.*;
  16. import java.io.File;
  17. import java.io.IOException;
  18. import java.util.*;
  19. /**
  20. * Motif FileChooserUI.
  21. *
  22. * @version 1.39 01/13/04
  23. * @author Jeff Dinkins
  24. */
  25. public class MotifFileChooserUI extends BasicFileChooserUI {
  26. private FilterComboBoxModel filterComboBoxModel;
  27. protected JList directoryList = null;
  28. protected JList fileList = null;
  29. protected JTextField pathField = null;
  30. protected JComboBox filterComboBox = null;
  31. protected JTextField filenameTextField = null;
  32. private static final Dimension hstrut10 = new Dimension(10, 1);
  33. private static final Dimension vstrut10 = new Dimension(1, 10);
  34. private static final Insets insets = new Insets(10, 10, 10, 10);
  35. private static Dimension prefListSize = new Dimension(75, 150);
  36. private static Dimension WITH_ACCELERATOR_PREF_SIZE = new Dimension(650, 450);
  37. private static Dimension PREF_SIZE = new Dimension(350, 450);
  38. private static Dimension MIN_SIZE = new Dimension(200, 300);
  39. private static Dimension PREF_ACC_SIZE = new Dimension(10, 10);
  40. private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
  41. private static Dimension MAX_SIZE = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
  42. private static final Insets buttonMargin = new Insets(3, 3, 3, 3);
  43. private JPanel directoryPanel = new JPanel();
  44. protected JButton approveButton;
  45. private String enterFileNameLabelText = null;
  46. private int enterFileNameLabelMnemonic = 0;
  47. private String filesLabelText = null;
  48. private int filesLabelMnemonic = 0;
  49. private String foldersLabelText = null;
  50. private int foldersLabelMnemonic = 0;
  51. private String pathLabelText = null;
  52. private int pathLabelMnemonic = 0;
  53. private String filterLabelText = null;
  54. private int filterLabelMnemonic = 0;
  55. private String fileNameString(File file) {
  56. if (file == null) {
  57. return null;
  58. } else {
  59. JFileChooser fc = getFileChooser();
  60. if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
  61. return file.getPath();
  62. } else {
  63. return file.getName();
  64. }
  65. }
  66. }
  67. private String fileNameString(File[] files) {
  68. StringBuffer buf = new StringBuffer();
  69. for (int i = 0; files != null && i < files.length; i++) {
  70. if (i > 0) {
  71. buf.append(" ");
  72. }
  73. if (files.length > 1) {
  74. buf.append("\"");
  75. }
  76. buf.append(fileNameString(files[i]));
  77. if (files.length > 1) {
  78. buf.append("\"");
  79. }
  80. }
  81. return buf.toString();
  82. }
  83. public MotifFileChooserUI(JFileChooser filechooser) {
  84. super(filechooser);
  85. }
  86. public String getFileName() {
  87. if(filenameTextField != null) {
  88. return filenameTextField.getText();
  89. } else {
  90. return null;
  91. }
  92. }
  93. public void setFileName(String filename) {
  94. if(filenameTextField != null) {
  95. filenameTextField.setText(filename);
  96. }
  97. }
  98. public String getDirectoryName() {
  99. return pathField.getText();
  100. }
  101. public void setDirectoryName(String dirname) {
  102. pathField.setText(dirname);
  103. }
  104. public void ensureFileIsVisible(JFileChooser fc, File f) {
  105. // PENDING(jeff)
  106. }
  107. public void rescanCurrentDirectory(JFileChooser fc) {
  108. // PENDING(jeff)
  109. }
  110. public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
  111. return new PropertyChangeListener() {
  112. public void propertyChange(PropertyChangeEvent e) {
  113. String prop = e.getPropertyName();
  114. if(prop.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
  115. File f = (File) e.getNewValue();
  116. if(f != null) {
  117. setFileName(getFileChooser().getName(f));
  118. }
  119. }
  120. else if (prop.equals(JFileChooser.SELECTED_FILES_CHANGED_PROPERTY)) {
  121. File[] files = (File[]) e.getNewValue();
  122. JFileChooser fc = getFileChooser();
  123. if (files != null && files.length > 0 && (files.length > 1 || fc.isDirectorySelectionEnabled() || !files[0].isDirectory())) {
  124. setFileName(fileNameString(files));
  125. }
  126. } else if(prop.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
  127. directoryList.clearSelection();
  128. fileList.clearSelection();
  129. File currentDirectory = getFileChooser().getCurrentDirectory();
  130. if(currentDirectory != null) {
  131. try {
  132. setDirectoryName(((File)e.getNewValue()).getCanonicalPath());
  133. } catch (IOException ioe) {
  134. setDirectoryName(((File)e.getNewValue()).getAbsolutePath());
  135. }
  136. }
  137. } else if(prop.equals(JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY)) {
  138. directoryList.clearSelection();
  139. } else if(prop == JFileChooser.MULTI_SELECTION_ENABLED_CHANGED_PROPERTY) {
  140. if(getFileChooser().isMultiSelectionEnabled()) {
  141. fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
  142. } else {
  143. fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  144. fileList.clearSelection();
  145. getFileChooser().setSelectedFiles(null);
  146. }
  147. } else if(prop == JFileChooser.ACCESSORY_CHANGED_PROPERTY) {
  148. if(getAccessoryPanel() != null) {
  149. if(e.getOldValue() != null) {
  150. getAccessoryPanel().remove((JComponent) e.getOldValue());
  151. }
  152. JComponent accessory = (JComponent) e.getNewValue();
  153. if(accessory != null) {
  154. getAccessoryPanel().add(accessory, BorderLayout.CENTER);
  155. getAccessoryPanel().setPreferredSize(PREF_ACC_SIZE);
  156. getAccessoryPanel().setMaximumSize(MAX_SIZE);
  157. } else {
  158. getAccessoryPanel().setPreferredSize(ZERO_ACC_SIZE);
  159. getAccessoryPanel().setMaximumSize(ZERO_ACC_SIZE);
  160. }
  161. }
  162. } else if (prop == JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY ||
  163. prop == JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY ||
  164. prop == JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY) {
  165. approveButton.setText(getApproveButtonText(getFileChooser()));
  166. approveButton.setToolTipText(getApproveButtonToolTipText(getFileChooser()));
  167. } else if (prop.equals("componentOrientation")) {
  168. ComponentOrientation o = (ComponentOrientation)e.getNewValue();
  169. JFileChooser cc = (JFileChooser)e.getSource();
  170. if (o != (ComponentOrientation)e.getOldValue()) {
  171. cc.applyComponentOrientation(o);
  172. }
  173. }
  174. }
  175. };
  176. }
  177. //
  178. // ComponentUI Interface Implementation methods
  179. //
  180. public static ComponentUI createUI(JComponent c) {
  181. return new MotifFileChooserUI((JFileChooser)c);
  182. }
  183. public void installUI(JComponent c) {
  184. super.installUI(c);
  185. }
  186. public void uninstallUI(JComponent c) {
  187. getFileChooser().removeAll();
  188. super.uninstallUI(c);
  189. }
  190. public void installComponents(JFileChooser fc) {
  191. fc.setLayout(new BorderLayout(10, 10));
  192. fc.setAlignmentX(JComponent.CENTER_ALIGNMENT);
  193. JPanel interior = new JPanel() {
  194. public Insets getInsets() {
  195. return insets;
  196. }
  197. };
  198. align(interior);
  199. interior.setLayout(new BoxLayout(interior, BoxLayout.PAGE_AXIS));
  200. fc.add(interior, BorderLayout.CENTER);
  201. // PENDING(jeff) - I18N
  202. JLabel l = new JLabel(pathLabelText);
  203. l.setDisplayedMnemonic(pathLabelMnemonic);
  204. align(l);
  205. interior.add(l);
  206. File currentDirectory = fc.getCurrentDirectory();
  207. String curDirName = null;
  208. if(currentDirectory != null) {
  209. curDirName = currentDirectory.getPath();
  210. }
  211. pathField = new JTextField(curDirName) {
  212. public Dimension getMaximumSize() {
  213. Dimension d = super.getMaximumSize();
  214. d.height = getPreferredSize().height;
  215. return d;
  216. }
  217. };
  218. l.setLabelFor(pathField);
  219. align(pathField);
  220. // Change to folder on return
  221. pathField.addActionListener(getUpdateAction());
  222. interior.add(pathField);
  223. interior.add(Box.createRigidArea(vstrut10));
  224. // CENTER: left, right accessory
  225. JPanel centerPanel = new JPanel();
  226. centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.LINE_AXIS));
  227. align(centerPanel);
  228. // left panel - Filter & folderList
  229. JPanel leftPanel = new JPanel();
  230. leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
  231. align(leftPanel);
  232. // add the filter PENDING(jeff) - I18N
  233. l = new JLabel(filterLabelText);
  234. l.setDisplayedMnemonic(filterLabelMnemonic);
  235. align(l);
  236. leftPanel.add(l);
  237. filterComboBox = new JComboBox() {
  238. public Dimension getMaximumSize() {
  239. Dimension d = super.getMaximumSize();
  240. d.height = getPreferredSize().height;
  241. return d;
  242. }
  243. };
  244. l.setLabelFor(filterComboBox);
  245. filterComboBoxModel = createFilterComboBoxModel();
  246. filterComboBox.setModel(filterComboBoxModel);
  247. filterComboBox.setRenderer(createFilterComboBoxRenderer());
  248. fc.addPropertyChangeListener(filterComboBoxModel);
  249. align(filterComboBox);
  250. leftPanel.add(filterComboBox);
  251. // leftPanel.add(Box.createRigidArea(vstrut10));
  252. // Add the Folder List PENDING(jeff) - I18N
  253. l = new JLabel(foldersLabelText);
  254. l.setDisplayedMnemonic(foldersLabelMnemonic);
  255. align(l);
  256. leftPanel.add(l);
  257. JScrollPane sp = createDirectoryList();
  258. sp.getVerticalScrollBar().setFocusable(false);
  259. sp.getHorizontalScrollBar().setFocusable(false);
  260. l.setLabelFor(sp.getViewport().getView());
  261. leftPanel.add(sp);
  262. // create files list
  263. JPanel rightPanel = new JPanel();
  264. align(rightPanel);
  265. rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.PAGE_AXIS));
  266. l = new JLabel(filesLabelText);
  267. l.setDisplayedMnemonic(filesLabelMnemonic);
  268. align(l);
  269. rightPanel.add(l);
  270. sp = createFilesList();
  271. l.setLabelFor(sp);
  272. rightPanel.add(sp);
  273. centerPanel.add(leftPanel);
  274. centerPanel.add(Box.createRigidArea(hstrut10));
  275. centerPanel.add(rightPanel);
  276. JComponent accessoryPanel = getAccessoryPanel();
  277. JComponent accessory = fc.getAccessory();
  278. if(accessoryPanel != null) {
  279. if(accessory == null) {
  280. accessoryPanel.setPreferredSize(ZERO_ACC_SIZE);
  281. accessoryPanel.setMaximumSize(ZERO_ACC_SIZE);
  282. } else {
  283. getAccessoryPanel().add(accessory, BorderLayout.CENTER);
  284. accessoryPanel.setPreferredSize(PREF_ACC_SIZE);
  285. accessoryPanel.setMaximumSize(MAX_SIZE);
  286. }
  287. align(accessoryPanel);
  288. centerPanel.add(accessoryPanel);
  289. }
  290. interior.add(centerPanel);
  291. interior.add(Box.createRigidArea(vstrut10));
  292. // add the filename field PENDING(jeff) - I18N
  293. l = new JLabel(enterFileNameLabelText);
  294. l.setDisplayedMnemonic(enterFileNameLabelMnemonic);
  295. align(l);
  296. interior.add(l);
  297. filenameTextField = new JTextField() {
  298. public Dimension getMaximumSize() {
  299. Dimension d = super.getMaximumSize();
  300. d.height = getPreferredSize().height;
  301. return d;
  302. }
  303. };
  304. l.setLabelFor(filenameTextField);
  305. filenameTextField.addActionListener(getApproveSelectionAction());
  306. align(filenameTextField);
  307. filenameTextField.setAlignmentX(JComponent.LEFT_ALIGNMENT);
  308. interior.add(filenameTextField);
  309. JPanel bottomPanel = new JPanel(new BorderLayout(0, 4));
  310. bottomPanel.add(new JSeparator(), BorderLayout.NORTH);
  311. // Add buttons
  312. JPanel buttonPanel = new JPanel();
  313. align(buttonPanel);
  314. buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
  315. buttonPanel.add(Box.createGlue());
  316. approveButton = new JButton(getApproveButtonText(fc)) {
  317. public Dimension getMaximumSize() {
  318. return new Dimension(MAX_SIZE.width, this.getPreferredSize().height);
  319. }
  320. };
  321. approveButton.setMnemonic(getApproveButtonMnemonic(fc));
  322. approveButton.setToolTipText(getApproveButtonToolTipText(fc));
  323. align(approveButton);
  324. approveButton.setMargin(buttonMargin);
  325. approveButton.addActionListener(getApproveSelectionAction());
  326. buttonPanel.add(approveButton);
  327. buttonPanel.add(Box.createGlue());
  328. JButton updateButton = new JButton(updateButtonText) {
  329. public Dimension getMaximumSize() {
  330. return new Dimension(MAX_SIZE.width, this.getPreferredSize().height);
  331. }
  332. };
  333. updateButton.setMnemonic(updateButtonMnemonic);
  334. updateButton.setToolTipText(updateButtonToolTipText);
  335. align(updateButton);
  336. updateButton.setMargin(buttonMargin);
  337. updateButton.addActionListener(getUpdateAction());
  338. buttonPanel.add(updateButton);
  339. buttonPanel.add(Box.createGlue());
  340. JButton cancelButton = new JButton(cancelButtonText) {
  341. public Dimension getMaximumSize() {
  342. return new Dimension(MAX_SIZE.width, this.getPreferredSize().height);
  343. }
  344. };
  345. cancelButton.setMnemonic(cancelButtonMnemonic);
  346. cancelButton.setToolTipText(cancelButtonToolTipText);
  347. align(cancelButton);
  348. cancelButton.setMargin(buttonMargin);
  349. cancelButton.addActionListener(getCancelSelectionAction());
  350. buttonPanel.add(cancelButton);
  351. buttonPanel.add(Box.createGlue());
  352. JButton helpButton = new JButton(helpButtonText) {
  353. public Dimension getMaximumSize() {
  354. return new Dimension(MAX_SIZE.width, this.getPreferredSize().height);
  355. }
  356. };
  357. helpButton.setMnemonic(helpButtonMnemonic);
  358. helpButton.setToolTipText(helpButtonToolTipText);
  359. align(helpButton);
  360. helpButton.setMargin(buttonMargin);
  361. helpButton.setEnabled(false);
  362. buttonPanel.add(helpButton);
  363. buttonPanel.add(Box.createGlue());
  364. bottomPanel.add(buttonPanel, BorderLayout.SOUTH);
  365. fc.add(bottomPanel, BorderLayout.SOUTH);
  366. }
  367. public void uninstallComponents(JFileChooser fc) {
  368. fc.removeAll();
  369. }
  370. protected void installStrings(JFileChooser fc) {
  371. super.installStrings(fc);
  372. Locale l = fc.getLocale();
  373. enterFileNameLabelText = UIManager.getString("FileChooser.enterFileNameLabelText",l);
  374. enterFileNameLabelMnemonic = UIManager.getInt("FileChooser.enterFileNameLabelMnemonic");
  375. filesLabelText = UIManager.getString("FileChooser.filesLabelText",l);
  376. filesLabelMnemonic = UIManager.getInt("FileChooser.filesLabelMnemonic");
  377. foldersLabelText = UIManager.getString("FileChooser.foldersLabelText",l);
  378. foldersLabelMnemonic = UIManager.getInt("FileChooser.foldersLabelMnemonic");
  379. pathLabelText = UIManager.getString("FileChooser.pathLabelText",l);
  380. pathLabelMnemonic = UIManager.getInt("FileChooser.pathLabelMnemonic");
  381. filterLabelText = UIManager.getString("FileChooser.filterLabelText",l);
  382. filterLabelMnemonic = UIManager.getInt("FileChooser.filterLabelMnemonic");
  383. }
  384. protected void installIcons(JFileChooser fc) {
  385. // Since motif doesn't have button icons, leave this empty
  386. // which overrides the supertype icon loading
  387. }
  388. protected void uninstallIcons(JFileChooser fc) {
  389. // Since motif doesn't have button icons, leave this empty
  390. // which overrides the supertype icon loading
  391. }
  392. protected JScrollPane createFilesList() {
  393. fileList = new JList();
  394. if(getFileChooser().isMultiSelectionEnabled()) {
  395. fileList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
  396. } else {
  397. fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  398. }
  399. fileList.setModel(new MotifFileListModel());
  400. fileList.setCellRenderer(new FileCellRenderer());
  401. fileList.addListSelectionListener(createListSelectionListener(getFileChooser()));
  402. fileList.addMouseListener(createDoubleClickListener(getFileChooser(), fileList));
  403. align(fileList);
  404. JScrollPane scrollpane = new JScrollPane(fileList);
  405. scrollpane.setPreferredSize(prefListSize);
  406. scrollpane.setMaximumSize(MAX_SIZE);
  407. align(scrollpane);
  408. return scrollpane;
  409. }
  410. protected JScrollPane createDirectoryList() {
  411. directoryList = new JList();
  412. align(directoryList);
  413. directoryList.setCellRenderer(new DirectoryCellRenderer());
  414. directoryList.setModel(new MotifDirectoryListModel());
  415. directoryList.addMouseListener(createDoubleClickListener(getFileChooser(), directoryList));
  416. directoryList.addListSelectionListener(createListSelectionListener(getFileChooser()));
  417. JScrollPane scrollpane = new JScrollPane(directoryList);
  418. scrollpane.setMaximumSize(MAX_SIZE);
  419. scrollpane.setPreferredSize(prefListSize);
  420. align(scrollpane);
  421. return scrollpane;
  422. }
  423. public Dimension getPreferredSize(JComponent c) {
  424. Dimension prefSize =
  425. (getFileChooser().getAccessory() != null) ? WITH_ACCELERATOR_PREF_SIZE : PREF_SIZE;
  426. Dimension d = c.getLayout().preferredLayoutSize(c);
  427. if (d != null) {
  428. return new Dimension(d.width < prefSize.width ? prefSize.width : d.width,
  429. d.height < prefSize.height ? prefSize.height : d.height);
  430. } else {
  431. return prefSize;
  432. }
  433. }
  434. public Dimension getMinimumSize(JComponent x) {
  435. return MIN_SIZE;
  436. }
  437. public Dimension getMaximumSize(JComponent x) {
  438. return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  439. }
  440. protected void align(JComponent c) {
  441. c.setAlignmentX(JComponent.LEFT_ALIGNMENT);
  442. c.setAlignmentY(JComponent.TOP_ALIGNMENT);
  443. }
  444. protected class FileCellRenderer extends DefaultListCellRenderer {
  445. public Component getListCellRendererComponent(JList list, Object value, int index,
  446. boolean isSelected, boolean cellHasFocus) {
  447. super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
  448. setText(getFileChooser().getName((File) value));
  449. return this;
  450. }
  451. }
  452. protected class DirectoryCellRenderer extends DefaultListCellRenderer {
  453. public Component getListCellRendererComponent(JList list, Object value, int index,
  454. boolean isSelected, boolean cellHasFocus) {
  455. super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
  456. setText(getFileChooser().getName((File) value));
  457. return this;
  458. }
  459. }
  460. protected class MotifDirectoryListModel extends AbstractListModel implements ListDataListener {
  461. public MotifDirectoryListModel() {
  462. getModel().addListDataListener(this);
  463. }
  464. public int getSize() {
  465. return getModel().getDirectories().size();
  466. }
  467. public Object getElementAt(int index) {
  468. return getModel().getDirectories().elementAt(index);
  469. }
  470. public void intervalAdded(ListDataEvent e) {
  471. }
  472. // PENDING(jeff) - implement
  473. public void intervalRemoved(ListDataEvent e) {
  474. }
  475. // PENDING(jeff) - this is inefficient - should sent out
  476. // incremental adjustment values instead of saying that the
  477. // whole list has changed.
  478. public void fireContentsChanged() {
  479. fireContentsChanged(this, 0, getModel().getDirectories().size()-1);
  480. }
  481. // PENDING(jeff) - fire the correct interval changed - currently sending
  482. // out that everything has changed
  483. public void contentsChanged(ListDataEvent e) {
  484. fireContentsChanged();
  485. }
  486. }
  487. protected class MotifFileListModel extends AbstractListModel implements ListDataListener {
  488. public MotifFileListModel() {
  489. getModel().addListDataListener(this);
  490. }
  491. public int getSize() {
  492. return getModel().getFiles().size();
  493. }
  494. public boolean contains(Object o) {
  495. return getModel().getFiles().contains(o);
  496. }
  497. public int indexOf(Object o) {
  498. return getModel().getFiles().indexOf(o);
  499. }
  500. public Object getElementAt(int index) {
  501. return getModel().getFiles().elementAt(index);
  502. }
  503. public void intervalAdded(ListDataEvent e) {
  504. }
  505. // PENDING(jeff) - implement
  506. public void intervalRemoved(ListDataEvent e) {
  507. }
  508. // PENDING(jeff) - this is inefficient - should sent out
  509. // incremental adjustment values instead of saying that the
  510. // whole list has changed.
  511. public void fireContentsChanged() {
  512. fireContentsChanged(this, 0, getModel().getFiles().size()-1);
  513. }
  514. // PENDING(jeff) - fire the interval changed
  515. public void contentsChanged(ListDataEvent e) {
  516. fireContentsChanged();
  517. }
  518. }
  519. //
  520. // DataModel for Types Comboxbox
  521. //
  522. protected FilterComboBoxModel createFilterComboBoxModel() {
  523. return new FilterComboBoxModel();
  524. }
  525. //
  526. // Renderer for Types ComboBox
  527. //
  528. protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
  529. return new FilterComboBoxRenderer();
  530. }
  531. /**
  532. * Render different type sizes and styles.
  533. */
  534. public class FilterComboBoxRenderer extends DefaultListCellRenderer {
  535. public Component getListCellRendererComponent(JList list,
  536. Object value, int index, boolean isSelected,
  537. boolean cellHasFocus) {
  538. super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
  539. if (value != null && value instanceof FileFilter) {
  540. setText(((FileFilter)value).getDescription());
  541. }
  542. return this;
  543. }
  544. }
  545. /**
  546. * Data model for a type-face selection combo-box.
  547. */
  548. protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
  549. protected FileFilter[] filters;
  550. protected FilterComboBoxModel() {
  551. super();
  552. filters = getFileChooser().getChoosableFileFilters();
  553. }
  554. public void propertyChange(PropertyChangeEvent e) {
  555. String prop = e.getPropertyName();
  556. if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
  557. filters = (FileFilter[]) e.getNewValue();
  558. fireContentsChanged(this, -1, -1);
  559. }
  560. }
  561. public void setSelectedItem(Object filter) {
  562. if(filter != null) {
  563. getFileChooser().setFileFilter((FileFilter) filter);
  564. fireContentsChanged(this, -1, -1);
  565. }
  566. }
  567. public Object getSelectedItem() {
  568. // Ensure that the current filter is in the list.
  569. // NOTE: we shouldnt' have to do this, since JFileChooser adds
  570. // the filter to the choosable filters list when the filter
  571. // is set. Lets be paranoid just in case someone overrides
  572. // setFileFilter in JFileChooser.
  573. FileFilter currentFilter = getFileChooser().getFileFilter();
  574. boolean found = false;
  575. if(currentFilter != null) {
  576. for(int i=0; i < filters.length; i++) {
  577. if(filters[i] == currentFilter) {
  578. found = true;
  579. }
  580. }
  581. if(found == false) {
  582. getFileChooser().addChoosableFileFilter(currentFilter);
  583. }
  584. }
  585. return getFileChooser().getFileFilter();
  586. }
  587. public int getSize() {
  588. if(filters != null) {
  589. return filters.length;
  590. } else {
  591. return 0;
  592. }
  593. }
  594. public Object getElementAt(int index) {
  595. if(index > getSize() - 1) {
  596. // This shouldn't happen. Try to recover gracefully.
  597. return getFileChooser().getFileFilter();
  598. }
  599. if(filters != null) {
  600. return filters[index];
  601. } else {
  602. return null;
  603. }
  604. }
  605. }
  606. protected JButton getApproveButton(JFileChooser fc) {
  607. return approveButton;
  608. }
  609. }