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

org.netbeans.modules.palette.ui.DropGlassPane Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.netbeans.modules.palette.ui;

import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;

import java.util.HashMap;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.UIManager;
import org.openide.awt.GraphicsUtils;


/**
 * Glass pane which is used for paint of a drop line over JComponent.
 *
 * @author  Jiri Rechtacek, S. Aubrecht
 *
 * @see java.awt.dnd.DropTarget
 * @see org.openide.explorer.view.TreeViewDropSupport
 */
final class DropGlassPane extends JPanel {
    private static final HashMap map = new HashMap<>();
    private static final int MIN_X = 0;//5;
    private static final int MIN_Y = 0;//3;
//    private static final int MIN_WIDTH = 0;//10;
    private static final int MIN_HEIGTH = 0;//3;
    private static Component oldPane;
    private static JComponent originalSource;
    private static boolean wasVisible;
    private Line2D line = null;
    private Rectangle prevLineRect = null;

    private DropGlassPane() {
    }

    /** Check the bounds of given line with the bounds of this pane. Optionally
     * calculate the new bounds in current pane's boundary.
     * @param comp
     * @return  */
    public static synchronized DropGlassPane getDefault(JComponent comp) {
        Integer id = System.identityHashCode(comp);

        if ((map.get(id)) == null) {
            DropGlassPane dgp = new DropGlassPane();
            dgp.setOpaque(false);
            map.put(id, dgp);
        }

        return map.get(id);
    }

    /** Stores the original glass pane on given tree.
     * @param source the active container
     * @param pane the original glass
     * @param visible was glass pane visible
     */
    static void setOriginalPane( JComponent source, Component pane, boolean visible ) {
        // pending, should throw an exception that original is set already
        oldPane = pane;
        originalSource = source;
        wasVisible = visible;
    }

    /** Is any original glass pane stored?
     * @return true if true; false otherwise
     */
    static boolean isOriginalPaneStored() {
        return oldPane != null;
    }

    /** Sets the original glass pane to the root pane of stored container.
     */
    static void putBackOriginal() {
        if (oldPane == null) {
            // pending, should throw an exception
            return;
        }

        originalSource.getRootPane().setGlassPane(oldPane);
        oldPane.setVisible(wasVisible);
        oldPane = null;
    }

    /** Unset drop line if setVisible to false.
     * @param boolean aFlag new state */
    @Override
    public void setVisible(boolean aFlag) {
        super.setVisible(aFlag);

        if (!aFlag) {
            setDropLine(null);
        }
    }

    /** Set drop line. Given line is used by paint method.
     * @param line drop line */
    public void setDropLine(Line2D line) {
        if( !isValid() )
            return;
        
        if( null != prevLineRect 
            && ((null != line
                && (!prevLineRect.contains( line.getP1() )
                    || !prevLineRect.contains( line.getP2() )))
                || null == line) ) {
            
            repaint( prevLineRect );
        }

        this.line = line;
        Rectangle newLineRect = null;
        if( null != this.line ) {
            checkLineBounds( this.line );
            newLineRect = line.getBounds();
            newLineRect.grow( 5, 5 );
        }
        
        if( null != newLineRect && !newLineRect.equals( prevLineRect ) ) {
            repaint( newLineRect );
        }
        prevLineRect = newLineRect;
    }

    /** Check the bounds of given line with the bounds of this pane. Optionally
     * calculate the new bounds in current pane's boundary.
     * @param line a line for check
     * @return  a line with bounds inside the pane's boundary */
    private Line2D checkLineBounds(Line2D line) {
        Rectangle bounds = getBounds();
        double startPointX;
        double startPointY;
        double endPointX;
        double endPointY;
        
        // check start point
        startPointX = Math.max(line.getX1(), bounds.x + MIN_X);
        startPointY = Math.max(line.getY1(), bounds.y + MIN_Y);

        // check end point
        endPointX = Math.min(line.getX2(), (bounds.x + bounds.width));// - MIN_WIDTH);
        endPointY = Math.min(line.getY2(), (bounds.y + bounds.height) - MIN_HEIGTH);

        // set new bounds
        line.setLine(startPointX, startPointY, endPointX, endPointY);

        return line;
    }

    /** Paint drop line on glass pane.
     * @param Graphics g Obtained graphics */
    @Override
    public void paint(Graphics g) {
        if (line != null) {
            g.setColor( UIManager.getColor( "Tree.selectionBackground" ) );

            int x1 = (int) line.getX1();
            int x2 = (int) line.getX2();
            int y1 = (int) line.getY1();
            int y2 = (int)line.getY2 ();

            if (g instanceof Graphics2D) {
                // create drop line shape
                Path2D shape = new Path2D.Float();
                if( y1 == y2 ) {
                    // horizontal line
                    shape.moveTo(x1, y1 - 3); // left-top edge
                    shape.lineTo(x1 + 3, y1); // horizontal line left
                    shape.lineTo(x2 - 3, y1); // horizontal line right
                    shape.lineTo(x2, y1 - 3); // right-top edge
                    shape.lineTo(x2, y1 + 5); // right-bottom edge
                    shape.lineTo(x2 - 3, y1 + 2); // horizontal line right
                    shape.lineTo(x1 + 3, y1 + 2); // horizontal line left
                    shape.lineTo(x1, y1 + 5); // left-bottom edge
                } else {
                    // vertical line
                    shape.moveTo(x1 - 3, y1); // left-top edge
                    shape.lineTo(x1, y1 + 3); // vertical line top
                    shape.lineTo(x1, y2 - 3); // vertical line bottom
                    shape.lineTo(x1 - 3, y2); // left-bottom edge
                    shape.lineTo(x1 + 5, y2); // right-bottom edge
                    shape.lineTo(x1 + 2, y2 - 3); // vertical line bottom
                    shape.lineTo(x1 + 2, y1 + 3); // vertical line top
                    shape.lineTo(x1 + 5, y1); // right-top edge
                }
                shape.closePath();

                // paint drop line shape
                GraphicsUtils.configureDefaultRenderingHints(g);
                ((Graphics2D)g).fill(shape);
            } else {
                // probably no longer used, but keep it for compatibility for the case
                // that graphics context is not a Graphics2D

                if( y1 == y2 ) {
                    // horizontal line
                    g.drawLine(x1 + 2, y1, x2 - 2, y1);
                    g.drawLine(x1 + 2, y1 + 1, x2 - 2, y1 + 1);

                    // left
                    g.drawLine(x1, y1 - 2, x1, y1 + 3);
                    g.drawLine(x1 + 1, y2 - 1, x1 + 1, y1 + 2);

                    // right
                    g.drawLine(x2, y1 - 2, x2, y1 + 3);
                    g.drawLine(x2 - 1, y1 - 1, x2 - 1, y1 + 2);
                } else {
                    // vertical line
                    g.drawLine(x1, y1 + 2, x2, y2 - 2);
                    g.drawLine(x1 + 1, y1 + 2, x2 + 1, y2 - 2);

                    // top
                    g.drawLine(x1 - 2, y1, x1 + 3, y1);
                    g.drawLine(x1 - 1, y1 + 1, x1 + 2, y1 + 1);

                    // bottom
                    g.drawLine(x2 - 2, y2, x2 + 3, y2);
                    g.drawLine(x2 - 1, y2 - 1, x2 + 2, y2 - 1);
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy