Swing/SelectFileNameWithoutExtension のバックアップ(No.3)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/SelectFileNameWithoutExtension へ行く。
- 1 (2023-10-02 (月) 00:02:09)
- 2 (2023-10-05 (木) 07:05:34)
- 3 (2024-02-09 (金) 14:06:23)
- category: swing folder: SelectFileNameWithoutExtension title: JFileChooserのセルエディタでリネームを開始したとき拡張子を除くファイル名を選択状態にする tags: [JFileChooser, JTextField, JList, ContainerListener, JTable, FocusListener, DefaultCellEditor] author: aterai pubdate: 2023-10-01T00:44:38+09:00 description: JFileChooserのListViewやDetailsViewでリネーム可能なセルエディタとして使用されるJTextFieldを取得し、ファイル名全体ではなく拡張子を除くファイル名が選択状態になるよう設定します。 image: https://drive.google.com/uc?id=1Q83JplI4_5QHhy5qekG6vSDpBZmQYuQv
概要
JFileChooser
のListView
やDetailsView
でリネーム可能なセルエディタとして使用されるJTextField
を取得し、ファイル名全体ではなく拡張子を除くファイル名が選択状態になるよう設定します。
Screenshot
Advertisement
サンプルコード
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.cellEditor
のJTextField
をJList
に追加してセルエディタとしている JList
にContainerListener
を追加し、セルエディタのJTextField
が追加(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);
}
});
}
}
参考リンク
- JFileChooserのリスト表示を垂直1列に変更する
- JFileChooserの詳細表示でファイル名が編集中の場合はそれをキャンセルする
- JListのセルに配置したJLabelのテキストを編集する