Package com.palantir.ptoss.cinch.swing

Source Code of com.palantir.ptoss.cinch.swing.Wiring

//   Copyright 2011 Palantir Technologies
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
package com.palantir.ptoss.cinch.swing;

import java.awt.Component;
import java.awt.Point;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.beans.IntrospectionException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.apache.log4j.Logger;

import com.google.common.collect.Lists;
import com.palantir.ptoss.cinch.core.*;
import com.palantir.ptoss.util.Throwables;

/**
* A binding for an interface component that has a location (setLocation/getLocation methods).
*
* @see Point
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface BoundLocation {
    /**
     * The model property to bind to.
     */
    String to();

    /**
     * When this binding should occur.
     */
    String on() default "";

    /**
     * Inner utility class that performs the runtime wiring of all {@link BoundLocation} bindings.
     *
     * @see Bindings#STANDARD_BINDINGS
     */
    public static class Wiring implements BindingWiring {
        private static final Logger logger = Logger.getLogger(BoundLocation.class);

        public Collection<Binding> wire(BindingContext context) {
            List<Field> boundFields = context.getAnnotatedFields(BoundLocation.class);
            List<Binding> bindings = Lists.newArrayList();
            for (Field field : boundFields) {
                BoundLocation bound = field.getAnnotation(BoundLocation.class);
                try {
                    bindings.addAll(wire(bound, context, field));
                } catch (Exception e) {
                    throw Throwables.throwUncheckedException(e);
                }
            }
            return bindings;
        }

        private static Collection<Binding> wire(BoundLocation bound, BindingContext context, Field field) throws IntrospectionException {
            String target = bound.to();
            final ObjectFieldMethod setter = context.findSetter(target);
            final ObjectFieldMethod getter = context.findGetter(target);
            if (setter == null || getter == null) {
                throw new IllegalArgumentException("could not finder setter/getter for @BoundLocation: " + field);
            }
            final BindableModel model1 = context.getFieldObject(setter.getField(), BindableModel.class);
            final BindableModel model2 = context.getFieldObject(getter.getField(), BindableModel.class);
            assert model1 == model2;
            if (Component.class.isAssignableFrom(field.getType())) {
                final Component comp = context.getFieldObject(field, Component.class);
                return bindComponent(bound, context, comp, setter, getter, model1);
            } else {
                throw new IllegalArgumentException("don't know how to wire up @BoundLocation field: " + field.getName());
            }
        }

        private static Collection<Binding> bindComponent(BoundLocation bound,
                BindingContext context,
                final Component comp,
                final ObjectFieldMethod setter, final ObjectFieldMethod getter,
                final BindableModel model1) {

            String on = bound.on();
            final Object onObject = context.evalOnObject(on, model1);

            comp.addComponentListener(new ComponentAdapter() {
                @Override
                public void componentMoved(ComponentEvent e) {
                    try {
                        setter.getMethod().invoke(model1, comp.getLocation());
                    } catch (Exception ex) {
                        logger.error("could not invoke Component binding", ex);
                    }
                }
            });

            Binding binding = new Binding() {
                public <T extends Enum<?> & ModelUpdate> void update(T... changed) {
                    if (!BindingContext.isOn(onObject, changed)) {
                        return;
                    }
                    try {
                        Point point = (Point)getter.getMethod().invoke(model1);
                        comp.setLocation(point);
                    } catch (Exception ex) {
                        logger.error("could not invoke Component binding", ex);
                    }
                }
            };
            model1.bind(binding);
            return Collections.singleton(binding);
        }
    }
}
TOP

Related Classes of com.palantir.ptoss.cinch.swing.Wiring

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.