java - JTree - 向右移动节点

标签 java swing jtree

我有一个具有多个节点级别的 JTree。我将根节点的图标更改为更大的图标。问题是,现在图标比默认图标大,垂直虚线和相应的子节点没有在根节点图标下方居中。

见下图:

JTree

我的问题是:是否可以将除根节点之外的所有内容都向右移动一点点?

最佳答案

JTree中设置左边距,在JLayer中单独绘制真正的根节点图标。

enter image description here

import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.*;
import javax.swing.tree.*;

public class MiddleXOfRootNodeIconTest {
  public JComponent makeUI() {
    int ow = UIManager.getIcon("Tree.openIcon").getIconWidth();
    int iw = 32;

    Icon icon1 = new ColorIcon(Color.GREEN, new Dimension(ow, iw));
    Icon icon2 = new ColorIcon(new Color(0x550000AA, true), new Dimension(iw, iw));

    JTree tree = new JTree();
    tree.setBorder(BorderFactory.createEmptyBorder(1, 1 + iw / 2, 1, 1));
    //TEST:
    //tree.setBorder(BorderFactory.createMatteBorder(1, 1 + iw / 2, 1, 1, Color.RED));
    tree.setCellRenderer(new CompoundTreeCellRenderer(icon1, iw));
    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 + ow / 2, 1);
        g2.dispose();
      }
    };

    JPanel p = new JPanel(new GridLayout(1, 3));
    p.add(new JScrollPane(new JTree()));
    p.add(new JScrollPane(new JLayer<JTree>(tree, layerUI)));
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new MiddleXOfRootNodeIconTest().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}
class CompoundTreeCellRenderer extends DefaultTreeCellRenderer {
  private static final Color ALPHA_ZERO = new Color(0x0, true);
  private final JPanel p = new JPanel(new GridBagLayout());
  private final GridBagConstraints ci = new GridBagConstraints();
  private final GridBagConstraints cl = new GridBagConstraints();
  private final JLabel icon = new JLabel();
  private final Icon gap1 = new ColorIcon(ALPHA_ZERO, new Dimension(2, 10));
  private final Icon gap2;
  private final Icon rootIcon;
  public CompoundTreeCellRenderer(Icon rootIcon, int iw) {
    super();
    Dimension d = new Dimension(2 + (iw - rootIcon.getIconWidth()) / 2, 10);
    this.rootIcon = rootIcon;
    //TEST: this.gap2 = new ColorIcon(Color.BLUE, d);
    this.gap2 = new ColorIcon(ALPHA_ZERO, d);
    this.setOpaque(false);
    p.setOpaque(false);
    ci.gridx = 0;
    ci.weightx = 1.0;
    cl.gridx = 1;
    cl.anchor = GridBagConstraints.WEST;
  }
  @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);
    l.setOpaque(false);
    p.removeAll();

    if (value.equals(tree.getModel().getRoot())) {
      icon.setIcon(rootIcon);
      l.setIcon(gap2);
    } else {
      icon.setIcon(l.getIcon());
      l.setIcon(gap1);
    }
    p.add(icon, ci);
    p.add(l, cl);
    return p;
  }
}
class ColorIcon implements Icon {
  private final Color color;
  private final Dimension dim;
  public ColorIcon(Color color, Dimension dim) {
    this.color = color;
    this.dim = dim;
  }
  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.translate(x, y);
    g2.setColor(color);
    g2.fillRect(1, 1, dim.width - 2, dim.height - 2);
    g2.dispose();
  }
  @Override public int getIconWidth()  {
    return dim.width;
  }
  @Override public int getIconHeight() {
    return dim.height;
  }
}

关于java - JTree - 向右移动节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40544376/

相关文章:

java - 在 Java 桌面应用程序中使用 CSS 和 JavaScript

Java Tetris - 使用旋转矩阵的旋转

java - JDialog - 刷新 JTree 中动态添加的节点

java - 如何在读取 CSV 时删除双引号

java - C++ 和 PHP 之间的通用桥梁

Java Swing ; JFrame 弹出窗口

java - 动态设置不同的jtree行高

java - 从 JTree 获取节点值并使用 JButton 将其显示在 JTable 中

java - 如何使用 Quarkus 解决 Infinispan JCache 拦截器中的异常 "Interceptor has no bindings"?

java - 进程挂起 waitFor() 方法