/* * Beanfabrics Framework Copyright (C) by Michael Karneim, beanfabrics.org * Use is subject to license terms. See license.txt. */ package org.beanfabrics.swing.customizer.util; import java.awt.Component; import java.awt.Window; import java.beans.Customizer; import java.lang.reflect.Type; import javax.swing.LookAndFeel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import org.beanfabrics.IModelProvider; import org.beanfabrics.ModelSubscriber; import org.beanfabrics.Path; import org.beanfabrics.View; import org.beanfabrics.ViewClassDecorator; import org.beanfabrics.context.Context; import org.beanfabrics.meta.PathNode; import org.beanfabrics.meta.TypeInfo; import org.beanfabrics.model.IListPM; import org.beanfabrics.model.PMManager; import org.beanfabrics.model.PresentationModel; import org.beanfabrics.swing.customizer.path.PathChooserController; import org.beanfabrics.swing.customizer.path.PathContext; import org.beanfabrics.util.GenericType; /** * <p> * ATTENTION: This class is experimental and should only be used inside beanfabrics. * </p> * The <code>CustomizerUtil</code> is a utility class used by JavaBeans {@link Customizer} classes in Beanfabrics. * * @author Michael Karneim */ public class CustomizerUtil { private static final String OS_NAME = System.getProperty("os.name").toLowerCase(); private CustomizerUtil() { } private static void setLookAndFeel(Component comp) throws Exception { if (isInEclipse()) { LookAndFeel oldLaF = UIManager.getLookAndFeel(); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); SwingUtilities.updateComponentTreeUI(comp); UIManager.setLookAndFeel(oldLaF); } } private static boolean isInEclipse() { try { Class.forName("org.eclipse.core.runtime.Platform"); return true; } catch (Exception ex) { return false; } } public static boolean isWindows() { return OS_NAME.startsWith("windows"); } public static boolean isMacOSX() { return OS_NAME.startsWith("mac os"); } public static boolean isAquaLookAndFeel() { return UIManager.getLookAndFeel().getID().equals("Aqua"); } public static PathChooserController createPathChooser(Context context, PathContext pathContext, Path initialPath) { PathChooserController ctrl = new PathChooserController(context, pathContext); ctrl.getPresentationModel().setData( initialPath); ctrl.getView().setModal(true); return ctrl; } public static RootWindowLocator getRootWindowLocator(final Component comp) { return new RootWindowLocator() { public Window getRootWindow() { Component result = SwingUtilities.getRoot(comp); if (result instanceof Window) { return (Window) result; } return null; } }; } public static Window locateRootWindow(PresentationModel pm) { return locateRootWindow(pm.getContext()); } public static Window locateRootWindow(Context context) { Window result; RootWindowLocator loc = context.getService(RootWindowLocator.class); if (loc == null) { result = null; } else { result = loc.getRootWindow(); } return result; } public static TypeInfo getTypeInfo(Class<? extends PresentationModel> pmClass) { if (pmClass == null) { return null; } return PMManager.getInstance().getMetadata().getTypeInfo(pmClass); } public static PathNode asRootNode(Class<? extends PresentationModel> pmClass) { if (pmClass == null) { return null; } return PMManager.getInstance().getMetadata().getPathNode(pmClass); } static Class<? extends PresentationModel> getDeclaredPmTypeFromView(ModelSubscriber aSubscriber) { if (aSubscriber instanceof View<?>) { View<?> view = (View<?>) aSubscriber; return getDeclaredPmTypeFromView(view); } return PresentationModel.class; } public static Class<? extends PresentationModel> getDeclaredPmTypeFromView(View<?> view) { @SuppressWarnings("unchecked") Class<? extends View<?>> viewClass = (Class<? extends View<?>>) view.getClass(); return getDeclaredPmTypeFromView(viewClass); } public static Class<? extends PresentationModel> getDeclaredPmTypeFromView(Class<? extends View<?>> viewClass) { ViewClassDecorator viewDeco = new ViewClassDecorator(viewClass); return viewDeco.getExpectedModelType(); } public static Class<? extends PresentationModel> getElementTypeOfSubscribedOrActualIListPM(ModelSubscriber subscriber) { PathNode pmNode = getSubscribedNode(subscriber); if (pmNode == null && subscriber instanceof View<?>) { pmNode = getRootNodeOfActualOrDeclaredPMFromView((View<?>) subscriber); } if (isIListPM(pmNode)) { return getElementTypeOfIListPM(pmNode); } return null; } private static Class<? extends PresentationModel> getElementTypeOfIListPM(PathNode pmNode) { if ( !isIListPM(pmNode)) { throw new IllegalArgumentException(String.format("pmNode must represent %s, but was %s!", IListPM.class.getSimpleName(), pmNode.getTypeInfo())); } GenericType gt = pmNode.getGenericType(); GenericType typeParam = gt.getTypeParameter(IListPM.class.getTypeParameters()[0]); Type tArg = typeParam.narrow(typeParam.getType(), PresentationModel.class); if (tArg instanceof Class) { @SuppressWarnings("unchecked") Class<? extends PresentationModel> result = (Class<? extends PresentationModel>) tArg; return result; } else { throw new IllegalStateException("Unexpected type: " + tArg.getClass().getName()); } } private static boolean isIListPM(PathNode pmNode) { return pmNode != null && IListPM.class.isAssignableFrom(pmNode.getTypeInfo().getJavaType()); } public static PathNode getSubscribedNode(ModelSubscriber subscriber) { IModelProvider provider = subscriber.getModelProvider(); Path path = subscriber.getPath(); if (path != null && provider != null) { return asRootNode(provider.getPresentationModelType()).getNode(path); } return null; } public static PathNode getProvidedRootNode(ModelSubscriber subscriber) { IModelProvider provider = subscriber.getModelProvider(); if (provider != null) { return asRootNode(provider.getPresentationModelType()); } return null; } public static PathNode getRootNodeOfActualOrDeclaredPMFromView(View<?> view) { PresentationModel actualPM = view.getPresentationModel(); if (actualPM != null) { return asRootNode(actualPM.getClass()); } return asRootNode(getDeclaredPmTypeFromView(view)); } public static PathContext getPathContextToCustomizeModelSubscriber(ModelSubscriber theSubscriber) { return getPathContextToCustomizeModelSubscriber(theSubscriber, getDeclaredPmTypeFromView(theSubscriber)); } public static PathContext getPathContextToCustomizeModelSubscriber(ModelSubscriber theSubscriber, Class<? extends PresentationModel> expectedModelType) { PathNode rootInfo = getProvidedRootNode(theSubscriber); if (rootInfo == null) { return null; } return new PathContext(rootInfo, getTypeInfo(expectedModelType)); } }