概要

JFileChooserのリスト表示をデフォルトの垂直優先ニュースペーパースタイルから、JListのデフォルトである垂直1列スタイルに変更します。

サンプルコード

JButton button2 = new JButton("LayoutOrientation: VERTICAL");
button2.addActionListener(e -> {
  JFileChooser chooser = new JFileChooser();
  stream(chooser)
    .filter(JList.class::isInstance)
    .map(JList.class::cast)
    .findFirst()
    .ifPresent(list -> {
      list.addHierarchyListener(new HierarchyListener() {
        @Override public void hierarchyChanged(HierarchyEvent e) {
          if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0
              && e.getComponent().isShowing()) {
            list.putClientProperty("List.isFileList", Boolean.FALSE);
            list.setLayoutOrientation(JList.VERTICAL);
          }
        }
      });
    });
  int retvalue = chooser.showOpenDialog(log.getRootPane());
  if (retvalue == JFileChooser.APPROVE_OPTION) {
    log.setText(chooser.getSelectedFile().getAbsolutePath());
  }
});
View in GitHub: Java, Kotlin

解説

  • Default
    • JFileChooserJListを使用するリスト表示のデフォルトは、ファイルが垂直方向の次に水平方向の順に並ぶ「ニュースペーパー・スタイル」
    • 名前が長いファイルが存在すると、リストが見づらくなる
  • LayoutOrientation: VERTICAL
    • JFileChooserの子要素を検索してJListを取得し、JList#setLayoutOrientation(JList.VERTICAL)でファイルが垂直方向1列に配置されるよう設定
    • sun.swing.FilePane#setViewType(...)が実行されて表示形式がJTableを使用するviewTypeDetailsからJListを使用するviewTypeListに切り替わる度にJList#setLayoutOrientation(JList.VERTICAL_WRAP)が実行されるため、JListJFileChooserに設定されて表示されるとJList#setLayoutOrientation(JList.VERTICAL)を実行するHierarchyListenerを追加
    • コメントで指摘されているようにsun.swing.FilePaneを使用しないLookAndFeelではこのサンプルは無意味
      • 例えばGTKLookAndFeelではディレクトリ用とファイル用にJListが使用されているが、どちらも垂直方向1列がデフォルト

参考リンク

コメント