001package kiwi.ui.propeditor; 002 003import java.awt.*; 004import java.awt.event.*; 005import java.util.*; 006import javax.swing.*; 007import javax.swing.border.*; 008import javax.swing.event.*; 009import javax.swing.tree.*; 010 011import kiwi.ui.*; 012import kiwi.ui.model.*; 013 014/* 015 * 016 * @author Mark Lindner 017 */ 018 019class PropertyCellEditor implements TreeCellEditor, TreeCellRenderer, 020 ActionListener 021 { 022 private Border _border, _noborder; 023 private KLabel label, editorLabel; 024 private PropertyValueEditor editor = null; 025 private KPanel editorPanel; 026 protected EventListenerList listenerList = new EventListenerList(); 027 transient protected ChangeEvent changeEvent = null; 028 private PropertyValueEditor fixedEditor = new FixedValueEditor(); 029 private _MouseListener mouseListener; 030 private Hashtable editors; 031 private PropertyEditorFactory factory; 032 033 /* 034 */ 035 036 PropertyCellEditor(PropertyEditorFactory factory) 037 { 038 this.factory = factory; 039 040 editorPanel = new KPanel(); 041 editorPanel.setLayout(new BorderLayout(5, 5)); 042 043 _border = new UnderlineBorder(); 044 _noborder = new EmptyBorder(0, 0, 1, 0); 045 046 editorLabel = new KLabel(); 047 editorLabel.setBorder(_noborder); 048 mouseListener = new _MouseListener(); 049 editorLabel.addMouseListener(mouseListener); 050 editorPanel.add("West", editorLabel); 051 052 editors = new Hashtable(); 053 054 label = new KLabel(); 055 label.setBorder(_noborder); 056 } 057 058 /* 059 */ 060 061 void setEditorFactory(PropertyEditorFactory factory) 062 { 063 editors.clear(); 064 this.factory = factory; 065 } 066 067 /* 068 */ 069 070 private PropertyValueEditor getEditor(PropertyType type) 071 { 072 PropertyValueEditor ed = (PropertyValueEditor)editors.get(type); 073 if(ed == null) 074 { 075 ed = factory.createEditor(type); 076 if(ed != null) 077 editors.put(type, ed); 078 } 079 080 return(ed); 081 } 082 083 /* 084 */ 085 086 public synchronized Component getTreeCellEditorComponent(JTree tree, 087 Object value, 088 boolean selected, 089 boolean expanded, 090 boolean leaf, 091 int row) 092 { 093 JComponent c; 094 Property prop = null; 095 096 if(editor != null) 097 { 098 c = editor.getEditorComponent(); 099 editor.removeActionListener(this); 100 editorPanel.remove(c); 101 } 102 103 editor = null; 104 105 if(value instanceof Property) 106 { 107 prop = (Property)value; 108 109 PropertyType type = prop.getType(); 110 111 if(type != null && prop.isEditable()) 112 editor = getEditor(type); 113 114 if(editor == null) 115 editor = fixedEditor; 116 117 editor.setProperty(prop); 118 editorLabel.setIcon(prop.getIcon()); 119 editorLabel.setText(prop.getName() + ":"); 120 } 121 122 // do we actually have an editor after all those checks? 123 124 if(editor != null) 125 { 126 c = editor.getEditorComponent(); 127 editor.addActionListener(this); 128 editorPanel.add("Center", c); 129// c.setBorder(_noborder); 130 editor.startFocus(); 131 } 132 133 return(editorPanel); 134 } 135 136 /* 137 */ 138 139 public synchronized Component getTreeCellRendererComponent(JTree tree, 140 Object value, 141 boolean selected, 142 boolean expanded, 143 boolean leaf, 144 int row, 145 boolean hasFocus) 146 { 147 if(value instanceof Property) 148 { 149 Property prop = (Property)value; 150 151 label.setIcon(prop.getIcon()); 152 label.setText(prop.toString()); 153 label.setBorder(prop.isEditable() ? _border : _noborder); 154 } 155 else 156 { 157 label.setText("?"); 158 label.setIcon(null); 159 label.setBorder(null); 160 } 161 162 return(label); 163 } 164 165 /* 166 */ 167 168 public boolean isCellEditable(EventObject evt) 169 { 170 return(true); 171 } 172 173 /* 174 */ 175 176 public boolean shouldSelectCell(EventObject evt) 177 { 178 if(editor != null) 179 editor.startFocus(); 180 181 return(true); 182 } 183 184 /* 185 */ 186 187 public void addCellEditorListener(CellEditorListener listener) 188 { 189 listenerList.add(CellEditorListener.class, listener); 190 } 191 192 /* 193 */ 194 195 public void removeCellEditorListener(CellEditorListener listener) 196 { 197 listenerList.remove(CellEditorListener.class, listener); 198 } 199 200 /* 201 */ 202 203 protected void fireEditingStopped() 204 { 205 // Guaranteed to return a non-null array 206 207 Object[] listeners = listenerList.getListenerList(); 208 // Process the listeners last to first, notifying 209 // those that are interested in this event 210 for (int i = listeners.length-2; i>=0; i-=2) 211 { 212 if (listeners[i]==CellEditorListener.class) 213 { 214 // Lazily create the event: 215 if (changeEvent == null) 216 changeEvent = new ChangeEvent(this); 217 ((CellEditorListener)listeners[i+1]).editingStopped(changeEvent); 218 } 219 } 220 } 221 222 /* 223 */ 224 225 protected void fireEditingCanceled() 226 { 227 // Guaranteed to return a non-null array 228 Object[] listeners = listenerList.getListenerList(); 229 // Process the listeners last to first, notifying 230 // those that are interested in this event 231 for(int i = listeners.length - 2; i >= 0; i -= 2) 232 { 233 if(listeners[i] == CellEditorListener.class) 234 { 235 // Lazily create the event: 236 if(changeEvent == null) 237 changeEvent = new ChangeEvent(this); 238 ((CellEditorListener)listeners[i + 1]).editingCanceled(changeEvent); 239 } 240 } 241 } 242 243 /* 244 */ 245 246 public void cancelCellEditing() 247 { 248 fireEditingCanceled(); 249 } 250 251 /* 252 */ 253 254 public boolean stopCellEditing() 255 { 256 if(editor == null) 257 return(true); 258 259 boolean ok = editor.validateInput(); 260 261 if(ok) 262 { 263 editor.commitInput(); 264 fireEditingStopped(); 265 } 266 267 return(ok); 268 } 269 270 /* 271 */ 272 273 public Object getCellEditorValue() 274 { 275 return((editor == null) ? null : editor.getProperty().getValue()); 276 } 277 278 /* 279 */ 280 281 public void actionPerformed(ActionEvent evt) 282 { 283 stopCellEditing(); 284 } 285 286 /* 287 */ 288 289 private class UnderlineBorder extends AbstractBorder 290 { 291 private Insets _insets = new Insets(0, 0, 1, 0); 292 293 UnderlineBorder() 294 { 295 super(); 296 } 297 298 public void paintBorder(java.awt.Component c, Graphics g, int x, int y, 299 int width, int height) 300 { 301 Color oldColor = g.getColor(); 302 303 g.setColor(Color.gray); 304 g.drawLine(x, y + height - 1, x + width - 1, y + height - 1); 305 306 g.setColor(oldColor); 307 } 308 309 public Insets getBorderInsets() 310 { 311 return(_insets); 312 } 313 314 public Insets getBorderInsets(Component c, Insets insets) 315 { 316 insets.left = insets.top = insets.right = 0; 317 insets.bottom = 1; 318 319 return(insets); 320 } 321 } 322 323 /* 324 */ 325 326 private class _MouseListener extends MouseAdapter 327 { 328 public void mouseClicked(MouseEvent evt) 329 { 330 if(editor != null) 331 { 332 editor.startFocus(); 333 } 334 } 335 } 336 } 337 338/* end of source file */