/** * Copyright (C) 2015 Valkyrie RCP * * 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 org.valkyriercp.form.binding.jide; import com.jidesoft.swing.DefaultOverlayable; import com.jidesoft.swing.Overlayable; import com.jidesoft.swing.OverlayableUtils; import org.valkyriercp.util.ObjectUtils; import javax.swing.*; import java.awt.*; /** * Repaint manager to be employed when using <code>JideBindingFactory</code> in order to make overlay support work. * <p> * Employs an <em>invasive</em> approach since extends from {@link RepaintManager}. Employing delegate methods would be * preferred but there are some tricky effects discovered when dealing with <a * href="http://jirabluebell.b2b2000.com/browse/BLUE-41">BLUE-41 issue</a>. * * <p> * Overrides {@link #addDirtyRegion(JComponent, int, int, int, int)} in order to repaint overlayables just after * invoking delegate method. This is a way to avoid rewriting <code>repaint</code> for every component class!! ...like * in <code>OverlayTextArea</code>: * * <pre> * @Override * public void repaint(long tm, int x, int y, int width, int height) { * * super.repaint(tm, x, y, width, height); * OverlayableUtils.repaintOverlayable(this); * } * </pre> * <p> * According to <a href="http://forums.sun.com/thread.jspa?threadID=725127">this thread</a> the "unique" way to listen * for repaint changes is overriding <code>RepaintManager</code>. This is not a recommended practice but works anyway... * <p> * <b>Note</b> this class implements singleton. * * @author <a href = "mailto:julio.arguello@gmail.com" >Julio Arg??ello (JAF)</a> * * * @since 20101228 */ public class JideRepaintManager extends RepaintManager { /** * The singleton instance. */ private static JideRepaintManager instance; /** * Creates the repaint manager given its delegate. */ public JideRepaintManager() { super(); } /** * {@inheritDoc} */ @Override public void addDirtyRegion(JComponent c, int x, int y, int w, int h) { super.addDirtyRegion(c, x, y, w, h); // Aditional behaviour this.repaintOverlayable(c); } /** * Repaints the parent container of the target component if that is a <code>DefaultOverlayable</code> instance. * * @param c * the child component. */ protected void repaintOverlayable(JComponent c) { final Container parent = c.getParent(); if ((!(c instanceof Overlayable)) && (parent != null) && (parent instanceof DefaultOverlayable)) { OverlayableUtils.repaintOverlayable(c); } } /** * Gets the singleton instance initialized in a lazy mode (useful for reducing race conditions probability). * * @return the jide repaint manager. */ public static JideRepaintManager getInstance() { if (JideRepaintManager.instance == null) { JideRepaintManager.instance = new JideRepaintManager(); } return JideRepaintManager.instance; } /** * Installs this repaint manager if not already set. * * @see ObjectUtils#shallowCopy(Object, Object) */ public static void installJideRepaintManagerIfNeeded() { final RepaintManager current = RepaintManager.currentManager(null); if (current != JideRepaintManager.getInstance()) { // (JAF), 20110101, This is needed unless for setting a suitable PaintManager on target (RepaintManager // seems to be over-protected). ObjectUtils.shallowCopy(current, JideRepaintManager.getInstance()); RepaintManager.setCurrentManager(JideRepaintManager.getInstance()); } } }