001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2015 the original author or authors. 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018//////////////////////////////////////////////////////////////////////////////// 019 020package com.puppycrawl.tools.checkstyle.gui; 021 022import javax.swing.event.EventListenerList; 023import javax.swing.event.TreeModelEvent; 024import javax.swing.event.TreeModelListener; 025 026/** 027 * An abstract implementation of the TreeTableModel interface, handling 028 * the list of listeners. 029 * 030 * <a href= 031 * "https://docs.oracle.com/cd/E48246_01/apirefs.1111/e13403/oracle/ide/controls/TreeTableModel.html"> 032 * Original Source Location</a> 033 * 034 * @author Philip Milne 035 */ 036public abstract class AbstractTreeTableModel implements TreeTableModel { 037 038 /** 039 * The root node of the tree table model. 040 */ 041 private final Object root; 042 043 /** 044 * A list of event listeners for the tree model. 045 */ 046 private final EventListenerList listenerList = new EventListenerList(); 047 048 /** 049 * Initializes the root node for the tree table model. 050 * 051 * @param root Root node. 052 */ 053 AbstractTreeTableModel(Object root) { 054 this.root = root; 055 } 056 057 // 058 // Default implementations for methods in the TreeModel interface. 059 // 060 061 @Override 062 public Object getRoot() { 063 return root; 064 } 065 066 @Override 067 public boolean isLeaf(Object node) { 068 return getChildCount(node) == 0; 069 } 070 071 // This is not called in the JTree's default mode: use a naive implementation. 072 @Override 073 public int getIndexOfChild(Object parent, Object child) { 074 for (int i = 0; i < getChildCount(parent); i++) { 075 if (getChild(parent, i).equals(child)) { 076 return i; 077 } 078 } 079 return -1; 080 } 081 082 @Override 083 public void addTreeModelListener(TreeModelListener listener) { 084 listenerList.add(TreeModelListener.class, listener); 085 } 086 087 @Override 088 public void removeTreeModelListener(TreeModelListener listener) { 089 listenerList.remove(TreeModelListener.class, listener); 090 } 091 092 /** 093 * Notifies all listeners that have registered interest for 094 * 'tree nodes changed' event. The event instance 095 * is lazily created using the parameters passed into 096 * the fire method. 097 * @param source The Object responsible for generating the event. 098 * @param path An array of Object identifying the path to the parent of the modified items. 099 * @param childIndices An array of int that specifies the index values of the removed items. 100 * @param children An array of Object containing the inserted, removed, or changed objects. 101 * @see EventListenerList 102 */ 103 protected void fireTreeNodesChanged(Object source, Object[] path, 104 int[] childIndices, 105 Object... children) { 106 // Guaranteed to return a non-null array 107 final Object[] listeners = listenerList.getListenerList(); 108 TreeModelEvent event = null; 109 // Process the listeners last to first, notifying 110 // those that are interested in this event 111 for (int i = listeners.length - 2; i >= 0; i -= 2) { 112 if (listeners[i] == TreeModelListener.class) { 113 // Lazily create the event: 114 if (event == null) { 115 event = new TreeModelEvent(source, path, 116 childIndices, children); 117 } 118 ((TreeModelListener) listeners[i + 1]).treeNodesChanged(event); 119 } 120 } 121 } 122 123 /** 124 * Notify all listeners that have registered interest for 125 * 'tree nodes inserted' event. The event instance 126 * is lazily created using the parameters passed into 127 * the fire method. 128 * @param source The Object responsible for generating the event. 129 * @param path An array of Object identifying the path to the parent of the modified items. 130 * @param childIndices An array of int that specifies the index values of the removed items. 131 * @param children An array of Object containing the inserted, removed, or changed objects. 132 * @see EventListenerList 133 */ 134 protected void fireTreeNodesInserted(Object source, Object[] path, 135 int[] childIndices, 136 Object... children) { 137 // Guaranteed to return a non-null array 138 final Object[] listeners = listenerList.getListenerList(); 139 TreeModelEvent event = null; 140 // Process the listeners last to first, notifying 141 // those that are interested in this event 142 for (int i = listeners.length - 2; i >= 0; i -= 2) { 143 if (listeners[i] == TreeModelListener.class) { 144 // Lazily create the event: 145 if (event == null) { 146 event = new TreeModelEvent(source, path, 147 childIndices, children); 148 } 149 ((TreeModelListener) listeners[i + 1]).treeNodesInserted(event); 150 } 151 } 152 } 153 154 /** 155 * Notify all listeners that have registered interest for 156 * 'tree nodes removed' event. The event instance 157 * is lazily created using the parameters passed into 158 * the fire method. 159 * @param source The Object responsible for generating the event. 160 * @param path An array of Object identifying the path to the parent of the modified items. 161 * @param childIndices An array of int that specifies the index values of the removed items. 162 * @param children An array of Object containing the inserted, removed, or changed objects. 163 * @see EventListenerList 164 */ 165 protected void fireTreeNodesRemoved(Object source, Object[] path, 166 int[] childIndices, 167 Object... children) { 168 // Guaranteed to return a non-null array 169 final Object[] listeners = listenerList.getListenerList(); 170 TreeModelEvent event = null; 171 // Process the listeners last to first, notifying 172 // those that are interested in this event 173 for (int i = listeners.length - 2; i >= 0; i -= 2) { 174 if (listeners[i] == TreeModelListener.class) { 175 // Lazily create the event: 176 if (event == null) { 177 event = new TreeModelEvent(source, path, 178 childIndices, children); 179 } 180 ((TreeModelListener) listeners[i + 1]).treeNodesRemoved(event); 181 } 182 } 183 } 184 185 /** 186 * Notify all listeners that have registered interest for 187 * 'tree structure changed' event. The event instance 188 * is lazily created using the parameters passed into 189 * the fire method. 190 * @param source The Object responsible for generating the event. 191 * @param path An array of Object identifying the path to the parent of the modified items. 192 * @param childIndices An array of int that specifies the index values of the removed items. 193 * @param children An array of Object containing the inserted, removed, or changed objects. 194 * @see EventListenerList 195 */ 196 void fireTreeStructureChanged(Object source, Object[] path, 197 int[] childIndices, 198 Object... children) { 199 // Guaranteed to return a non-null array 200 final Object[] listeners = listenerList.getListenerList(); 201 TreeModelEvent event = null; 202 // Process the listeners last to first, notifying 203 // those that are interested in this event 204 for (int i = listeners.length - 2; i >= 0; i -= 2) { 205 if (listeners[i] == TreeModelListener.class) { 206 // Lazily create the event: 207 if (event == null) { 208 event = new TreeModelEvent(source, path, 209 childIndices, children); 210 } 211 ((TreeModelListener) listeners[i + 1]).treeStructureChanged(event); 212 } 213 } 214 } 215 216 // 217 // Default implementations for methods in the TreeTableModel interface. 218 // 219 220 @Override 221 public Class<?> getColumnClass(int column) { 222 return Object.class; 223 } 224 225 /** By default, make the column with the Tree in it the only editable one. 226 * Making this column editable causes the JTable to forward mouse 227 * and keyboard events in the Tree column to the underlying JTree. 228 */ 229 @Override 230 public boolean isCellEditable(int column) { 231 return getColumnClass(column) == TreeTableModel.class; 232 } 233}