001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2016 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; 025import javax.swing.tree.TreeModel; 026import javax.swing.tree.TreePath; 027 028import com.puppycrawl.tools.checkstyle.api.DetailAST; 029 030/** 031 * The model that backs the parse tree in the GUI. 032 * 033 * @author Lars Kühne 034 */ 035public class ParseTreeTableModel implements TreeModel { 036 /** Presentation model. */ 037 private final ParseTreeTablePModel pModel; 038 039 /** 040 * A list of event listeners for the tree model. 041 */ 042 private final EventListenerList listenerList = new EventListenerList(); 043 044 /** 045 * @param parseTree DetailAST parse tree. 046 */ 047 public ParseTreeTableModel(DetailAST parseTree) { 048 pModel = new ParseTreeTablePModel(parseTree); 049 setParseTree(parseTree); 050 } 051 052 /** 053 * Sets parse tree. 054 * @param parseTree DetailAST parse tree. 055 */ 056 protected final void setParseTree(DetailAST parseTree) { 057 pModel.setParseTree(parseTree); 058 final Object[] path = {pModel.getRoot()}; 059 // no need to setup remaining info, as the call results in a 060 // table structure changed event anyway - we just pass nulls 061 fireTreeStructureChanged(this, path, null, (Object[]) null); 062 } 063 064 /** 065 * @return the number of available column. 066 */ 067 public int getColumnCount() { 068 return pModel.getColumnCount(); 069 } 070 071 /** 072 * @param column the column number 073 * @return the name for column number {@code column}. 074 */ 075 public String getColumnName(int column) { 076 return pModel.getColumnName(column); 077 } 078 079 /** 080 * @param column the column number 081 * @return the type for column number {@code column}. 082 */ 083 public Class<?> getColumnClass(int column) { 084 return pModel.getColumnClass(column); 085 } 086 087 /** 088 * @param node the node 089 * @param column the column number 090 * @return the value to be displayed for node {@code node}, 091 * at column number {@code column}. 092 */ 093 public Object getValueAt(Object node, int column) { 094 return pModel.getValueAt(node, column); 095 } 096 097 @Override 098 public Object getChild(Object parent, int index) { 099 return pModel.getChild(parent, index); 100 } 101 102 @Override 103 public int getChildCount(Object parent) { 104 return pModel.getChildCount(parent); 105 } 106 107 @Override 108 public void valueForPathChanged(TreePath path, Object newValue) { 109 // No Code, as tree is read-only 110 } 111 112 @Override 113 public Object getRoot() { 114 return pModel.getRoot(); 115 } 116 117 @Override 118 public boolean isLeaf(Object node) { 119 return pModel.isLeaf(node); 120 } 121 122 // This is not called in the JTree's default mode: use a naive implementation. 123 @Override 124 public int getIndexOfChild(Object parent, Object child) { 125 return pModel.getIndexOfChild(parent, child); 126 } 127 128 @Override 129 public void addTreeModelListener(TreeModelListener listener) { 130 listenerList.add(TreeModelListener.class, listener); 131 } 132 133 @Override 134 public void removeTreeModelListener(TreeModelListener listener) { 135 listenerList.remove(TreeModelListener.class, listener); 136 } 137 138 /** 139 * Notify all listeners that have registered interest for 140 * 'tree structure changed' event. The event instance 141 * is lazily created using the parameters passed into 142 * the fire method. 143 * @param source The Object responsible for generating the event. 144 * @param path An array of Object identifying the path to the parent of the modified items. 145 * @param childIndices An array of int that specifies the index values of the removed items. 146 * @param children An array of Object containing the inserted, removed, or changed objects. 147 * @see EventListenerList 148 */ 149 private void fireTreeStructureChanged(Object source, Object[] path, 150 int[] childIndices, 151 Object... children) { 152 // Guaranteed to return a non-null array 153 final Object[] listeners = listenerList.getListenerList(); 154 TreeModelEvent event = null; 155 // Process the listeners last to first, notifying 156 // those that are interested in this event 157 for (int i = listeners.length - 2; i >= 0; i -= 2) { 158 if (listeners[i] == TreeModelListener.class) { 159 // Lazily create the event: 160 if (event == null) { 161 event = new TreeModelEvent(source, path, 162 childIndices, children); 163 } 164 ((TreeModelListener) listeners[i + 1]).treeStructureChanged(event); 165 } 166 } 167 } 168 169 /** 170 * Indicates whether the the value for node {@code node}, 171 * at column number {@code column} is editable. 172 * 173 * @param column the column number 174 * @return true if editable 175 */ 176 public boolean isCellEditable(int column) { 177 return pModel.isCellEditable(column); 178 } 179}