JTree中的颜色行 [英] Color row in JTree

查看:39
本文介绍了JTree中的颜色行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为 JTree 中的元素着色.然而,仅仅为标签添加背景颜色看起来有点奇怪.特别是如果选择了多个节点,生成的形状看起来参差不齐且分散注意力.

I'd like to color elements in a JTree. However, simply adding a background color only to the label looks kind of strange. Particularly if more than one node is selected, the resulting shape looks ragged and distracting.

有没有办法让背景延伸到树元素的整个宽度,让整行都被着色?要么从左边框开始,要么从标签的开头开始,但肯定一直延伸到组件的右边框?

Is there a way to make the background extend the whole width of the tree element, so that the whole row gets colored? Either starting at the left border or starting at the beginning of the label, but definitely extending till the right border of the component?

这是一个基于this question的小型独立演示.

Here is a small self-contained demo, based on this question.

import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
public class SO26724913 {
    public static void main(String[] args) {
        DefaultMutableTreeNode a = new DefaultMutableTreeNode("a");
        DefaultMutableTreeNode b = new DefaultMutableTreeNode("b");
        DefaultMutableTreeNode c = new DefaultMutableTreeNode("c");
        a.add(b);
        a.add(c);
        final JTree tree = new JTree(a);
        tree.setCellRenderer(new DefaultTreeCellRenderer() {
                @Override
                public Component getTreeCellRendererComponent
                    (JTree tree, Object value, boolean selected,
                     boolean expanded, boolean leaf, int row, boolean focus)
                {
                    JComponent c = (JComponent)
                        super.getTreeCellRendererComponent
                        (tree, value, selected, expanded, leaf, row, focus);
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
                    String data = (String)node.getUserObject();
                    if ("b".equals(data)) {
                        c.setBackground(Color.RED);
                        c.setOpaque(true);
                    }
                    else {
                        c.setBackground(null);
                        c.setOpaque(false);
                    }
                    return c;
                }
            });
        JFrame frm = new JFrame();
        frm.getContentPane().add(tree);
        frm.setSize(200, 200);
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.setVisible(true);
    }
}

这是代码当前生成的内容.

This is what the code currently generates.

我更喜欢这个
或者这个.

I'd prefer either this
or this.

推荐答案

你也许可以重写 JTreepaintComponent(Graphics) 方法来直接绘制选择矩形:

You might be able to override the paintComponent(Graphics) method of JTree to paint selection rectangles directly:

import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import javax.swing.*;
import javax.swing.tree.*;

public class ColorTreeTest {
  private static final Color SELC = Color.RED;
  public JComponent makeUI() {
    FocusListener fl = new FocusListener() {
      @Override public void focusGained(FocusEvent e) {
        e.getComponent().repaint();
      }
      @Override public void focusLost(FocusEvent e) {
        e.getComponent().repaint();
      }
    };
    DefaultTreeCellRenderer r = 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, false);
        l.setBackground(selected ? Color.RED
                                 : tree.getBackground());
        l.setOpaque(true);
        return l;
      }
    };
    JPanel p = new JPanel(new GridLayout(1, 2));
    for (JTree t : Arrays.asList(new ColorTree1(), new ColorTree2())) {
      t.addFocusListener(fl);
      t.setCellRenderer(r);
      t.setOpaque(false);
      p.add(new JScrollPane(t));
    }
    return p;
  }
  static class ColorTree1 extends JTree {
    @Override public void paintComponent(Graphics g) {
      g.setColor(getBackground());
      g.fillRect(0, 0, getWidth(), getHeight());
      if (getSelectionCount() > 0) {
        g.setColor(SELC);
        for (int i : getSelectionRows()) {
          Rectangle r = getRowBounds(i);
          g.fillRect(r.x, r.y, getWidth() - r.x, r.height);
        }
      }
      super.paintComponent(g);
      if (getLeadSelectionPath() != null) {
        Rectangle r = getRowBounds(getRowForPath(getLeadSelectionPath()));
        g.setColor(hasFocus() ? SELC.darker() : SELC);
        g.drawRect(r.x, r.y, getWidth() - r.x - 1, r.height - 1);
      }
    }
  }
  static class ColorTree2 extends JTree {
    private static final Color SELC = Color.RED;
    @Override public void paintComponent(Graphics g) {
      g.setColor(getBackground());
      g.fillRect(0, 0, getWidth(), getHeight());
      if (getSelectionCount() > 0) {
        g.setColor(SELC);
        //@see http://ateraimemo.com/Swing/TreeRowSelection.html
        for (int i : getSelectionRows()) {
          Rectangle r = getRowBounds(i);
          g.fillRect(0, r.y, getWidth(), r.height);
        }
      }
      super.paintComponent(g);
      if (getLeadSelectionPath() != null) {
        Rectangle r = getRowBounds(getRowForPath(getLeadSelectionPath()));
        g.setColor(hasFocus() ? SELC.darker() : SELC);
        g.drawRect(0, r.y, getWidth() - 1, r.height - 1);
      }
    }
  }
  public static void main(String... args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new ColorTreeTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

这篇关于JTree中的颜色行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆