概要

JTreeのルートノードアイコンのみ、そのサイズを拡大し、アイコンの中央に垂直の接続線が描画されるように設定します。

サンプルコード

int ow = UIManager.getIcon("Tree.openIcon").getIconWidth();
int iw = 32;
int ih = 24;
Icon icon1 = new ColorIcon(Color.GREEN, new Dimension(ow, ih));
Icon icon2 = new ColorIcon(new Color(0x550000AA, true), new Dimension(iw, ih));
JTree tree = new JTree();
tree.setRowHeight(0);
tree.setBorder(BorderFactory.createEmptyBorder(1, 1 + (iw - ow) / 2, 1, 1));
tree.setCellRenderer(new DefaultTreeCellRenderer() {
  @Override public Component getTreeCellRendererComponent(
      JTree tree, Object value, boolean selected, boolean expanded,
      boolean leaf, int row, boolean hasFocus) {
    JLabel l = (JLabel) super.getTreeCellRendererComponent(
        tree, value, selected, expanded, leaf, row, hasFocus);
    if (value.equals(tree.getModel().getRoot())) {
      l.setIcon(icon1);
      l.setIconTextGap(2 + (iw - icon1.getIconWidth()) / 2);
    }
    return l;
  }
});
LayerUI<JTree> layerUI = new LayerUI<JTree>() {
  @Override public void paint(Graphics g, JComponent c) {
    super.paint(g, c);
    Graphics2D g2 = (Graphics2D) g.create();
    icon2.paintIcon(c, g2, 1, 1);
    g2.dispose();
  }
};
view all

解説

  • 左: デフォルト
    • tree.setRowHeight(0)でセルレンダラーが行の高さを決めるように設定
    • ルートノードのアイコンのみサイズを変更するTreeCellRendererを設定
    • アイコンを繋ぐ垂直の接続線は、左側寄りの位置に描画される
  • 右: setBorder + JLayer
    • tree.setRowHeight(0)でセルレンダラーが行の高さを決めるように設定
    • JTreeに、別途JLayerで描画するルートノードのアイコンの幅だけ余白を設定
      • UIManager.put("Tree.padding", 10)は、SynthLookAndFeelでのみ有効?
    • ルートノードのアイコンのみ、幅はデフォルトで高さを変更するTreeCellRendererを設定
      • JLabel#setIconTextGap(...)メソッドで、別途JLayerで描画するアイコンの幅だけ余白を設定しておく
    • 本来JTreeのルートノードアイコンとして設定したいアイコンをJLayerを使用して描画
    • アイコンを繋ぐ垂直の接続線は、中央に描画される

参考リンク

コメント