Java 9下自定义JFileChooser详情视图按日期排序失效求助
Hey there, let's work through this frustrating issue with your custom JFileChooser sorting breaking after upgrading to Java 9. The root problem here is that Java 9 changed some internal behaviors of JFileChooser's table component and row sorter—your old approach relying on hard-coded column indexes and toggleSortOrder no longer works reliably. Here's how to fix it properly:
Why Your Old Code Broke
In Java 8 and earlier, the date column was consistently at index 3, and calling toggleSortOrder(3) twice reliably set a descending sort. But Java 9 adjusted the internal UI structure of JFileChooser—the column index for dates might have changed, or the initial sort state of the row sorter is different, making the toggle calls ineffective. Additionally, replacing the row sorter entirely introduces sync issues between the table's selection and the underlying model, which causes those "wrong file selected" bugs.
Solution: Dynamic Column Detection + Explicit Sort Configuration
Instead of relying on hard-coded indexes or toggle calls, we'll:
- Dynamically find the date column (so we don't depend on fixed indexes)
- Explicitly set the sort order to descending using the existing row sorter (to avoid selection sync issues)
Here's the revised code for your JFileChooserCustom class:
import javax.swing.*; import javax.swing.table.*; import java.util.Collections; import java.util.Date; public class JFileChooserCustom extends JFileChooser { // ... your existing code ... private void configureDateSorting() { // Get the file chooser's table (same as before) JTable fileChooserTable = SwingUtils.getDescendantsOfType(JTable.class, this).get(0); RowSorter<?> rowSorter = fileChooserTable.getRowSorter(); // Step 1: Dynamically locate the date column int dateColumnIndex = -1; TableModel tableModel = fileChooserTable.getModel(); // Option 1: Detect by column class (most reliable) for (int i = 0; i < tableModel.getColumnCount(); i++) { Class<?> columnClass = tableModel.getColumnClass(i); // Date columns are typically Date or Long (timestamp) types if (Date.class.isAssignableFrom(columnClass) || Long.class.isAssignableFrom(columnClass)) { dateColumnIndex = i; break; } } // Fallback: Detect by localized column header text (if class check fails) if (dateColumnIndex == -1) { String dateHeaderText = UIManager.getString("FileChooser.dateHeaderText"); TableColumnModel columnModel = fileChooserTable.getColumnModel(); for (int i = 0; i < columnModel.getColumnCount(); i++) { TableColumn column = columnModel.getColumn(i); if (dateHeaderText.equals(column.getHeaderValue())) { dateColumnIndex = i; break; } } } // Step 2: Set explicit descending sort if we found the column if (dateColumnIndex != -1) { // Replace any existing sort keys with our descending date sort rowSorter.setSortKeys(Collections.singletonList( new RowSorter.SortKey(dateColumnIndex, SortOrder.DESCENDING) )); // Trigger the sort immediately rowSorter.sort(); } } // Call this method when initializing your custom file chooser // e.g., in the constructor or after showing the dialog }
Key Improvements
- No hard-coded indexes: We find the date column dynamically, so this works across Java versions and localized UI setups.
- Explicit sort configuration: Instead of toggling (which depends on the initial sort state), we directly set the sort order to descending. This is far more reliable.
- Uses the existing row sorter: We don't replace the row sorter, so we avoid the selection sync issues you encountered with custom sorters.
Bonus: Ensure EDT Compliance
Make sure you call this configuration code on the Event Dispatch Thread (EDT)—Swing components must be modified only on the EDT to avoid unexpected bugs. Wrap the call like this if needed:
SwingUtilities.invokeLater(this::configureDateSorting);
This should get your date sorting working again in Java 9+ without those annoying side effects.
内容的提问来源于stack exchange,提问作者Klaus Guenther

