JTree将节点背景设置为非不透明 [英] JTree set background of node to non-opaque

查看:167
本文介绍了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;

公共类SimpleTree扩展JFrame
{
public static void main(final String [] args)
{
new SimpleTree();
}

public SimpleTree()
{
super(创建一个简单的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);
}

/ **
*小例程将使节点脱离数组中的第一个条目,
*然后从后续条目中生成节点并使他们是第一个
*的子节点。对于
*数组的条目,递归重复该过程。
* /

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 [])//即带子节点的节点
child = this.processHierarchy((Object [])nodeSpecifier);
else
child = new DefaultMutableTreeNode(nodeSpecifier); //即Leaf
node.add(child);
}
return(node);
}

公共类MyCellRenderer扩展DefaultTreeCellRenderer
{
@Override
public Component getTreeCellRendererComponent(最终的JTree树,最终的Object值,最终的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);
}
返回ret;
}
}
}

解决方案

你应覆盖。

  • 不要扩展 JFrame 不必要地创建一个实例并使用它。

  • 不要在<$ c $上调用 setSize c> JFrame 而是使用正确的 LayoutManager 和/或覆盖 getPreferredSize()并调用 pack() JFrame 上,然后将其设置为可见但在添加所有组件之后。

  • 请记住使用 DISPOSE_ON_CLOSE EXIT_ON_CLOSE JFrame #setDefaultCloseOperation c>( DISPOSE_XXX 通常是首选的unles使用计时器 s,因为这将允许 main(String [] args)在Gui关闭后继续执行)。


  • Please have a look at the SSCCE. How can I make the non-selected tree nodes' background transparent. At the moment the background of non-selected nodes is white. My cell renderer, however, should paint it non-opaque if it is not selected (and green when selected...what it does). In the end I want non-selected nodes to be just text without background, since the area which is red in the SSCCE has a gradient fill in my application.

        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;
            }
        }
    }
    

    解决方案

    You should override getBackgroundNonSelectionColor,getBackgroundSelectionColor and getBackground of DefaultTreeCellRenderer and return appropriate values like so:

    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;
        }
    }
    

    which will produce:

    Other suggestions:

    • Create and manipulate Swing components on Event Dispatch Thread.
    • Dont extend JFrame unnecessarily rather create an instance and use that.
    • Dont call setSize on JFrame rather use a correct LayoutManager and/or override getPreferredSize() and call pack() on JFrame before setting it visible but after adding all components.
    • Remember to call JFrame#setDefaultCloseOperation with either DISPOSE_ON_CLOSE or EXIT_ON_CLOSE (DISPOSE_XXX is usually preferred unless using Timers as this will allow main(String[] args) to continue its execution after Gui has been closed).

    这篇关于JTree将节点背景设置为非不透明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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