]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/provisional/GraphPropertyNode.java
b9ce6c012546c1f577dfb4a2465dd64b7a45197d
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / provisional / GraphPropertyNode.java
1 /*******************************************************************************
2  * Copyright (c) 2010 Association for Decentralized Information Management in
3  * Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.scenegraph.g2d.nodes.provisional;
13
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;
20 import java.util.Map;
21 import java.util.concurrent.ConcurrentHashMap;
22
23 import org.simantics.scenegraph.g2d.G2DNode;
24
25 /**
26  * @author Antti Villberg
27  */
28 public abstract class GraphPropertyNode extends G2DNode {
29
30     private static final long serialVersionUID = 245761992671850588L;
31
32     private static Map<Class<? extends GraphPropertyNode>, Map<String, Field>> fieldCache       = new ConcurrentHashMap<Class<? extends GraphPropertyNode>, Map<String, Field>>();
33
34     protected transient final Map<String, Field> fields;
35
36     private PropertyChangeListener               fieldListener = null;
37
38     protected GraphPropertyNode() {
39         this.fields = getFields(getClass());
40     }
41
42     @Override
43     public void init() {
44         super.init();
45         addEventHandler(this);
46     }
47
48     @Override
49     public void cleanup() {
50         removeEventHandler(this);
51         super.cleanup();
52     }
53
54     public void setFieldListener(PropertyChangeListener listener) {
55         this.fieldListener = listener;
56     }
57
58     public void propertyChange(String field, Object value) {
59     }
60
61     public void setProperty(String field, Object value) {
62         Field f = fields.get(field);
63         if (f == null) {
64             System.err.println("GraphPropertyNode tried to set undefined property '" + field + "'");
65             return;
66         }
67         try {
68             //System.out.println("setting field '" + field + "'");
69             f.set(this, value);
70             propertyChange(field, value);
71         } catch (IllegalArgumentException e) {
72             e.printStackTrace();
73         } catch (IllegalAccessException e) {
74             e.printStackTrace();
75         }
76     }
77
78     public void commitProperty(String field, Object value) {
79         if (fieldListener != null) {
80             fieldListener.propertyChange(new PropertyChangeEvent(this, field, null, value));
81         }
82     }
83
84     public boolean hitTest(double x, double y, double tolerance) {
85         return false;
86     }
87
88     @Override
89     public Rectangle2D getBoundsInLocal() {
90         return null;
91     }
92
93     private static Map<String, Field> getFields(Class<? extends GraphPropertyNode> clazz) {
94         Map<String, Field> fields = fieldCache.get(clazz);
95         if (fields != null)
96             return fields;
97         fields = calculateFields(clazz);
98         fieldCache.put(clazz, fields);
99         return fields;
100     }
101
102     private static Map<String, Field> calculateFields(Class<? extends GraphPropertyNode> clazz) {
103         Map<String, Field> result = new HashMap<String, Field>();
104         for (Class<?> cls = clazz; cls != null && !GraphPropertyNode.class.equals(cls); cls = clazz.getSuperclass()) {
105             for (Field f : cls.getFields()) {
106                 int mod = f.getModifiers();
107                 if (Modifier.isStatic(mod))
108                     continue;
109                 if (Modifier.isTransient(mod))
110                     continue;
111                 if (Modifier.isFinal(mod))
112                     continue;
113                 if (!result.containsKey(f.getName()))
114                     result.put(f.getName(), f);
115             }
116         }
117         return result;
118     }
119
120 }