/* * $Id$ * * Copyright 2009 Sun Microsystems, Inc., 4150 Network Circle, * Santa Clara, California 95054, U.S.A. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.jdesktop.swingx.plaf.basic; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; /** * Extension to allow for experimenting with pluggable Rendering- and/or * HeaderHandler. * * @author Jeanette Winzenburg */ public class DemoMonthViewUI extends BasicMonthViewUI { public static final String RENDERING_HANDLER_KEY = "monthView.renderingHandler"; public static final String RENDERING_HANDLER_CLASS_NAME_KEY = "monthView.renderingHandlerClassName"; /** * {@inheritDoc} <p> * * Overridden to support lookup of handler/class name and return it, if available. * Returns a new intance of type DemoCalendarRenderingHandler otherwise. */ @Override protected CalendarRenderingHandler createRenderingHandler() { String handlerClass = null; // <snip> Custom CalendarRenderingHandler // the handler is responsible for providing and configuring // components to render the cells of a month box. The mechanism // is very similar to renderers in the collection views. // Custom implementations can support extended visuals, by // adding Highlighters or StringValues. if (monthView != null) { // lookup per-monthView handler instance Object handler = monthView.getClientProperty(RENDERING_HANDLER_KEY); if (handler instanceof CalendarRenderingHandler) { return (CalendarRenderingHandler) handler; } } // look per-application handler class name handlerClass = UIManager.getString(RENDERING_HANDLER_CLASS_NAME_KEY); if (handlerClass != null) { try { Class<?> clazz = Class.forName(handlerClass); return (CalendarRenderingHandler) clazz.newInstance(); } catch (Exception e) { // no success - fall back to default } } // </snip> // fallback to default return new DemoCalendarRenderingHandler(); } /** * {@inheritDoc} <p> * * Overridden to support a per-component header handler. */ @Override protected CalendarHeaderHandler createCalendarHeaderHandler() { // <snip> Custom CalendarHeaderHandler // the HeaderHandler is responsible to provide a component used // as header of a month box if the monthView's zoomable property is enabled. // This component is added to the monthView box which allows direct // user interaction with it and its children. if (monthView != null) { // lookup per-instance handler Object handler = monthView.getClientProperty(CalendarHeaderHandler.uiControllerID); if (handler instanceof CalendarHeaderHandler) { return (CalendarHeaderHandler) handler; } } // </snip> // fallback to super (which does a for a per-application handler class name lookup // before falling back to a do-nothing base ;-) return super.createCalendarHeaderHandler(); } //------------------------ updates on property changes related to handlers /** * Updates the RenderingHandler if the monthView's client property has changed. */ protected void updateRenderingHandler() { // <snip> Custom CalendarRenderingHandler setRenderingHandler(createRenderingHandler()); monthView.revalidate(); monthView.repaint(); // </snip> } /** * Updates the header handler if the monthView's zoomable property * has changed. */ protected void updateHeaderHandler() { // <snip> Custom CalendarHeaderHandler // super is not yet prepared for dynamical setting of header handler // so have to take over here: uninstall the old and install the new if (monthView.isZoomable()) { // cleanup old monthView.remove(getCalendarHeaderHandler().getHeaderComponent()); getCalendarHeaderHandler().uninstall(monthView); // create and install new setCalendarHeaderHandler(createCalendarHeaderHandler()); getCalendarHeaderHandler().install(monthView); updateZoomable(); } // <snip> } /** * {@inheritDoc} <p> * * Overridden to update header and rendering handlers on property * change of the monthView */ @Override protected PropertyChangeListener createPropertyChangeListener() { final PropertyChangeListener r = super.createPropertyChangeListener(); PropertyChangeListener ml = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (RENDERING_HANDLER_KEY.equals(evt.getPropertyName())) { updateRenderingHandler(); } else if (CalendarHeaderHandler.uiControllerID.equals(evt.getPropertyName())) { updateHeaderHandler(); } else { r.propertyChange(evt); } } }; return ml; } @SuppressWarnings({"UnusedDeclaration"}) public static ComponentUI createUI(JComponent c) { return new DemoMonthViewUI(); } }