• category: swing folder: GetComponentsRecursively title: Containerの子Componentを再帰的にすべて取得する tags: [Container, Component, JFileChooser, JTable] author: aterai pubdate: 2017-02-06T14:11:50+09:00 description: Containerの子Componentを再帰的にすべて取得するメソッドを作成し、JFileChooserに配置されたJTableを取得します。 image: https://drive.google.com/uc?id=1NedWhPhVuMDTwrHRaFdW-YXZjdH-019yuw

概要

Containerの子Componentを再帰的にすべて取得するメソッドを作成し、JFileChooserに配置されたJTableを取得します。

サンプルコード

public static Stream<Component> stream(Container parent) {
  return Stream.of(parent.getComponents())
      .filter(Container.class::isInstance).map(c -> stream((Container) c))
      .reduce(Stream.of(parent), Stream::concat);
}
// ...
stream(chooser)
  .filter(JTable.class::isInstance).map(JTable.class::cast)
  .findFirst()
  .ifPresent(t -> t.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN));
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JFileChooserの詳細表示で使用されているJTableを取得し、その自動サイズ変更モードを変更しています。

  • JPopupMenuJComponent#setComponentPopupMenu(...)で設定されていても、その子Componentは取得しない
  • JDK1.8で導入されたStreamを使用
    • 以下のようにflatMapを使用する方法もある
      // flatMap + Stream.concat(...)
      public static Stream<Component> stream5(Container parent) {
        return Arrays.stream(parent.getComponents())
          .filter(Container.class::isInstance).map(Container.class::cast)
          .flatMap(c -> Stream.concat(Stream.of(c), stream5(c)));
      }
      // Arrays.stream(...) + flatMap
      public static Stream<Component> stream6(Container parent) {
        return Stream.concat(Stream.of(parent), Arrays.stream(parent.getComponents())
          .filter(Container.class::isInstance).map(Container.class::cast)
          .flatMap(MainPanel::stream6));
      }
      
    • 以下のように、Streamを使用しない方法もある
      public static boolean searchAndResizeMode(Container parent) {
        for (Component c: parent.getComponents()) {
          if (c instanceof JTable) {
            ((JTable) c).setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
            return true;
          } else if (c instanceof Container && searchAndResizeMode((Container) c)) {
            return true;
          }
        }
        return false;
      }
      

参考リンク

コメント