com.skcraft.launcher.swing.ObjectSwingMapper.java Source code

Java tutorial

Introduction

Here is the source code for com.skcraft.launcher.swing.ObjectSwingMapper.java

Source

/*
 * SK's Minecraft Launcher
 * Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
 * Please see LICENSE.txt for license information.
 */

package com.skcraft.launcher.swing;

import com.google.common.base.Strings;
import lombok.NonNull;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class ObjectSwingMapper {

    private final List<FieldMapping> mappings = new ArrayList<FieldMapping>();
    private final Object object;

    public ObjectSwingMapper(@NonNull Object object) {
        this.object = object;
    }

    public void copyFromObject() {
        for (FieldMapping mapping : mappings) {
            mapping.copyFromObject();
        }
    }

    public void copyFromSwing() {
        for (FieldMapping mapping : mappings) {
            mapping.copyFromSwing();
        }
    }

    private void add(@NonNull FieldMapping mapping) {
        mappings.add(mapping);
    }

    private <V> MutatorAccessorField<V> getField(@NonNull String field, Class<V> clazz) {
        return new MutatorAccessorField<V>(object, field, clazz);
    }

    public void map(@NonNull final JTextComponent textComponent, String name) {
        final MutatorAccessorField<String> field = getField(name, String.class);

        add(new FieldMapping() {
            @Override
            public void copyFromObject() {
                textComponent.setText(field.get());
            }

            @SuppressWarnings("unchecked")
            @Override
            public void copyFromSwing() {
                field.set(Strings.emptyToNull(textComponent.getText()));
            }
        });
    }

    public void map(@NonNull final JSpinner spinner, String name) {
        final MutatorAccessorField<Integer> field = getField(name, int.class);

        add(new FieldMapping() {
            @Override
            public void copyFromObject() {
                spinner.setValue(field.get());
            }

            @SuppressWarnings("unchecked")
            @Override
            public void copyFromSwing() {
                field.set((Integer) spinner.getValue());
            }
        });
    }

    public void map(@NonNull final JCheckBox check, String name) {
        final MutatorAccessorField<Boolean> field = getField(name, boolean.class);

        add(new FieldMapping() {
            @Override
            public void copyFromObject() {
                check.setSelected(field.get());
            }

            @SuppressWarnings("unchecked")
            @Override
            public void copyFromSwing() {
                field.set(check.isSelected());
            }
        });
    }

    public static interface FieldMapping {
        void copyFromObject();

        void copyFromSwing();
    }

    public static class MutatorAccessorField<V> {
        private final Class<V> clazz;
        private final Object object;
        private final Method mutator;
        private final Method accessor;

        public MutatorAccessorField(Object object, String name, Class<V> clazz) {
            this.object = object;
            this.clazz = clazz;

            Method mutator = null;
            Method accessor = null;
            for (Method method : object.getClass().getMethods()) {
                if (isAccessor(method, name)) {
                    accessor = method;
                } else if (isMutator(method, name)) {
                    mutator = method;
                }
            }

            if (accessor == null) {
                throw new NoSuchMethodError(
                        "Failed to find accessor pair on " + object.getClass().getCanonicalName() + " for " + name);
            }

            if (mutator == null) {
                throw new NoSuchMethodError(
                        "Failed to find mutator pair on " + object.getClass().getCanonicalName() + " for " + name);
            }

            this.mutator = mutator;
            this.accessor = accessor;
        }

        private boolean isAccessor(Method method, String name) {
            String methodName = method.getName();
            Class<?>[] paramTypes = method.getParameterTypes();
            Class<?> returnType = method.getReturnType();

            return (methodName.equalsIgnoreCase("get" + name) || methodName.equalsIgnoreCase("is" + name))
                    && paramTypes.length == 0 && clazz.isAssignableFrom(returnType);
        }

        private boolean isMutator(Method method, String name) {
            String methodName = method.getName();
            Class<?>[] paramTypes = method.getParameterTypes();

            return methodName.equalsIgnoreCase("set" + name) && paramTypes.length == 1
                    && paramTypes[0].isAssignableFrom(clazz);
        }

        @SuppressWarnings("unchecked")
        public V get() {
            try {
                Object value = accessor.invoke(object);
                return (V) value;
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        }

        public void set(V value) {
            try {
                mutator.invoke(object, value);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        }
    }

}