1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.scenegraph.g2d.nodes.provisional;
\r
14 import java.awt.geom.Rectangle2D;
\r
15 import java.beans.PropertyChangeEvent;
\r
16 import java.beans.PropertyChangeListener;
\r
17 import java.lang.reflect.Field;
\r
18 import java.lang.reflect.Modifier;
\r
19 import java.util.HashMap;
\r
20 import java.util.Map;
\r
21 import java.util.concurrent.ConcurrentHashMap;
\r
23 import org.simantics.scenegraph.g2d.G2DNode;
\r
26 * @author Antti Villberg
\r
28 public abstract class GraphPropertyNode extends G2DNode {
\r
30 private static final long serialVersionUID = 245761992671850588L;
\r
32 private static Map<Class<? extends GraphPropertyNode>, Map<String, Field>> fieldCache = new ConcurrentHashMap<Class<? extends GraphPropertyNode>, Map<String, Field>>();
\r
34 protected transient final Map<String, Field> fields;
\r
36 private PropertyChangeListener fieldListener = null;
\r
38 protected GraphPropertyNode() {
\r
39 this.fields = getFields(getClass());
\r
43 public void init() {
\r
45 addEventHandler(this);
\r
49 public void cleanup() {
\r
50 removeEventHandler(this);
\r
54 public void setFieldListener(PropertyChangeListener listener) {
\r
55 this.fieldListener = listener;
\r
58 public void propertyChange(String field, Object value) {
\r
61 public void setProperty(String field, Object value) {
\r
62 Field f = fields.get(field);
\r
64 System.err.println("GraphPropertyNode tried to set undefined property '" + field + "'");
\r
68 //System.out.println("setting field '" + field + "'");
\r
70 propertyChange(field, value);
\r
71 } catch (IllegalArgumentException e) {
\r
72 e.printStackTrace();
\r
73 } catch (IllegalAccessException e) {
\r
74 e.printStackTrace();
\r
78 public void commitProperty(String field, Object value) {
\r
79 if (fieldListener != null) {
\r
80 fieldListener.propertyChange(new PropertyChangeEvent(this, field, null, value));
\r
84 public boolean hitTest(double x, double y, double tolerance) {
\r
89 public Rectangle2D getBoundsInLocal() {
\r
93 private static Map<String, Field> getFields(Class<? extends GraphPropertyNode> clazz) {
\r
94 Map<String, Field> fields = fieldCache.get(clazz);
\r
97 fields = calculateFields(clazz);
\r
98 fieldCache.put(clazz, fields);
\r
102 private static Map<String, Field> calculateFields(Class<? extends GraphPropertyNode> clazz) {
\r
103 Map<String, Field> result = new HashMap<String, Field>();
\r
104 for (Class<?> cls = clazz; cls != null && !GraphPropertyNode.class.equals(cls); cls = clazz.getSuperclass()) {
\r
105 for (Field f : cls.getFields()) {
\r
106 int mod = f.getModifiers();
\r
107 if (Modifier.isStatic(mod))
\r
109 if (Modifier.isTransient(mod))
\r
111 if (Modifier.isFinal(mod))
\r
113 if (!result.containsKey(f.getName()))
\r
114 result.put(f.getName(), f);
\r