001package org.openstreetmap.gui.jmapviewer.checkBoxTree; 002 003import java.awt.BorderLayout; 004import java.awt.event.MouseAdapter; 005 006import javax.swing.JFrame; 007import javax.swing.JScrollPane; 008import javax.swing.JTree; 009import javax.swing.event.TreeModelEvent; 010import javax.swing.event.TreeModelListener; 011import javax.swing.event.TreeSelectionEvent; 012import javax.swing.event.TreeSelectionListener; 013import javax.swing.tree.DefaultMutableTreeNode; 014import javax.swing.tree.DefaultTreeModel; 015 016import org.openstreetmap.gui.jmapviewer.AbstractLayer; 017import org.openstreetmap.gui.jmapviewer.Layer; 018import org.openstreetmap.gui.jmapviewer.LayerGroup; 019 020/** 021 * JTree for checkBox Tree Layers 022 * 023 * @author galo 024 */ 025public class CheckBoxTree extends JTree{ 026 /** Serial Version UID */ 027 private static final long serialVersionUID = 6943401106938034256L; 028 029 private final CheckBoxNodeEditor editor; 030 031 public CheckBoxTree(AbstractLayer layer){ 032 this(new CheckBoxNodeData(layer)); 033 } 034 public CheckBoxTree(String rootName){ 035 this(new CheckBoxNodeData(rootName)); 036 } 037 public CheckBoxTree(CheckBoxNodeData root ){ 038 this(new DefaultMutableTreeNode(root)); 039 } 040 public CheckBoxTree(DefaultMutableTreeNode node){ 041 super(new DefaultTreeModel(node)); 042 043 final CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer(); 044 setCellRenderer(renderer); 045 046 editor = new CheckBoxNodeEditor(this); 047 setCellEditor(editor); 048 setEditable(true); 049 050 // listen for changes in the model (including check box toggles) 051 getModel().addTreeModelListener(new TreeModelListener() { 052 @Override 053 public void treeNodesChanged(final TreeModelEvent e) { 054 DefaultTreeModel model = (DefaultTreeModel)e.getSource(); 055 Object[] nodes = e.getChildren(); 056 DefaultMutableTreeNode node; 057 if(nodes==null||nodes.length==0){ 058 node = node(model.getRoot()); 059 }else{ 060 node = node(nodes[0]); 061 } 062 nodeChanged(node); 063 repaint(); 064 } 065 066 @Override 067 public void treeNodesInserted(final TreeModelEvent e) { 068 //System.out.println("nodes inserted"); 069 } 070 071 @Override 072 public void treeNodesRemoved(final TreeModelEvent e) { 073 //System.out.println("nodes removed"); 074 } 075 076 @Override 077 public void treeStructureChanged(final TreeModelEvent e) { 078 //System.out.println("structure changed"); 079 } 080 }); 081 } 082 public void addNodeListener(MouseAdapter listener){ 083 editor.addNodeListener(listener); 084 } 085 public static void main(final String args[]) { 086 final DefaultMutableTreeNode root = new DefaultMutableTreeNode(new CheckBoxNodeData("Root",true)); 087 088 final DefaultMutableTreeNode accessibility = 089 add(root, "Accessibility", true); 090 add(accessibility, "Move system caret with focus/selection changes", false); 091 add(accessibility, "Always expand alt text for images", true); 092 root.add(accessibility); 093 094 final DefaultMutableTreeNode browsing = 095 new DefaultMutableTreeNode(new CheckBoxNodeData("Browsing", null)); 096 add(browsing, "Notify when downloads complete", true); 097 add(browsing, "Disable script debugging", true); 098 add(browsing, "Use AutoComplete", true); 099 add(browsing, "Browse in a new process", false); 100 root.add(browsing); 101 102 final CheckBoxTree tree = new CheckBoxTree(root); 103 ((DefaultMutableTreeNode)tree.getModel().getRoot()).add(new DefaultMutableTreeNode(new CheckBoxNodeData("gggg", null))); 104 ((DefaultTreeModel)tree.getModel()).reload(); 105 // listen for changes in the selection 106 tree.addTreeSelectionListener(new TreeSelectionListener() { 107 @Override 108 public void valueChanged(final TreeSelectionEvent e) { 109 //System.out.println("selection changed"); 110 } 111 }); 112 // show the tree on screen 113 final JFrame frame = new JFrame("CheckBox Tree"); 114 final JScrollPane scrollPane = new JScrollPane(tree); 115 frame.getContentPane().add(scrollPane, BorderLayout.CENTER); 116 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 117 frame.setSize(300, 150); 118 frame.setVisible(true); 119 } 120 private static Boolean childStatus(DefaultMutableTreeNode node){ 121 Boolean status = data(node.getChildAt(0)).isSelected(); 122 for(int i=1; i<node.getChildCount()&&status!=null; i++){ 123 if(status != data(node.getChildAt(i)).isSelected()) return null; 124 } 125 return status; 126 } 127 private static void changeParents(DefaultMutableTreeNode node){ 128 if(node!=null){ 129 DefaultMutableTreeNode parent = node(node.getParent()); 130 if(parent!=null){ 131 CheckBoxNodeData dataParent = data(parent); 132 Boolean childStatus = childStatus(parent); 133 if(dataParent.isSelected()!=childStatus){ 134 dataParent.setSelected(childStatus); 135 changeParents(parent); 136 } 137 } 138 } 139 } 140 private static void nodeChanged(DefaultMutableTreeNode node){ 141 if(node!=null){ 142 changeParents(node); 143 setChildrens(node, data(node).isSelected()); 144 } 145 } 146 private static void setChildrens(DefaultMutableTreeNode node, Boolean value){ 147 for(int i=0; i<node.getChildCount(); i++){ 148 DefaultMutableTreeNode childNode = node(node.getChildAt(i)); 149 if (data(childNode).isSelected() !=data(node).isSelected()){ 150 data(childNode).setSelected(data(node).isSelected()); 151 setChildrens(childNode, value); 152 } 153 } 154 } 155 public DefaultMutableTreeNode rootNode(){ 156 return node(getModel().getRoot()); 157 } 158 public LayerGroup rootLayer(){ 159 return (LayerGroup)rootData().getAbstractLayer(); 160 } 161 public CheckBoxNodeData rootData(){ 162 return data(rootNode()); 163 } 164 private static DefaultMutableTreeNode node(Object node){ 165 return (DefaultMutableTreeNode)node; 166 } 167 public static CheckBoxNodeData data(DefaultMutableTreeNode node){ 168 return node==null?null:(CheckBoxNodeData)node.getUserObject(); 169 } 170 private static CheckBoxNodeData data(Object node){ 171 return data(node(node)); 172 } 173 private static DefaultMutableTreeNode add(final DefaultMutableTreeNode parent, final String text, final boolean checked){ 174 final CheckBoxNodeData data = new CheckBoxNodeData(text, checked); 175 final DefaultMutableTreeNode node = new DefaultMutableTreeNode(data); 176 parent.add(node); 177 return node; 178 } 179 public static CheckBoxNodeData createNodeData(AbstractLayer layer){ 180 return new CheckBoxNodeData(layer); 181 } 182 public static DefaultMutableTreeNode createNode(AbstractLayer layer){ 183 return new DefaultMutableTreeNode(createNodeData(layer)); 184 } 185 /*public DefaultMutableTreeNode addLayerGroup(LayerGroup group){ 186 if(group!=null){ 187 if(group.getParent()==null){ 188 return add(rootNode(), group); 189 }else{ 190 DefaultMutableTreeNode parentGroup = searchNode(group.getParent()); 191 if(parentGroup==null) parentGroup = addLayerGroup(group.getParent()); 192 DefaultMutableTreeNode node = add(parentGroup, group); 193 return node; 194 } 195 }else return null; 196 }*/ 197 public Layer addLayer(String name){ 198 Layer layer = new Layer(name); 199 addLayer(layer); 200 return layer; 201 } 202 public DefaultMutableTreeNode addLayer(AbstractLayer layer){ 203 if (layer!=null){ 204 DefaultMutableTreeNode parent; 205 if(layer.getParent()==null){ 206 rootLayer().add(layer); 207 parent = rootNode(); 208 }else{ 209 parent = searchNode(layer.getParent()); 210 if(parent==null) parent=addLayer(layer.getParent()); 211 } 212 return add(parent, layer); 213 }else return null; 214 } 215 public DefaultMutableTreeNode add(DefaultMutableTreeNode parent, final AbstractLayer layer){ 216 layer.setVisible(data(parent).isSelected()); 217 DefaultMutableTreeNode node = createNode(layer); 218 parent.add(node); 219 ((DefaultTreeModel)getModel()).reload(); 220 //System.out.println("Created node "+layer+" upper of "+data(parent)); 221 return node; 222 } 223 public DefaultMutableTreeNode searchNode(AbstractLayer layer){ 224 return searchNode(rootNode(), layer); 225 } 226 public DefaultMutableTreeNode searchNode(DefaultMutableTreeNode node, AbstractLayer layer){ 227 CheckBoxNodeData data = CheckBoxTree.data(node); 228 if(data.getAbstractLayer() == layer) return node; 229 else{ 230 DefaultMutableTreeNode found = null; 231 for(int i=0; i<node.getChildCount() && found==null; i++){ 232 found = searchNode((DefaultMutableTreeNode)node.getChildAt(i), layer); 233 } 234 return found; 235 } 236 } 237}