Swing自定義組件: JCheckTree – JAVA編程語言程序開發技術文章

一個Renderer 一個Listener 應該可以搞定.. 自定義組件..關鍵就在交互事件上..

 

4個類.分別為:CheckTreeDemo,CheckTree,Node,CheckRenderer,CheckListener

從類名可以看出來. CheckTreeDemo是JFrame類 CheckTree是組件,Node是數據模型,CheckRenderer是CheckTree得渲染,CheckListener是CheckTree的事件


package tree;

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 *
 * @author chensiyu
 * @createDate 2011/8/24
 */
public class CheckTreeDemo extends JPanel {

    private CheckTree checkTree;
   
    public CheckTreeDemo() {
        init();
    }
   
    private void init(){
        setLayout(new BorderLayout());
       
        Node rootNode = new Node("Root");
        Node []nodes = new Node[10];
        for(int i = 0;i <nodes.length;i++){
            Node node = new Node("Node-"+i);
            rootNode.add(node);
        }
        checkTree = new CheckTree(rootNode);
        add(checkTree,BorderLayout.CENTER);
       
    }

    public static void main(String[] args) {
        final JFrame frame = new JFrame();
        frame.setTitle("CheckTree");
        frame.setLayout(new BorderLayout());
        frame.setSize(200, 400);
        frame.getContentPane().add(new CheckTreeDemo());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                frame.setVisible(true);
            }
        });
    }
}


package tree;

import javax.swing.JTree;
import javax.swing.tree.TreeNode;

/**
 *
 * @author chensiyu
 * @createDate 2011/8/24
 */
public class CheckTree extends JTree {

    private CheckRenderer checkRenderer;
    private CheckListener checkListener;

    public CheckTree() {
        init();
    }

    public CheckTree(TreeNode node) {
        super(node);
        init();
    }

    private void init() {
        checkRenderer = new CheckRenderer();
        checkListener = new CheckListener();
        setCellRenderer(checkRenderer);
        addMouseListener(checkListener);
    }
}

package tree;

import javax.swing.tree.DefaultMutableTreeNode;

/**
 *
 * @author chensiyu
 * @createDate 2011/8/24
 */
public class Node extends DefaultMutableTreeNode{

    private String name = "";
    private boolean selected = false;

    public Node(String name){
        super(name);
        setName(name);
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }
}

package tree;

/**
 *
 * @author chensiyu
 * @createDate 2011/8/24
 */
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;

class CheckRenderer extends JPanel implements TreeCellRenderer {

    protected static JCheckBox check;
    protected JLabel label;
    private static Rectangle checkBounds;

    public CheckRenderer() {
        setLayout(null);
        add(check = new JCheckBox());
        add(label = new JLabel(""));
        check.setBackground(UIManager.getColor("Tree.textBackground"));
        label.setForeground(UIManager.getColor("Tree.textForeground"));
    }

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean isSelected, boolean expanded, boolean leaf, int row,
            boolean hasFocus) {
        String stringValue = tree.convertValueToText(value, isSelected,
                expanded, leaf, row, hasFocus);
        setEnabled(tree.isEnabled());
        label.setFont(tree.getFont());
        label.setText(stringValue);
        setBackground(tree.getBackground());
        setForeground(tree.getForeground());
       
        if(value instanceof Node){
            Node node = (Node)value;
            check.setSelected(node.isSelected());
        }
        return this;
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension d_check = check.getPreferredSize();
        Dimension d_label = label.getPreferredSize();
        return new Dimension(d_check.width + d_label.width,
                (d_check.height < d_label.height ? d_label.height
                : d_check.height));
    }

    @Override
    public void doLayout() {
        Dimension d_check = check.getPreferredSize();
        Dimension d_label = label.getPreferredSize();
        int y_check = 0;
        int y_label = 0;
        if (d_check.height < d_label.height) {
            y_check = (d_label.height – d_check.height) / 2;
        } else {
            y_label = (d_check.height – d_label.height) / 2;
        }
        check.setLocation(0, y_check);
        check.setBounds(0, y_check, d_check.width, d_check.height);
        label.setLocation(d_check.width, y_label);
        label.setBounds(d_check.width, y_label, d_label.width, d_label.height);
        if (checkBounds == null){
            checkBounds = check.getBounds();
        }
               
    }
   
    public static Rectangle getCheckBoxRectangle() {
        if( null == checkBounds )
            return new Rectangle(0,0,0,0);
        return (Rectangle) checkBounds.clone();
    }
}

package tree;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JTree;
import javax.swing.tree.TreePath;

/**
 *
 * @author chensiyu
 * @createDate 2011/8/24
 */
class CheckListener extends MouseAdapter {

    public CheckListener() {
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        JTree tree = (JTree) e.getSource();
        Point p = e.getPoint();
        int x = e.getX();
        int y = e.getY();
        int row = tree.getRowForLocation(x, y);
        TreePath path = tree.getPathForRow(row);

        if (null == path) {
            return;
        }

        Object component = path.getLastPathComponent();
        if (null == component) {
            return;
        }

        if (component instanceof Node) {
            Rectangle chRect = CheckRenderer.getCheckBoxRectangle();
            Rectangle rowRect = tree.getPathBounds(path);
            chRect.setLocation(chRect.x + rowRect.x, chRect.y + rowRect.y);
            if (e.getClickCount() == 1 && chRect.contains(p)) {
                Node node = (Node)component;
                node.setSelected(!node.isSelected());
                tree.repaint();
            }
        }
    }
}

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *