JTree установил фон узла как непрозрачный

Пожалуйста, взгляните на SSCCE. Как я могу сделать фон невыделенных узлов дерева прозрачным. На данный момент фон невыбранных узлов белый. Мой рендерер ячеек должен, однако, рисовать его непрозрачным, если он не выделен (и зеленым, если выбран... что он делает). В конце я хочу, чтобы невыбранные узлы были просто текстом без фона, так как область, которая красного цвета в SSCCE, имеет градиентную заливку в моем приложении.

    import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;

public class SimpleTree extends JFrame
{
    public static void main(final String[] args)
    {
        new SimpleTree();
    }

    public SimpleTree()
    {
        super("Creating a Simple JTree");
        final Container content = this.getContentPane();
        content.setBackground(Color.RED);
        final Object[] hierarchy = { "javax.swing", "javax.swing.border", "javax.swing.colorchooser", "javax.swing.event", "javax.swing.filechooser", new Object[] { "javax.swing.plaf", "javax.swing.plaf.basic", "javax.swing.plaf.metal", "javax.swing.plaf.multi" }, "javax.swing.table",
                        new Object[] { "javax.swing.text", new Object[] { "javax.swing.text.html", "javax.swing.text.html.parser" }, "javax.swing.text.rtf" }, "javax.swing.tree", "javax.swing.undo" };
        final DefaultMutableTreeNode root = this.processHierarchy(hierarchy);
        final JTree tree = new JTree(root);
        tree.setOpaque(false);
        tree.setCellRenderer(new MyCellRenderer());
        final JScrollPane scroller = new JScrollPane(tree);
        scroller.getViewport().setOpaque(false);
        scroller.setOpaque(false);
        content.add(scroller, BorderLayout.CENTER);
        this.setSize(275, 300);
        this.setVisible(true);
    }

    /**
     * Small routine that will make node out of the first entry in the array,
     * then make nodes out of subsequent entries and make them child nodes of
     * the first one. The process is repeated recursively for entries that are
     * arrays.
     */

    private DefaultMutableTreeNode processHierarchy(final Object[] hierarchy)
    {
        final DefaultMutableTreeNode node = new DefaultMutableTreeNode(hierarchy[0]);
        DefaultMutableTreeNode child;
        for (int i = 1; i < hierarchy.length; i++)
        {
            final Object nodeSpecifier = hierarchy[i];
            if (nodeSpecifier instanceof Object[]) // Ie node with children
                child = this.processHierarchy((Object[]) nodeSpecifier);
            else
                child = new DefaultMutableTreeNode(nodeSpecifier); // Ie Leaf
            node.add(child);
        }
        return (node);
    }

    public class MyCellRenderer extends DefaultTreeCellRenderer
    {
        @Override
        public Component getTreeCellRendererComponent(final JTree tree, final Object value, final boolean sel, final boolean expanded, final boolean leaf, final int row, final boolean hasFocus)
        {
            final Component ret = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

            final DefaultMutableTreeNode node = ((DefaultMutableTreeNode) (value));

            this.setText(value.toString());
            if (sel)
            {
                this.setOpaque(true);
                this.setBackground(Color.GREEN);

            }
            else
            {
                this.setOpaque(false);
                this.setBackground(null);
            }
            return ret;
        }
    }
}

2 ответа

Решение

Вы должны переопределить getBackgroundNonSelectionColor, getBackgroundSelectionColor а также getBackground из DefaultTreeCellRenderer и вернуть соответствующие значения, например, так:

public class MyCellRenderer extends DefaultTreeCellRenderer {

    @Override
    public Color getBackgroundNonSelectionColor() {
        return (null);
    }

    @Override
    public Color getBackgroundSelectionColor() {
        return Color.GREEN;
    }

    @Override
    public Color getBackground() {
        return (null);
    }

    @Override
    public Component getTreeCellRendererComponent(final JTree tree, final Object value, final boolean sel, final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) {
        final Component ret = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

        final DefaultMutableTreeNode node = ((DefaultMutableTreeNode) (value));
        this.setText(value.toString());
        return ret;
    }
}

который будет производить:

Другие предложения:

  • Создание и управление компонентами Swing в потоке диспетчеризации событий.
  • Не расширяйте JFrame излишне, а создать экземпляр и использовать его.
  • Не звоните setSize на JFrame скорее используйте правильный LayoutManager и / или переопределить getPreferredSize() и позвонить pack() на JFrame до установки это видно, но после добавления всех компонентов.
  • Не забудьте позвонить JFrame#setDefaultCloseOperation либо с DISPOSE_ON_CLOSE или же EXIT_ON_CLOSE (DISPOSE_XXX обычно предпочтительнее, если не использовать Timer с как это позволит main(String[] args) продолжить выполнение после закрытия Gui).

Чтобы избежать фонового заполнения, просто поставьте UIManager.put("Tree.rendererFillBackground", false); до new SimpleTree(); или после super("Creating a Simple JTree");,

Другие вопросы по тегам