2013-12-12 72 views
0

我想創建一個自定義的JTree它是節點的JProgressBar的我有這個工作,就像我希望它定製JTree的單元格渲染器自定義打開/關閉圖標

enter image description here

但是你會發現,它缺少它是開放/關閉的圖標,我也想成爲一個自定義的+/-圖標,而不是標準的可擴展文件夾。不完全知道我在做什麼錯了(只是開發此刻的概念美化的代碼之前)

package com.testingarea; 

import java.awt.Component; 
import java.awt.Graphics; 
import java.util.HashMap; 

import javax.swing.BoxLayout; 
import javax.swing.Icon; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JProgressBar; 
import javax.swing.JScrollPane; 
import javax.swing.JTree; 
import javax.swing.UIManager; 
import javax.swing.plaf.IconUIResource; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeCellRenderer; 
import javax.swing.tree.DefaultTreeModel; 
import javax.swing.tree.TreeCellRenderer; 

public class TestTrees { 

    public static void main(String args[]) { 
    JFrame frame = new JFrame("Tree"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    ProgressTreeCellRenderer renderer = new ProgressTreeCellRenderer(); 

    JProgressBar progressBar = new JProgressBar(0, 100); 
    progressBar.setValue(50); 
    progressBar.setStringPainted(true); 
    DefaultMutableTreeNode top = 
     new DefaultMutableTreeNode(progressBar); 
    renderer.getNodeMap().put(top, new ProgressTreeCellRenderer2(progressBar)); 

    createNodes(top, renderer); 
    DefaultTreeModel model = new DefaultTreeModel(top);  

    JTree tree = new JTree(model); 
    tree.setCellRenderer(renderer); 
    JScrollPane pane = new JScrollPane(tree); 
    tree.clearSelection(); 
    frame.getContentPane().add(pane); 
    frame.setSize(250, 250); 
    frame.setVisible(true); 
    } 

    private static void createNodes(DefaultMutableTreeNode top, ProgressTreeCellRenderer renderer) { 
    JProgressBar progressBar1 = new JProgressBar(0, 100); 
    progressBar1.setValue(25); 
    progressBar1.setStringPainted(true); 
    DefaultMutableTreeNode one = 
     new DefaultMutableTreeNode(progressBar1); 
    top.add(one); 
    renderer.getNodeMap().put(one, new ProgressTreeCellRenderer2(progressBar1)); 

    JProgressBar progressBar2 = new JProgressBar(0, 100); 
    progressBar2.setValue(25); 
    progressBar2.setStringPainted(true); 
    DefaultMutableTreeNode two = 
     new DefaultMutableTreeNode(progressBar2); 
    top.add(two); 
    renderer.getNodeMap().put(two, new ProgressTreeCellRenderer2(progressBar2)); 
    } 

} 

@SuppressWarnings("serial") 
class ProgressTreeCellRenderer extends DefaultTreeCellRenderer { 

    private HashMap<DefaultMutableTreeNode, ProgressTreeCellRenderer2> nodeMap = new HashMap<DefaultMutableTreeNode, ProgressTreeCellRenderer2>(); 

    @Override 
    public Component getTreeCellRendererComponent(JTree tree, final Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { 
    if(nodeMap.containsKey(value)) { 
     //I was expecting this to work, alas it does not? 
     setClosedIcon(new IconUIResource(new NodeIcon('+'))); 
     setOpenIcon(new IconUIResource(new NodeIcon('-'))); 
     return nodeMap.get(value).getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); 
    } 
    return super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); 
    } 

    public HashMap<DefaultMutableTreeNode, ProgressTreeCellRenderer2> getNodeMap() { 
    return nodeMap; 
    } 
} 

class ProgressTreeCellRenderer2 implements TreeCellRenderer { 

    private JProgressBar _progressBar; 
    private DefaultTreeCellRenderer _defaultRenderer; 

    public ProgressTreeCellRenderer2(JProgressBar progressBar) { 
    _progressBar = progressBar; 
    _defaultRenderer = new DefaultTreeCellRenderer(); 
    } 

    @Override 
    public Component getTreeCellRendererComponent(JTree tree, final Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { 
    Component render = _defaultRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); 
    final JPanel panel = new JPanel(); 
    BoxLayout layout = new BoxLayout(panel, BoxLayout.X_AXIS); 

    panel.setLayout(layout); 
    panel.add(_progressBar); 
    render = panel;  
    return render; 
    } 

} 

class NodeIcon implements Icon { 

    private static final int SIZE = 9; 

    private char type; 

    public NodeIcon(char type) { 
    this.type = type; 
    } 

    public void paintIcon(Component c, Graphics g, int x, int y) { 
    g.setColor(UIManager.getColor("Tree.background")); 
    g.fillRect(x, y, SIZE - 1, SIZE - 1); 

    g.setColor(UIManager.getColor("Tree.hash").darker()); 
    g.drawRect(x, y, SIZE - 1, SIZE - 1); 

    g.setColor(UIManager.getColor("Tree.foreground")); 
    g.drawLine(x + 2, y + SIZE/2, x + SIZE - 3, y + SIZE/2); 
    if (type == '+') { 
     g.drawLine(x + SIZE/2, y + 2, x + SIZE/2, y + SIZE - 3); 
    } 
    } 

    public int getIconWidth() { 
    return SIZE; 
    } 

    public int getIconHeight() { 
    return SIZE; 
    } 
} 

回答

2

ProgressTreeCellRenderer調用setClosedIconsetOpenIcon的情況下,有沒有影響,因爲你正在返回從檢索另一個渲染器一個nodeMap。您必須在執行ProgressTreeCellRenderer2時添加圖標。例如,嘗試這一個圖標ProgressTreeCellRenderer2添加到面板:

panel.add((new JLabel((Icon)UIManager.get("Tree.closedIcon")))); 

但是,注意,目前的實現是非常昂貴的。不僅每個節點都有一個新的渲染器,而且還在getTreeCellRendererComponent()內重新分配面板實例。嘗試爲所有具有預分配控件的節點使用單個渲染器,其中只根據getTreeCellRendererComponent的參數更新屬性。查看How to Use Trees獲取渲染器詳細信息和樹顯示自定義示例。

看看這個answer(by @mKorbel),它演示了一個表中的單個進度條渲染器。

相關問題