概要

JFileChooserListViewDetailsViewでリネーム可能なセルエディタとして使用されるJTextFieldを取得し、ファイル名全体ではなく拡張子を除くファイル名が選択状態になるよう設定します。

サンプルコード

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, Kotlin

解説

  • Default
    • デフォルトのJFileChooserのセルエディタは編集開始時にJTextField#selectAll()でファイル名が全選択される
  • ListView(JList)
    • デフォルトのJListにはセルアイテムを編集するエディタは用意されていないので、JFileChooser(FilePane)では名前がTree.cellEditorJTextFieldJListに追加してセルエディタとして使用している
    • JListへのセルエディタ追加をContainerListener#componentAdded(ContainerEvent)で受信し、追加後そのセルエディタにJTextField#setSelectionEnd(...)を実行して拡張子を除くファイル名が選択状態になるよう設定
  • DetailsView(JTable)
    • ファイル名を表示する0列目のTableColumnからTableColumn#getCellEditor()#getComponent()でセルエディタとして使用するJTextFieldを取得
    • 取得したJTextFieldFocusListenerを追加し、フォーカスが当たったら(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);
      }
    });
  }
}

参考リンク

コメント