Summary

JTree内で選択した複数ノードのTreePathから最長の共通パスを検索することで共通の親TreeNodeを取得します。

Source Code Examples

  private void showCommonParent() {
private void showCommonParent() {
  JTree tree = (JTree) getInvoker();
  Optional.ofNullable(tree.getSelectionPaths())
      .filter(paths -> paths.length > 1)
      .map(TreeUtils::findCommonParent)
      .ifPresent(p -> {
        Object node = p.getLastPathComponent();
        String title = "common parent";
        JOptionPane.showMessageDialog(
            tree, node, title, JOptionPane.INFORMATION_MESSAGE);
      });
}

// class TreeUtils ...
public static TreePath findCommonParent(TreePath... paths) {
  return Stream.of(paths)
      .map(TreePath::getPath)
      .reduce(TreeUtils::getCommonPath)
      .map(TreePath::new)
      .orElse(null);
}

public static <T> T[] getCommonPath(T[] node1, T[] node2) {
  int min = Math.min(node1.length, node2.length);
  for (int len = min; len > 0; len--) {
    T[] a1 = Arrays.copyOf(node1, len);
    T[] a2 = Arrays.copyOf(node2, len);
    if (Arrays.deepEquals(a1, a2)) {
      return a1;
    }
  }
  return Arrays.copyOf(node1, 1);
}
View in GitHub: Java, Kotlin

Description

  • JTree#getSelectionPaths()で取得した選択TreePathが複数存在する場合、それらをTreePath#getPath()でルートノードからのTreeNodeの配列に変換
  • Stream.reduce(...)TreeNode配列を2つ取り出し、それらをArrays.copyOf(...)を使用して短いTreeNode配列の長さに揃えてからArrays.deepEquals(a, b)で一致するかチェック
    • 一致しなければTreeNode配列の長さを1レベル短くして再比較
    • TreeNode配列の長さが1になるまで一致しない場合はルートノードが共通の親TreeNodeとなる

Reference

Comment