Java核心技术II-第6章-对象树-源代码

Java核心技术II-第6章-对象树-源代码,在博文的最后有运行效果图。

package javaee.vii.ch06;

import java.awt.EventQueue;
import javax.swing.JFrame;

/**
 * This program demonstrates cell rendering and listening to tree selection
 * events.
 *
 * @author lcwell
 */
public class ClassTree {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new ClassTreeFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

 

package javaee.vii.ch06;

import java.awt.Component;
import java.awt.Font;
import java.lang.reflect.Modifier;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;

/**
 * This class renders a class name either in plain or italic. Abstract classes
 * are italic.
 *
 * @author lcwell
 */
public class ClassNameTreeCellRenderer extends DefaultTreeCellRenderer {

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
            boolean expanded, boolean leaf, int row, boolean hasFocus) {
        Component comp = super.getTreeCellRendererComponent(tree, value, leaf, expanded, leaf, row, hasFocus);
        // get the user object
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
        Class<?> c = (Class<?>) node.getUserObject();

        // the first time, derive itablic font from plain font
        if (plainFont == null) {
            plainFont = getFont();
            // the tree cell renderer is sometimes called with a label that has a null font
            if (plainFont != null) {
                italicFont = plainFont.deriveFont(Font.ITALIC);
            }
        }

        // set font to italic if the class is abstract, plain otherwise
        if (c != null && (c.getModifiers() & Modifier.ABSTRACT) == 0) {
            setFont(plainFont);
        } else {
            comp.setFont(italicFont);
        }
        
        return comp;
    }

    private Font plainFont = null;
    private Font italicFont = null;
}

 

package javaee.vii.ch06;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Enumeration;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

/**
 * This frame displays the class tree, a text field and add button to 
 * add more classes into the tree.
 * @author lcwell
 */
public class ClassTreeFrame extends JFrame {
    
    public ClassTreeFrame() {
        setTitle("ClassTree");
        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
        
        // the root of the class tree is Object
        root = new DefaultMutableTreeNode(java.lang.Object.class);
        model = new DefaultTreeModel(root);
        tree = new JTree(model);
        
        // add this class to populate the tree with some data
        addClass(getClass());
        
        // set up node icons
        ClassNameTreeCellRenderer renderer = new ClassNameTreeCellRenderer();
        renderer.setClosedIcon(new ImageIcon("src/images/1.jpg"));
        renderer.setOpenIcon(new ImageIcon("src/images/2.jpg"));
        renderer.setLeafIcon(new ImageIcon("src/images/3.jpg"));
        tree.setCellRenderer(renderer);
        
        // set up selection mode
        tree.addTreeSelectionListener(new TreeSelectionListener(){
            public void valueChanged(TreeSelectionEvent event) {
                // the user selected a diffent node -- update description
                TreePath path = tree.getSelectionPath();
                if (path == null) {
                    return;
                }
                DefaultMutableTreeNode selectedNode = 
                        (DefaultMutableTreeNode) path.getLastPathComponent();
                Class<?> c = (Class<?>) selectedNode.getUserObject();
                String description = getFieldDescription(c);
                textArea.setText(description);
            }
        });
        int mode = TreeSelectionModel.SINGLE_TREE_SELECTION;
        tree.getSelectionModel().setSelectionMode(mode);
        
        // this text area holds the class description
        textArea = new JTextArea();
        
        // add tree and text area
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(1, 2));
        panel.add(new JScrollPane(tree));
        panel.add(new JScrollPane(textArea));
        
        add(panel, BorderLayout.CENTER);
        
        addTextField();
    }
    
    /**
     * Add the text field and "Add" button to add a new class.
     */
    public void addTextField() {
        JPanel panel = new JPanel();
        ActionListener addListener = new ActionListener(){
            public void actionPerformed(ActionEvent event) {
                // add the class whose name is in the text field
                try {
                    String text = textField.getText();
                    addClass(Class.forName(text));  // clear text field to indicate success
                    textField.setText("");
                } catch (ClassNotFoundException e) {
                    JOptionPane.showMessageDialog(null, "Class not found");
                }
            }
        };
        
        // new class names are typed into this text field
        textField = new JTextField(20);
        textField.addActionListener(addListener);
        panel.add(textField);
        
        JButton addButton = new JButton("Add");
        addButton.addActionListener(addListener);
        panel.add(addButton);
        
        add(panel, BorderLayout.SOUTH);
    }
    
    /**
     * Finds an object in the tree.
     * @param obj the object to find
     * @return the node containing the object or null if the objects is not persent in the tree
     */
    @SuppressWarnings("unchecked")
    public DefaultMutableTreeNode findUserObject(Object obj) {
       // find the node containing a user object
        Enumeration<TreeNode> e = (Enumeration<TreeNode>) root.breadthFirstEnumeration();
        while (e.hasMoreElements()) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.nextElement();
            if (node != null & obj.equals(node.getUserObject())) return node;
        }
        
        return null;
    }
    
    /**
     * Adds a new and any parent classes that aren't yet part of the tree
     * @param c the class to add
     * @return the newly added node
     */
    public DefaultMutableTreeNode addClass(Class<?> c) {
        // add a new class to the tree
        
        // skip non-class types
        if (c.isInterface() || c.isPrimitive()) return null;
        
        // if the class is already in the tree, return its node
        DefaultMutableTreeNode node = findUserObject(c);
        if (node != null) return node;
        
        // class isn't present -- first add class parent recursively
        Class<?> s = c.getSuperclass();
        DefaultMutableTreeNode parent;
        if (s == null) parent = root;
        else parent = addClass(s);
        
        // add the class as a child to the parent
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(c);
        model.insertNodeInto(newNode, parent, parent.getChildCount());
        
        // make node visible
        TreePath path = new TreePath(model.getPathToRoot(newNode));
        tree.makeVisible(path);
        
        return newNode;
    }
    
    /**
     * Return a description to find types and names of fields.
     * @param c the classt o be described
     * @return a string contraining all field types and names
     */
    public static String getFieldDescription(Class<?> c) {
        // use reflection to find types and names of fileds
        StringBuilder r = new StringBuilder();
        Field[] fields = c.getDeclaredFields();
        for (Field f : fields) {
            if ((f.getModifiers() & Modifier.STATIC) != 0) r.append("static ");
            r.append(f.getType().getName());
            r.append(" ");
            r.append(f.getName());
            r.append("\n");
        }
        return r.toString();
    }
    
    private DefaultMutableTreeNode root;
    private DefaultTreeModel model;
    private JTree tree;
    private JTextField textField;
    private JTextArea textArea;
    private static final int DEFAULT_WIDTH = 400;
    private static final int DEFAULT_HEIGHT = 300;
}

 

运行效果:

Java核心技术II-06 对象树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值