1 /*******************************************************************************
2 * Copyright (c) 2010 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.scenegraph.g2d.nodes.provisional;
14 import java.awt.geom.Rectangle2D;
15 import java.beans.PropertyChangeEvent;
16 import java.beans.PropertyChangeListener;
17 import java.lang.reflect.Field;
18 import java.lang.reflect.Modifier;
19 import java.util.HashMap;
21 import java.util.concurrent.ConcurrentHashMap;
23 import org.simantics.scenegraph.g2d.G2DNode;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * @author Antti Villberg
30 public abstract class GraphPropertyNode extends G2DNode {
32 private static final Logger LOGGER = LoggerFactory.getLogger(GraphPropertyNode.class);
33 private static final long serialVersionUID = 245761992671850588L;
35 private static Map<Class<? extends GraphPropertyNode>, Map<String, Field>> fieldCache = new ConcurrentHashMap<Class<? extends GraphPropertyNode>, Map<String, Field>>();
37 protected transient final Map<String, Field> fields;
39 private PropertyChangeListener fieldListener = null;
41 protected GraphPropertyNode() {
42 this.fields = getFields(getClass());
48 addEventHandler(this);
52 public void cleanup() {
53 removeEventHandler(this);
57 public void setFieldListener(PropertyChangeListener listener) {
58 this.fieldListener = listener;
61 public void propertyChange(String field, Object value) {
64 public void setProperty(String field, Object value) {
65 Field f = fields.get(field);
67 LOGGER.warn("GraphPropertyNode tried to set undefined property '" + field + "'");
71 //System.out.println("setting field '" + field + "'");
73 propertyChange(field, value);
74 } catch (IllegalArgumentException e) {
76 } catch (IllegalAccessException e) {
81 public void commitProperty(String field, Object value) {
82 if (fieldListener != null) {
83 fieldListener.propertyChange(new PropertyChangeEvent(this, field, null, value));
87 public boolean hitTest(double x, double y, double tolerance) {
92 public Rectangle2D getBoundsInLocal() {
96 private static Map<String, Field> getFields(Class<? extends GraphPropertyNode> clazz) {
97 Map<String, Field> fields = fieldCache.get(clazz);
100 fields = calculateFields(clazz);
101 fieldCache.put(clazz, fields);
105 private static Map<String, Field> calculateFields(Class<? extends GraphPropertyNode> clazz) {
106 Map<String, Field> result = new HashMap<String, Field>();
107 for (Class<?> cls = clazz; cls != null && !GraphPropertyNode.class.equals(cls); cls = clazz.getSuperclass()) {
108 for (Field f : cls.getFields()) {
109 int mod = f.getModifiers();
110 if (Modifier.isStatic(mod))
112 if (Modifier.isTransient(mod))
114 if (Modifier.isFinal(mod))
116 if (!result.containsKey(f.getName()))
117 result.put(f.getName(), f);