All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jdesktop.jxlayer.plaf.ext.SpotLightUI Maven / Gradle / Ivy

/**
 * Copyright (c) 2006-2008, Alexander Potochkin
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the JXLayer project nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.jdesktop.jxlayer.plaf.ext;

import org.jdesktop.jxlayer.JXLayer;
import org.jdesktop.jxlayer.plaf.AbstractBufferedLayerUI;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

/**
 * SpotLightUI paints the layer as is and then
 * it paints translucent mask on the top.
 * 

* Here you can see the example of overridden {@code contains()} method, * which implements a custom mouseEvent filter;
* A mouseEvent will be processed only if any of added shapes contain its coordinates *

* The mask is generated with help of the {@code paintLayer()};
* The perfomance if very good because most of the time the cached image is used, * and it is repainted only when the layer is resized * or when {@code setDirty(true)} is called) * * @see #paint(Graphics,JComponent) * @see #contains(JComponent,int,int) */ public class SpotLightUI extends AbstractBufferedLayerUI { /** * Clip list. */ private ArrayList clipList = new ArrayList(); /** * Overlay color for the non-matching items. */ private Color overlayColor; /** * Width of the "soft border" */ private int softClipWidth; /** * Creates an instance of SpotLightUI */ public SpotLightUI() { this(0); } /** * Creates an instance of SpotLightUI with the specified width * of the "soft border" * * @param softClipWidth the width of the "soft border" */ public SpotLightUI(int softClipWidth) { this(new Color(0, 0, 0, 128), softClipWidth); } /** * Creates an instance of SpotLightUI with the specified width * of the "soft border" and overlay color, which is usually translucent. * * @param overlayColor the overlay color * @param softClipWidth the width of the "soft border" */ public SpotLightUI(final Color overlayColor, int softClipWidth) { setOverlayColor(overlayColor); setSoftClipWidth(softClipWidth); } private void softClipping(Graphics2D g2, Shape shape) { g2.setComposite(AlphaComposite.Src); for (int i = 0; i < softClipWidth; i++) { int alpha = (i + 1) * overlayColor.getAlpha() / (softClipWidth + 1); Color temp = new Color( overlayColor.getRed(), overlayColor.getGreen(), overlayColor.getBlue(), alpha); g2.setColor(temp); g2.setStroke(new BasicStroke(softClipWidth - i)); g2.draw(shape); } } /** * Returns the overlay color used for spotlight effect * * @return the overlay color used for spotlight effect */ public Color getOverlayColor() { return overlayColor; } /** * Sets the overlay color used for spotlight effect * * @param overlayColor the overlay color used for spotlight effect */ public void setOverlayColor(Color overlayColor) { if (overlayColor == null) { throw new IllegalArgumentException("overlayColor is null"); } Color oldColor = getOverlayColor(); this.overlayColor = overlayColor; firePropertyChange("overlayColor", oldColor, overlayColor); setDirty(true); } /** * Gets the width for the "soft border" * * @return the width for the "soft border" */ public int getSoftClipWidth() { return softClipWidth; } /** * Sets the width for the "soft border" * * @param softClipWidth the width for the "soft border" */ public void setSoftClipWidth(int softClipWidth) { if (softClipWidth < 0) { throw new IllegalArgumentException("softClipWidth can't be less than 0"); } int oldClipWidth = getSoftClipWidth(); this.softClipWidth = softClipWidth; firePropertyChange("softClipWidth", oldClipWidth, softClipWidth); setDirty(true); } /** * Resets this SpotLightUI. */ public void reset() { clipList.clear(); setDirty(true); } /** * Adds the specified shape to the slip list. * * @param shape Shape to add to the clip list. */ public void addShape(Shape shape) { clipList.add(shape); setDirty(true); } /** * We don't want to update the buffer of this painter * for every component's repainting, so this method returns {@code false} * and it makes the painting much faster * * @param l the {@code JXLayer} being painted * @return {@code false} to disable the incremental update mode */ protected boolean isIncrementalUpdate(JXLayer l) { return false; } /** * {@inheritDoc} */ @Override public void paint(Graphics g, JComponent c) { //always paint the layer as is c.paint(g); //and then call the super implementation super.paint(g, c); } /** * {@inheritDoc} */ @Override protected void paintLayer(Graphics2D g2, JXLayer l) { //note that we don't call super.paintLayer() here //since layer is already painted by paint() method. //The SpotLight mask is regenerated after setDirty(true) is called //or after layer changes its size g2.setComposite(AlphaComposite.Clear); g2.fillRect(0, 0, l.getWidth(), l.getHeight()); g2.setComposite(AlphaComposite.SrcOver); g2.setColor(overlayColor); g2.fillRect(0, 0, l.getWidth(), l.getHeight()); for (Shape shape : clipList) { g2.setClip(shape); g2.setComposite(AlphaComposite.Clear); g2.fill(shape); softClipping(g2, shape); } } /** * {@inheritDoc} */ @Override public boolean contains(JComponent c, int x, int y) { for (Shape shape : clipList) { if (shape.contains(x, y)) { return true; } } return false; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy