001    // GraphLab Project: http://graphlab.sharif.edu
002    // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
003    // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/
004    package graphlab.ui;
005    
006    import graphlab.platform.attribute.AttributeListener;
007    import graphlab.platform.attribute.AttributeSet;
008    import graphlab.platform.parameter.Parameter;
009    import graphlab.platform.parameter.Parametrizable;
010    import graphlab.ui.components.utils.GAttrFrame;
011    
012    import javax.swing.*;
013    import java.lang.reflect.Field;
014    import java.lang.reflect.Method;
015    import java.util.HashMap;
016    import java.util.Map;
017    
018    /**
019     * this class provides the ability to show and edit the parametr of a
020     * parametrizable object with a property editor
021     *
022     * @author azin azadi
023     */
024    public class ParameterShower implements AttributeListener {
025        private Object o;
026    
027        /**
028         * show all the fields of the object which have setter and getter in a property editor in runtime
029         * so you can change them easily
030         *
031         * @param o
032         */
033        public void show(Object o) {
034            try {
035                this.o = o;
036                PortableNotifiableAttributeSetImpl p = new PortableNotifiableAttributeSetImpl();
037                p.addAttributeListener(this);
038                for (Method m : o.getClass().getMethods()) {
039                    String name = m.getName();
040                    if (name.startsWith("set")) {
041                        name = name.substring(3);
042                        System.out.println(m.getName() + "," + name);
043    
044                        Method getter = null;
045                        try {
046                            getter = o.getClass().getMethod("get" + name, new Class[0]);
047                        } catch (Exception e) {
048    //                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
049                        }
050                        if (getter != null) {
051                            p.put(name, getter.invoke(o, (Object[]) new Class[0]));
052                        }
053                    }
054    
055                }
056                GAttrFrame.showEditDialog(p, false);
057            } catch (Exception e) {
058                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
059            }
060    
061        }
062    
063    //    public void attributeUpdated(String name, Object oldVal, Object newVal) {
064    //        if (o == null)
065    //            return;
066    //        try {
067    //            Method m = o.getClass().getMethod("set" + name, newVal.getClass());
068    //            m.invoke(o, newVal);
069    ////            Field f = o.getClass().getField(name);
070    ////            f.set(o, newVal);
071    //        } catch (Exception e) {
072    //            System.err.println("err on " + name);
073    ////            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
074    //        }
075    //    }
076    
077        public boolean xshow(Object o) {
078            try {
079                this.o = o;
080                PortableNotifiableAttributeSetImpl p = new PortableNotifiableAttributeSetImpl();
081                p.addAttributeListener(this);
082                for (Field f : o.getClass().getFields()) {
083                    Parameter anot = f.getAnnotation(Parameter.class);
084    //                System.out.println(anot);
085    //                System.out.println(f.getName());
086                    if (anot != null) {
087                        addField(p, f, o, anot.name(), anot.description());
088                    }
089                }
090                return GAttrFrame.showEditDialog(p, true).getReturnStatus();
091            }
092            catch (Exception e) {
093                e.printStackTrace();
094            }
095            return false;
096        }
097    
098        public boolean show(Parametrizable p) {
099            boolean finished = false;
100            while (!finished) {
101                boolean b = xshow(p);
102                if (!b) {
103                    return false;   //cancelled
104                }
105                String s = p.checkParameters();
106                if (s == null)
107                    finished = true;
108                else
109                    JOptionPane.showMessageDialog(null, s);
110            }
111            while (p.checkParameters() != null) ;
112            return true;
113        }
114    
115        /**
116         * if f is an AttributeSet adds its members to the p
117         *
118         * @param p
119         * @param f
120         * @param o
121         * @param name
122         * @param desc
123         * @throws IllegalAccessException
124         */
125        private void addField(PortableNotifiableAttributeSetImpl p, Field f, Object o, String name, String desc) throws IllegalAccessException {
126            if (AttributeSet.class.isAssignableFrom(f.getType())) {
127                if (f.get(o) instanceof AttributeSet) {
128                    AttributeSet as = (AttributeSet) f.get(o);
129                    for (Map.Entry<String, Object> x : as.getAttrs().entrySet()) {
130                        String nam = "atrset." + f.getName() + "." + x.getKey();
131                        p.put(nam, x.getValue());
132                        p.getView().setDisplayName(nam, x.getKey());
133                    }
134                }
135            } else {
136                p.put(f.getName(), f.get(o));
137                if (!name.equals(""))
138                    p.getView().setDisplayName(f.getName(), name);
139                p.getView().setDescription(f.getName(), desc);
140            }
141        }
142    
143        HashMap<String, String> names = new HashMap<String, String>();
144    
145        public void attributeUpdated(String name, Object oldVal, Object newVal) {
146            try {
147                if (name.startsWith("atrset")) {
148                    name = name.substring(7);
149                    String atn = name.substring(0, name.indexOf("."));
150                    String fn = name.substring(name.indexOf(".") + 1);
151                    Object field = o.getClass().getDeclaredField(atn).get(o);
152                    if (field instanceof AttributeSet) {
153                        AttributeSet attributeSet = (AttributeSet) field;
154                        attributeSet.put(fn, newVal);
155                    }
156                } else {
157                    o.getClass().getDeclaredField(name).set(o, newVal);
158                }
159            } catch (IllegalAccessException e) {
160    //            e.printStackTrace();
161            } catch (NoSuchFieldException e) {
162    //            e.printStackTrace();
163            }
164        }
165    }