JFileChooserのセルエディタでリネームを開始したとき拡張子を除くファイル名を選択状態にする
Total: 968, Today: 2, Yesterday: 1
Posted by aterai at 
Last-modified: 
Summary
JFileChooserのListViewやDetailsViewでリネーム可能なセルエディタとして使用されるJTextFieldを取得し、ファイル名全体ではなく拡張子を除くファイル名が選択状態になるよう設定します。
Screenshot

Advertisement
Source Code Examples
JButton button2 = new JButton("ListView");
button2.addActionListener(e -> {
  JFileChooser chooser = new JFileChooser();
  descendants(chooser)
      .filter(JList.class::isInstance)
      .map(JList.class::cast)
      .findFirst()
      .ifPresent(MainPanel::addCellEditorListener);
  int retValue = chooser.showOpenDialog(log.getRootPane());
  if (retValue == JFileChooser.APPROVE_OPTION) {
    log.setText(chooser.getSelectedFile().getAbsolutePath());
  }
});
// ...
private static void selectWithoutExtension(JTextField editor) {
  EventQueue.invokeLater(() -> {
    String name = editor.getText();
    int end = name.lastIndexOf('.');
    editor.setSelectionStart(0);
    editor.setSelectionEnd(end > 0 ? end : name.length());
  });
}
private static void addCellEditorListener(JList<?> list) {
  boolean readOnly = UIManager.getBoolean("FileChooser.readOnly");
  if (!readOnly) {
    list.addContainerListener(new ContainerAdapter() {
      @Override public void componentAdded(ContainerEvent e) {
        Component c = e.getChild();
        if (c instanceof JTextField && "Tree.cellEditor".equals(c.getName())) {
          selectWithoutExtension((JTextField) c);
        }
      }
    });
  }
}
View in GitHub: Java, KotlinDescription
Default- デフォルトの
JFileChooserのセルエディタは編集開始時にJTextField#selectAll()でファイル名が全選択される 
- デフォルトの
 ListView(JList)- デフォルトの
JListにはセルアイテムを編集するエディタは用意されていないので、JFileChooser(FilePane)では名前がTree.cellEditorのJTextFieldをJListに追加してセルエディタとして使用している- 名前が
FilePane.cellEditorやList.cellEditorなどではなくTree.cellEditorである理由は不明、以前または別のLookAndFeelではFilePaneにJTreeを使用していた? 
 - 名前が
 JListへのセルエディタ追加をContainerListener#componentAdded(ContainerEvent)で受信し、追加後そのセルエディタにJTextField#setSelectionEnd(...)を実行して拡張子を除くファイル名が選択状態になるよう設定
- デフォルトの
 DetailsView(JTable)- ファイル名を表示する
0列目のTableColumnからTableColumn#getCellEditor()#getComponent()でセルエディタとして使用するJTextFieldを取得 - 取得した
JTextFieldにFocusListenerを追加し、フォーカスが当たったら(FocusListener#focusGained(FocusEvent))拡張子を除くファイル名が選択状態になるよう設定 - マウスでファイル名のセルを選択したあと、シングルクリックでリネーム開始するとセルエディタが表示されるまでに想定外のタイムラグが発生する?
- F2でのリネーム開始は正常に動作している
 
 
- ファイル名を表示する
 
JButton button3 = new JButton("DetailsView");
button3.addActionListener(e -> {
  JFileChooser chooser = new JFileChooser();
  String cmd = "viewTypeDetails";
  Action detailsAction = chooser.getActionMap().get(cmd);
  if (Objects.nonNull(detailsAction)) {
    detailsAction.actionPerformed(
        new ActionEvent(chooser, ActionEvent.ACTION_PERFORMED, cmd));
  }
  descendants(chooser)
      .filter(JTable.class::isInstance)
      .map(JTable.class::cast)
      .findFirst()
      .ifPresent(MainPanel::addCellEditorFocusListener);
  int retValue = chooser.showOpenDialog(log.getRootPane());
  if (retValue == JFileChooser.APPROVE_OPTION) {
    log.setText(chooser.getSelectedFile().getAbsolutePath());
  }
});
// ...
private static void addCellEditorFocusListener(JTable table) {
  boolean readOnly = UIManager.getBoolean("FileChooser.readOnly");
  TableColumnModel columnModel = table.getColumnModel();
  if (!readOnly && columnModel.getColumnCount() > 0) {
    TableColumn tc = columnModel.getColumn(0);
    DefaultCellEditor editor = (DefaultCellEditor) tc.getCellEditor();
    JTextField tf = (JTextField) editor.getComponent();
    tf.addFocusListener(new FocusAdapter() {
      @Override public void focusGained(FocusEvent e) {
        selectWithoutExtension(tf);
      }
    });
  }
}
Reference
- JFileChooserのリスト表示を垂直1列に変更する
 - JFileChooserの詳細表示でファイル名が編集中の場合はそれをキャンセルする
 - JListのセルに配置したJLabelのテキストを編集する