if (cmd == ACTION_CANCEL) { return getFileChooser().isEnabled(); } else if (cmd == ACTION_EDIT_FILE_NAME) { return !readOnly && getFileChooser().isEnabled(); } else { return true; } } } ArrayList<Action> actionList = new ArrayList<Action>(8); Action action; actionList.add(new FilePaneAction(ACTION_CANCEL)); actionList.add(new FilePaneAction(ACTION_EDIT_FILE_NAME)); actionList.add(new FilePaneAction(refreshActionLabelText, ACTION_REFRESH)); action = fileChooserUIAccessor.getApproveSelectionAction(); if (action != null) { actionList.add(action); } action = fileChooserUIAccessor.getChangeToParentDirectoryAction(); if (action != null) { actionList.add(action); } action = getNewFolderAction(); if (action != null) { actionList.add(action); } action = getViewTypeAction(VIEWTYPE_LIST); if (action != null) { actionList.add(action); } action = getViewTypeAction(VIEWTYPE_DETAILS); if (action != null) { actionList.add(action); } actions = actionList.toArray(new Action[actionList.size()]); } return actions; } protected void createActionMap() { addActionsToMap(super.getActionMap(), getActions()); } public static void addActionsToMap(ActionMap map, Action[] actions) { if (map != null && actions != null) { for (Action a : actions) { String cmd = (String)a.getValue(Action.ACTION_COMMAND_KEY); if (cmd == null) { cmd = (String)a.getValue(Action.NAME); } map.put(cmd, a); } } } private void updateListRowCount(JList list) { if (smallIconsView) { list.setVisibleRowCount(getModel().getSize() / 3); } else { list.setVisibleRowCount(-1); } } public JPanel createList() { JPanel p = new JPanel(new BorderLayout()); final JFileChooser fileChooser = getFileChooser(); final JList list = new JList() { public int getNextMatch(String prefix, int startIndex, Position.Bias bias) { ListModel model = getModel(); int max = model.getSize(); if (prefix == null || startIndex < 0 || startIndex >= max) { throw new IllegalArgumentException(); } // start search from the next element before/after the selected element boolean backwards = (bias == Position.Bias.Backward); for (int i = startIndex; backwards ? i >= 0 : i < max; i += (backwards ? -1 : 1)) { String filename = fileChooser.getName((File)model.getElementAt(i)); if (filename.regionMatches(true, 0, prefix, 0, prefix.length())) { return i; } } return -1; } }; list.setCellRenderer(new FileRenderer()); list.setLayoutOrientation(JList.VERTICAL_WRAP); // 4835633 : tell BasicListUI that this is a file list list.putClientProperty("List.isFileList", Boolean.TRUE); if (listViewWindowsStyle) { list.addFocusListener(repaintListener); } updateListRowCount(list); getModel().addListDataListener(new ListDataListener() { public void intervalAdded(ListDataEvent e) { updateListRowCount(list); } public void intervalRemoved(ListDataEvent e) { updateListRowCount(list); } public void contentsChanged(ListDataEvent e) { if (isShowing()) { clearSelection(); } updateListRowCount(list); } }); getModel().addPropertyChangeListener(this); if (fileChooser.isMultiSelectionEnabled()) { list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); } else { list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } list.setModel(new SortableListModel()); list.addListSelectionListener(createListSelectionListener()); list.addMouseListener(getMouseHandler()); JScrollPane scrollpane = new JScrollPane(list); if (listViewBackground != null) { list.setBackground(listViewBackground); } if (listViewBorder != null) { scrollpane.setBorder(listViewBorder); } p.add(scrollpane, BorderLayout.CENTER); return p; } /** * This model allows for sorting JList */ private class SortableListModel extends AbstractListModel implements TableModelListener, RowSorterListener { public SortableListModel() { getDetailsTableModel().addTableModelListener(this); getRowSorter().addRowSorterListener(this); } public int getSize() { return getModel().getSize(); } public Object getElementAt(int index) { // JList doesn't support RowSorter so far, so we put it into the list model return getModel().getElementAt(getRowSorter().convertRowIndexToModel(index)); } public void tableChanged(TableModelEvent e) { fireContentsChanged(this, 0, getSize()); } public void sorterChanged(RowSorterEvent e) { fireContentsChanged(this, 0, getSize()); } } private DetailsTableModel getDetailsTableModel() { if(detailsTableModel == null) { detailsTableModel = new DetailsTableModel(getFileChooser()); } return detailsTableModel; } class DetailsTableModel extends AbstractTableModel implements ListDataListener { JFileChooser chooser; BasicDirectoryModel directoryModel; ShellFolderColumnInfo[] columns; int[] columnMap; DetailsTableModel(JFileChooser fc) { this.chooser = fc; directoryModel = getModel(); directoryModel.addListDataListener(this); updateColumnInfo(); } void updateColumnInfo() { File dir = chooser.getCurrentDirectory(); if (dir != null && usesShellFolder(chooser)) { try { dir = ShellFolder.getShellFolder(dir); } catch (FileNotFoundException e) { // Leave dir without changing } } ShellFolderColumnInfo[] allColumns = ShellFolder.getFolderColumns(dir); ArrayList<ShellFolderColumnInfo> visibleColumns = new ArrayList<ShellFolderColumnInfo>(); columnMap = new int[allColumns.length]; for (int i = 0; i < allColumns.length; i++) { ShellFolderColumnInfo column = allColumns[i]; if (column.isVisible()) { columnMap[visibleColumns.size()] = i; visibleColumns.add(column); } } columns = new ShellFolderColumnInfo[visibleColumns.size()]; visibleColumns.toArray(columns); columnMap = Arrays.copyOf(columnMap, columns.length); List<? extends RowSorter.SortKey> sortKeys = (rowSorter == null) ? null : rowSorter.getSortKeys(); fireTableStructureChanged(); restoreSortKeys(sortKeys); } private void restoreSortKeys(List<? extends RowSorter.SortKey> sortKeys) { if (sortKeys != null) { // check if preserved sortKeys are valid for this folder for (int i = 0; i < sortKeys.size(); i++) { RowSorter.SortKey sortKey = sortKeys.get(i); if (sortKey.getColumn() >= columns.length) { sortKeys = null; break; } } if (sortKeys != null) { rowSorter.setSortKeys(sortKeys); } } } public int getRowCount() { return directoryModel.getSize(); } public int getColumnCount() { return columns.length; } public Object getValueAt(int row, int col) { // Note: It is very important to avoid getting info on drives, as // this will trigger "No disk in A:" and similar dialogs. // // Use (f.exists() && !chooser.getFileSystemView().isFileSystemRoot(f)) to // determine if it is safe to call methods directly on f. return getFileColumnValue((File)directoryModel.getElementAt(row), col); } private Object getFileColumnValue(File f, int col) { return (col == COLUMN_FILENAME) ? f // always return the file itself for the 1st column : ShellFolder.getFolderColumnValue(f, columnMap[col]); } public void setValueAt(Object value, int row, int col) { if (col == COLUMN_FILENAME) { final JFileChooser chooser = getFileChooser(); File f = (File)getValueAt(row, col); if (f != null) { String oldDisplayName = chooser.getName(f); String oldFileName = f.getName(); String newDisplayName = ((String)value).trim(); String newFileName; if (!newDisplayName.equals(oldDisplayName)) { newFileName = newDisplayName; //Check if extension is hidden from user int i1 = oldFileName.length(); int i2 = oldDisplayName.length(); if (i1 > i2 && oldFileName.charAt(i2) == '.') { newFileName = newDisplayName + oldFileName.substring(i2); } // rename FileSystemView fsv = chooser.getFileSystemView(); final File f2 = fsv.createFileObject(f.getParentFile(), newFileName); if (f2.exists()) { JOptionPane.showMessageDialog(chooser, MessageFormat.format(renameErrorFileExistsText, oldFileName), renameErrorTitleText, JOptionPane.ERROR_MESSAGE); } else { if (FilePane.this.getModel().renameFile(f, f2)) { if (fsv.isParent(chooser.getCurrentDirectory(), f2)) { // The setSelectedFile method produces a new setValueAt invocation while the JTable // is editing. Postpone file selection to be sure that edit mode of the JTable // is completed SwingUtilities.invokeLater(new Runnable() { public void run() { if (chooser.isMultiSelectionEnabled()) { chooser.setSelectedFiles(new File[]{f2}); } else { chooser.setSelectedFile(f2); } } }); } else { // Could be because of delay in updating Desktop folder // chooser.setSelectedFile(null); } } else { JOptionPane.showMessageDialog(chooser, MessageFormat.format(renameErrorText, oldFileName), renameErrorTitleText, JOptionPane.ERROR_MESSAGE); } } } } } } public boolean isCellEditable(int row, int column) { File currentDirectory = getFileChooser().getCurrentDirectory(); return (!readOnly && column == COLUMN_FILENAME && canWrite(currentDirectory)); } public void contentsChanged(ListDataEvent e) { // Update the selection after the model has been updated new DelayedSelectionUpdater(); fireTableDataChanged(); } public void intervalAdded(ListDataEvent e) { int i0 = e.getIndex0(); int i1 = e.getIndex1(); if (i0 == i1) { File file = (File)getModel().getElementAt(i0); if (file.equals(newFolderFile)) { new DelayedSelectionUpdater(file); newFolderFile = null; } } fireTableRowsInserted(e.getIndex0(), e.getIndex1()); } public void intervalRemoved(ListDataEvent e) { fireTableRowsDeleted(e.getIndex0(), e.getIndex1()); } public ShellFolderColumnInfo[] getColumns() { return columns; } } private void updateDetailsColumnModel(JTable table) { if (table != null) { ShellFolderColumnInfo[] columns = detailsTableModel.getColumns(); TableColumnModel columnModel = new DefaultTableColumnModel(); for (int i = 0; i < columns.length; i++) { ShellFolderColumnInfo dataItem = columns[i]; TableColumn column = new TableColumn(i); String title = dataItem.getTitle(); if (title != null && title.startsWith("FileChooser.") && title.endsWith("HeaderText")) { // the column must have a string resource that we try to get String uiTitle = UIManager.getString(title, table.getLocale()); if (uiTitle != null) { title = uiTitle; } } column.setHeaderValue(title); Integer width = dataItem.getWidth(); if (width != null) { column.setPreferredWidth(width); // otherwise we let JTable to decide the actual width } columnModel.addColumn(column); } // Install cell editor for editing file name if (!readOnly && columnModel.getColumnCount() > COLUMN_FILENAME) { columnModel.getColumn(COLUMN_FILENAME). setCellEditor(getDetailsTableCellEditor()); } table.setColumnModel(columnModel); } } private DetailsTableRowSorter getRowSorter() { if (rowSorter == null) { rowSorter = new DetailsTableRowSorter(); } return rowSorter; } private class DetailsTableRowSorter extends TableRowSorter<TableModel> { public DetailsTableRowSorter() { setModelWrapper(new SorterModelWrapper()); } public void updateComparators(ShellFolderColumnInfo [] columns) { for (int i = 0; i < columns.length; i++) { Comparator c = columns[i].getComparator(); if (c != null) { c = new DirectoriesFirstComparatorWrapper(i, c); } setComparator(i, c); } } @Override public void sort() { ShellFolder.invoke(new Callable<Void>() { public Void call() { DetailsTableRowSorter.super.sort(); return null; } }); } public void modelStructureChanged() { super.modelStructureChanged(); updateComparators(detailsTableModel.getColumns()); } private class SorterModelWrapper extends ModelWrapper<TableModel, Integer> { public TableModel getModel() { return getDetailsTableModel(); } public int getColumnCount() { return getDetailsTableModel().getColumnCount(); } public int getRowCount() { return getDetailsTableModel().getRowCount(); } public Object getValueAt(int row, int column) { return FilePane.this.getModel().getElementAt(row); } public Integer getIdentifier(int row) { return row; } } } /** * This class sorts directories before files, comparing directory to * directory and file to file using the wrapped comparator. */ private class DirectoriesFirstComparatorWrapper implements Comparator<File> { private Comparator comparator; private int column; public DirectoriesFirstComparatorWrapper(int column, Comparator comparator) { this.column = column; this.comparator = comparator; } public int compare(File f1, File f2) { if (f1 != null && f2 != null) { boolean traversable1 = getFileChooser().isTraversable(f1); boolean traversable2 = getFileChooser().isTraversable(f2); // directories go first if (traversable1 && !traversable2) { return -1; } if (!traversable1 && traversable2) { return 1; } } if (detailsTableModel.getColumns()[column].isCompareByColumn()) { return comparator.compare( getDetailsTableModel().getFileColumnValue(f1, column), getDetailsTableModel().getFileColumnValue(f2, column) ); } // For this column we need to pass the file itself (not a // column value) to the comparator return comparator.compare(f1, f2); } } private DetailsTableCellEditor tableCellEditor; private DetailsTableCellEditor getDetailsTableCellEditor() { if (tableCellEditor == null) { tableCellEditor = new DetailsTableCellEditor(new JTextField()); } return tableCellEditor; } private class DetailsTableCellEditor extends DefaultCellEditor { private final JTextField tf; public DetailsTableCellEditor(JTextField tf) { super(tf);Lines 501–1000 of 2012. Previous lines Load more
if (cmd == ACTION_CANCEL) { return getFileChooser().isEnabled(); } else if (cmd == ACTION_EDIT_FILE_NAME) { return !readOnly && getFileChooser().isEnabled(); } else { return true; } } } ArrayList<Action> actionList = new ArrayList<Action>(8); Action action; actionList.add(new FilePaneAction(ACTION_CANCEL)); actionList.add(new FilePaneAction(ACTION_EDIT_FILE_NAME)); actionList.add(new FilePaneAction(refreshActionLabelText, ACTION_REFRESH)); action = fileChooserUIAccessor.getApproveSelectionAction(); if (action != null) { actionList.add(action); } action = fileChooserUIAccessor.getChangeToParentDirectoryAction(); if (action != null) { actionList.add(action); } action = getNewFolderAction(); if (action != null) { actionList.add(action); } action = getViewTypeAction(VIEWTYPE_LIST); if (action != null) { actionList.add(action); } action = getViewTypeAction(VIEWTYPE_DETAILS); if (action != null) { actionList.add(action); } actions = actionList.toArray(new Action[actionList.size()]); } return actions; } protected void createActionMap() { addActionsToMap(super.getActionMap(), getActions()); } public static void addActionsToMap(ActionMap map, Action[] actions) { if (map != null && actions != null) { for (Action a : actions) { String cmd = (String)a.getValue(Action.ACTION_COMMAND_KEY); if (cmd == null) { cmd = (String)a.getValue(Action.NAME); } map.put(cmd, a); } } } private void updateListRowCount(JList list) { if (smallIconsView) { list.setVisibleRowCount(getModel().getSize() / 3); } else { list.setVisibleRowCount(-1); } } public JPanel createList() { JPanel p = new JPanel(new BorderLayout()); final JFileChooser fileChooser = getFileChooser(); final JList list = new JList() { public int getNextMatch(String prefix, int startIndex, Position.Bias bias) { ListModel model = getModel(); int max = model.getSize(); if (prefix == null || startIndex < 0 || startIndex >= max) { throw new IllegalArgumentException(); } // start search from the next element before/after the selected element boolean backwards = (bias == Position.Bias.Backward); for (int i = startIndex; backwards ? i >= 0 : i < max; i += (backwards ? -1 : 1)) { String filename = fileChooser.getName((File)model.getElementAt(i)); if (filename.regionMatches(true, 0, prefix, 0, prefix.length())) { return i; } } return -1; } }; list.setCellRenderer(new FileRenderer()); list.setLayoutOrientation(JList.VERTICAL_WRAP); // 4835633 : tell BasicListUI that this is a file list list.putClientProperty("List.isFileList", Boolean.TRUE); if (listViewWindowsStyle) { list.addFocusListener(repaintListener); } updateListRowCount(list); getModel().addListDataListener(new ListDataListener() { public void intervalAdded(ListDataEvent e) { updateListRowCount(list); } public void intervalRemoved(ListDataEvent e) { updateListRowCount(list); } public void contentsChanged(ListDataEvent e) { if (isShowing()) { clearSelection(); } updateListRowCount(list); } }); getModel().addPropertyChangeListener(this); if (fileChooser.isMultiSelectionEnabled()) { list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); } else { list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } list.setModel(new SortableListModel()); list.addListSelectionListener(createListSelectionListener()); list.addMouseListener(getMouseHandler()); JScrollPane scrollpane = new JScrollPane(list); if (listViewBackground != null) { list.setBackground(listViewBackground); } if (listViewBorder != null) { scrollpane.setBorder(listViewBorder); } p.add(scrollpane, BorderLayout.CENTER); return p; } /** * This model allows for sorting JList */ private class SortableListModel extends AbstractListModel implements TableModelListener, RowSorterListener { public SortableListModel() { getDetailsTableModel().addTableModelListener(this); getRowSorter().addRowSorterListener(this); } public int getSize() { return getModel().getSize(); } public Object getElementAt(int index) { // JList doesn't support RowSorter so far, so we put it into the list model return getModel().getElementAt(getRowSorter().convertRowIndexToModel(index)); } public void tableChanged(TableModelEvent e) { fireContentsChanged(this, 0, getSize()); } public void sorterChanged(RowSorterEvent e) { fireContentsChanged(this, 0, getSize()); } } private DetailsTableModel getDetailsTableModel() { if(detailsTableModel == null) { detailsTableModel = new DetailsTableModel(getFileChooser()); } return detailsTableModel; } class DetailsTableModel extends AbstractTableModel implements ListDataListener { JFileChooser chooser; BasicDirectoryModel directoryModel; ShellFolderColumnInfo[] columns; int[] columnMap; DetailsTableModel(JFileChooser fc) { this.chooser = fc; directoryModel = getModel(); directoryModel.addListDataListener(this); updateColumnInfo(); } void updateColumnInfo() { File dir = chooser.getCurrentDirectory(); if (dir != null && usesShellFolder(chooser)) { try { dir = ShellFolder.getShellFolder(dir); } catch (FileNotFoundException e) { // Leave dir without changing } } ShellFolderColumnInfo[] allColumns = ShellFolder.getFolderColumns(dir); ArrayList<ShellFolderColumnInfo> visibleColumns = new ArrayList<ShellFolderColumnInfo>(); columnMap = new int[allColumns.length]; for (int i = 0; i < allColumns.length; i++) { ShellFolderColumnInfo column = allColumns[i]; if (column.isVisible()) { columnMap[visibleColumns.size()] = i; visibleColumns.add(column); } } columns = new ShellFolderColumnInfo[visibleColumns.size()]; visibleColumns.toArray(columns); columnMap = Arrays.copyOf(columnMap, columns.length); List<? extends RowSorter.SortKey> sortKeys = (rowSorter == null) ? null : rowSorter.getSortKeys(); fireTableStructureChanged(); restoreSortKeys(sortKeys); } private void restoreSortKeys(List<? extends RowSorter.SortKey> sortKeys) { if (sortKeys != null) { // check if preserved sortKeys are valid for this folder for (int i = 0; i < sortKeys.size(); i++) { RowSorter.SortKey sortKey = sortKeys.get(i); if (sortKey.getColumn() >= columns.length) { sortKeys = null; break; } } if (sortKeys != null) { rowSorter.setSortKeys(sortKeys); } } } public int getRowCount() { return directoryModel.getSize(); } public int getColumnCount() { return columns.length; } public Object getValueAt(int row, int col) { // Note: It is very important to avoid getting info on drives, as // this will trigger "No disk in A:" and similar dialogs. // // Use (f.exists() && !chooser.getFileSystemView().isFileSystemRoot(f)) to // determine if it is safe to call methods directly on f. return getFileColumnValue((File)directoryModel.getElementAt(row), col); } private Object getFileColumnValue(File f, int col) { return (col == COLUMN_FILENAME) ? f // always return the file itself for the 1st column : ShellFolder.getFolderColumnValue(f, columnMap[col]); } public void setValueAt(Object value, int row, int col) { if (col == COLUMN_FILENAME) { final JFileChooser chooser = getFileChooser(); File f = (File)getValueAt(row, col); if (f != null) { String oldDisplayName = chooser.getName(f); String oldFileName = f.getName(); String newDisplayName = ((String)value).trim(); String newFileName; if (!newDisplayName.equals(oldDisplayName)) { newFileName = newDisplayName; //Check if extension is hidden from user int i1 = oldFileName.length(); int i2 = oldDisplayName.length(); if (i1 > i2 && oldFileName.charAt(i2) == '.') { newFileName = newDisplayName + oldFileName.substring(i2); } // rename FileSystemView fsv = chooser.getFileSystemView(); final File f2 = fsv.createFileObject(f.getParentFile(), newFileName); if (f2.exists()) { JOptionPane.showMessageDialog(chooser, MessageFormat.format(renameErrorFileExistsText, oldFileName), renameErrorTitleText, JOptionPane.ERROR_MESSAGE); } else { if (FilePane.this.getModel().renameFile(f, f2)) { if (fsv.isParent(chooser.getCurrentDirectory(), f2)) { // The setSelectedFile method produces a new setValueAt invocation while the JTable // is editing. Postpone file selection to be sure that edit mode of the JTable // is completed SwingUtilities.invokeLater(new Runnable() { public void run() { if (chooser.isMultiSelectionEnabled()) { chooser.setSelectedFiles(new File[]{f2}); } else { chooser.setSelectedFile(f2); } } }); } else { // Could be because of delay in updating Desktop folder // chooser.setSelectedFile(null); } } else { JOptionPane.showMessageDialog(chooser, MessageFormat.format(renameErrorText, oldFileName), renameErrorTitleText, JOptionPane.ERROR_MESSAGE); } } } } } } public boolean isCellEditable(int row, int column) { File currentDirectory = getFileChooser().getCurrentDirectory(); return (!readOnly && column == COLUMN_FILENAME && canWrite(currentDirectory)); } public void contentsChanged(ListDataEvent e) { // Update the selection after the model has been updated new DelayedSelectionUpdater(); fireTableDataChanged(); } public void intervalAdded(ListDataEvent e) { int i0 = e.getIndex0(); int i1 = e.getIndex1(); if (i0 == i1) { File file = (File)getModel().getElementAt(i0); if (file.equals(newFolderFile)) { new DelayedSelectionUpdater(file); newFolderFile = null; } } fireTableRowsInserted(e.getIndex0(), e.getIndex1()); } public void intervalRemoved(ListDataEvent e) { fireTableRowsDeleted(e.getIndex0(), e.getIndex1()); } public ShellFolderColumnInfo[] getColumns() { return columns; } } private void updateDetailsColumnModel(JTable table) { if (table != null) { ShellFolderColumnInfo[] columns = detailsTableModel.getColumns(); TableColumnModel columnModel = new DefaultTableColumnModel(); for (int i = 0; i < columns.length; i++) { ShellFolderColumnInfo dataItem = columns[i]; TableColumn column = new TableColumn(i); String title = dataItem.getTitle(); if (title != null && title.startsWith("FileChooser.") && title.endsWith("HeaderText")) { // the column must have a string resource that we try to get String uiTitle = UIManager.getString(title, table.getLocale()); if (uiTitle != null) { title = uiTitle; } } column.setHeaderValue(title); Integer width = dataItem.getWidth(); if (width != null) { column.setPreferredWidth(width); // otherwise we let JTable to decide the actual width } columnModel.addColumn(column); } // Install cell editor for editing file name if (!readOnly && columnModel.getColumnCount() > COLUMN_FILENAME) { columnModel.getColumn(COLUMN_FILENAME). setCellEditor(getDetailsTableCellEditor()); } table.setColumnModel(columnModel); } } private DetailsTableRowSorter getRowSorter() { if (rowSorter == null) { rowSorter = new DetailsTableRowSorter(); } return rowSorter; } private class DetailsTableRowSorter extends TableRowSorter<TableModel> { public DetailsTableRowSorter() { setModelWrapper(new SorterModelWrapper()); } public void updateComparators(ShellFolderColumnInfo [] columns) { for (int i = 0; i < columns.length; i++) { Comparator c = columns[i].getComparator(); if (c != null) { c = new DirectoriesFirstComparatorWrapper(i, c); } setComparator(i, c); } } @Override public void sort() { ShellFolder.invoke(new Callable<Void>() { public Void call() { DetailsTableRowSorter.super.sort(); return null; } }); } public void modelStructureChanged() { super.modelStructureChanged(); updateComparators(detailsTableModel.getColumns()); } private class SorterModelWrapper extends ModelWrapper<TableModel, Integer> { public TableModel getModel() { return getDetailsTableModel(); } public int getColumnCount() { return getDetailsTableModel().getColumnCount(); } public int getRowCount() { return getDetailsTableModel().getRowCount(); } public Object getValueAt(int row, int column) { return FilePane.this.getModel().getElementAt(row); } public Integer getIdentifier(int row) { return row; } } } /** * This class sorts directories before files, comparing directory to * directory and file to file using the wrapped comparator. */ private class DirectoriesFirstComparatorWrapper implements Comparator<File> { private Comparator comparator; private int column; public DirectoriesFirstComparatorWrapper(int column, Comparator comparator) { this.column = column; this.comparator = comparator; } public int compare(File f1, File f2) { if (f1 != null && f2 != null) { boolean traversable1 = getFileChooser().isTraversable(f1); boolean traversable2 = getFileChooser().isTraversable(f2); // directories go first if (traversable1 && !traversable2) { return -1; } if (!traversable1 && traversable2) { return 1; } } if (detailsTableModel.getColumns()[column].isCompareByColumn()) { return comparator.compare( getDetailsTableModel().getFileColumnValue(f1, column), getDetailsTableModel().getFileColumnValue(f2, column) ); } // For this column we need to pass the file itself (not a // column value) to the comparator return comparator.compare(f1, f2); } } private DetailsTableCellEditor tableCellEditor; private DetailsTableCellEditor getDetailsTableCellEditor() { if (tableCellEditor == null) { tableCellEditor = new DetailsTableCellEditor(new JTextField()); } return tableCellEditor; } private class DetailsTableCellEditor extends DefaultCellEditor { private final JTextField tf; public DetailsTableCellEditor(JTextField tf) { super(tf);