![]() | Source code below from: Professional Java User Interfaces By Mauro Marinilli Published 26 May, 2006 Average rating Powells Alibris |
package com.marinilli.b1.c5.templates; import javax.swing.*; import java.awt.dnd.*; import javax.swing.event.*; import javax.swing.tree.*; import java.awt.event.*; import java.awt.*; import java.io.*; import java.util.*; import com.marinilli.b1.c7.ServiceManager; /** * Standard and Specialized Components * * A Tree Prototype Class Facility * * @author Mauro Marinilli * @version 1.0 */ public class JProtoTree extends JTree implements MouseListener, TreeSelectionListener { private final static int CAPTION = 0; private final static int TOOLTIP = 1; private final static int ICON = 2; private final static int CONTEXTUAL_MENU = 3; public JProtoTree(String prp) { super(); ProtoTreeModel model = new ProtoTreeModel(prp); setModel(model); // addTreeWillExpandListener(model); fillClientProperties(model.getClientProperties()); ProtoCellRenderer renderer = new ProtoCellRenderer(); setCellRenderer(renderer); setShowsRootHandles(model.isShowsRootHandles()); setScrollsOnExpand(model.isScrollsOnExpand()); setRootVisible(model.isRootVisible()); setDragEnabled(model.isDragEnabled()); if(model.getOpenIcon()!=null) renderer.setOpenIcon(model.getOpenIcon()); if(model.getClosedIcon()!=null) renderer.setClosedIcon(model.getClosedIcon()); if(model.getLeafIcon()!=null) renderer.setLeafIcon(model.getLeafIcon()); if (model.isDragEnabled()) setDropTarget(new DropTarget()); addMouseListener(this); addTreeSelectionListener(this); // tooltip support ToolTipManager.sharedInstance().registerComponent(this); } private void fillClientProperties(HashMap map){ if (map.keySet()!=null) for (Iterator i = map.keySet().iterator(); i.hasNext(); ) { String k = (String)i.next(); putClientProperty(k, map.get(k)); } } /* * control mouse events */ public void mousePressed(MouseEvent e) { if ((e.getModifiers() & java.awt.event.InputEvent.BUTTON1_MASK ) == java.awt.event.InputEvent.BUTTON1_MASK ) { return; } if ((e.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK ) == java.awt.event.InputEvent.BUTTON3_MASK ) { //right click TreePath tp = getPathForLocation(e.getX(), e.getY()); if (tp != null) { setSelectionPath(tp); JPopupMenu popup = new JPopupMenu(); String[] appearance = (String[]) ((DefaultMutableTreeNode)tp.getLastPathComponent()).getUserObject(); String commands = appearance[CONTEXTUAL_MENU]; if (commands!=null && commands.length()>0) { while (commands.indexOf("%%")!=-1) { String c = commands.substring(0,commands.indexOf("%%")); commands = commands.substring(commands.indexOf("%%")+2,commands.length()); if (c.equals("--")) popup.addSeparator(); else popup.add(c); } popup.add(commands); } popup.show(this, e.getX(),e.getY()); } } } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { if (e.getClickCount()==2) { TreePath tp = getPathForLocation(e.getX(), e.getY()); if (tp != null) { doubleclick(); } } } //for double click code overload this method public void doubleclick(){ } public void valueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)getLastSelectedPathComponent(); if (node == null) return; //value changed code here } /** * the dedicated model * Note that this Model breaks the separation of logic and appearance for practicity */ public class ProtoTreeModel extends DefaultTreeModel { private boolean isShowsRootHandles = false; private boolean isScrollsOnExpand = false; private boolean isRootVisible = false; private boolean isDragEnabled = false; private HashMap clientProperties; private Icon leafIcon ; private Icon closedIcon ; private Icon openIcon ; public ProtoTreeModel(String fileName) { super(null); clientProperties = new HashMap(); Properties prpts = new Properties();// defaults try { java.io.InputStream in = ServiceManager.getInstance().getClass().getClassLoader().getResourceAsStream(fileName); prpts.load(in); } catch (Exception ex) { System.out.println("loading tree properties: "+ex); } //launch recursion setRoot(createNode("root",prpts,"")); //read other properties for (Enumeration i = prpts.propertyNames(); i.hasMoreElements(); ) { String s = (String)i.nextElement(); if (s.startsWith("JTree.")) clientProperties.put(s,prpts.getProperty(s)); else { if (s.equals("setScrollsOnExpand") && prpts.get(s).equals("true")) isScrollsOnExpand=true; else if (s.equals("setShowsRootHandles") && prpts.get(s).equals("true")) isShowsRootHandles=true; else if (s.equals("setRootVisible") && prpts.get(s).equals("true")) isRootVisible=true; else if (s.equals("setDragEnabled") && prpts.get(s).equals("true")) isDragEnabled=true; else if (s.equals("setLeafIcon")) leafIcon = ServiceManager.getImageIcon((String)prpts.getProperty(s)); else if (s.equals("setClosedIcon")) closedIcon = ServiceManager.getImageIcon((String)prpts.getProperty(s)); else if (s.equals("setOpenIcon")) openIcon = ServiceManager.getImageIcon((String)prpts.getProperty(s)); } } } // accessory methods public HashMap getClientProperties() { return clientProperties; } boolean isRootVisible(){ return isRootVisible; } boolean isShowsRootHandles(){ return isShowsRootHandles; } boolean isScrollsOnExpand(){ return isScrollsOnExpand; } boolean isDragEnabled(){ return isDragEnabled; } Icon getOpenIcon(){ return openIcon; } Icon getClosedIcon(){ return closedIcon; } Icon getLeafIcon(){ return leafIcon; } /** * recursively creates nodes */ private DefaultMutableTreeNode createNode(String n, Properties treeProperties, String parentMenu){ String[] s = getTokens((String)treeProperties.get(n)); DefaultMutableTreeNode node = new DefaultMutableTreeNode(); String[] appearance = new String[4]; appearance[CAPTION] = s[CAPTION]; appearance[TOOLTIP] = s[TOOLTIP]; appearance[ICON] = s[ICON]; if (s[CONTEXTUAL_MENU].length()==0) { //use parent's one appearance[CONTEXTUAL_MENU] = parentMenu; } else appearance[CONTEXTUAL_MENU] = s[CONTEXTUAL_MENU]; node.setUserObject(appearance); //extract children ArrayList children = new ArrayList(); for (int i = 4; i < s.length; i++) { children.add(s[i]); } //visit all children for (Iterator i = children.iterator(); i.hasNext(); ) { String child = (String)i.next(); node.add(createNode(child,treeProperties,appearance[CONTEXTUAL_MENU])); } return node; } private String[] getTokens(String s){ ArrayList result = new ArrayList(); StringTokenizer st = new StringTokenizer(s,",;"); while (st.hasMoreTokens()) { String w = st.nextToken(); if (w.equals("-")) result.add(""); else result.add(w); } String[] a = new String[result.size()]; result.toArray(a); return a; } }//JProtoTree class /** * Cell Renderer inner class */ public class ProtoCellRenderer extends DefaultTreeCellRenderer{ public ProtoCellRenderer() { super(); } public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { Object valueObj = ((DefaultMutableTreeNode)value).getUserObject(); String[] v = (String[])valueObj; if (v[ICON].length()==0){ if (leaf) { setIcon(getLeafIcon()); } else if (expanded) { setIcon(getOpenIcon()); } else { setIcon(getClosedIcon()); } } else setIcon(ServiceManager.getImageIcon(v[ICON])); setToolTipText(v[TOOLTIP]); setText(v[CAPTION]); if(sel) setForeground(getTextSelectionColor()); else setForeground(getTextNonSelectionColor()); setComponentOrientation(tree.getComponentOrientation()); selected = sel; return this; } } /** * test main */ static public void main(String[] args) { JFrame f =new JFrame("Test Prototype Tree"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add(new JScrollPane( new JProtoTree("tree.properties")) ); f.pack(); f.setVisible(true); } }