com.googlecode.blaisemath.graphics.swing.JGraphicSelectionHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.blaisemath.graphics.swing.JGraphicSelectionHandler.java

Source

/**
 * JGraphicSelectionHandler.java
 * Created Aug 1, 2012
 */
package com.googlecode.blaisemath.graphics.swing;

/*
 * #%L
 * BlaiseGraphics
 * --
 * Copyright (C) 2009 - 2015 Elisha Peterson
 * --
 * 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.
 * #L%
 */

import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.Sets;
import com.googlecode.blaisemath.graphics.core.Graphic;
import com.googlecode.blaisemath.style.AttributeSet;
import com.googlecode.blaisemath.style.StyleHints;
import com.googlecode.blaisemath.style.Styles;
import com.googlecode.blaisemath.util.CanvasPainter;
import com.googlecode.blaisemath.util.SetSelectionModel;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collections;
import java.util.Set;

/**
 * <p>
 *  Mouse handler that enables selection on a composite graphic object.
 *  Control must be down for any selection capability.
 * </p>
 * @param <G> type of render canvas
 * @author elisha
 */
public final class JGraphicSelectionHandler<G> extends MouseAdapter implements CanvasPainter<Graphics2D> {

    /** Whether selector is enabled */
    private boolean enabled = true;
    /** Determines which objects can be selected */
    private final JGraphicComponent component;
    /** Model of selected items */
    private final SetSelectionModel<Graphic<Graphics2D>> selection = new SetSelectionModel<Graphic<Graphics2D>>();

    /** Style for drawing selection box */
    private AttributeSet selectionBoxStyle = Styles.fillStroke(new Color(128, 128, 255, 32),
            new Color(0, 0, 128, 64));

    private transient Point pressPt;
    private transient Point dragPt;
    private transient Rectangle2D.Double selectionBox = null;

    /** 
     * Initialize for specified component
     * @param compt the component for handling 
     */
    public JGraphicSelectionHandler(JGraphicComponent compt) {
        this.component = compt;

        // highlight updates
        selection.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                Set<Graphic> old = (Set<Graphic>) evt.getOldValue();
                Set<Graphic> nue = (Set<Graphic>) evt.getNewValue();
                for (Graphic g : Sets.difference(old, nue)) {
                    g.getStyleHints().remove(StyleHints.SELECTED_HINT);
                }
                for (Graphic g : Sets.difference(nue, old)) {
                    g.getStyleHints().put(StyleHints.SELECTED_HINT, true);
                }
            }
        });
    }

    //<editor-fold defaultstate="collapsed" desc="PROPERTIES">
    //
    // PROPERTIES
    //

    public SetSelectionModel<Graphic<Graphics2D>> getSelectionModel() {
        return selection;
    }

    public boolean isSelectionEnabled() {
        return enabled;
    }

    public void setSelectionEnabled(boolean enabled) {
        if (this.enabled != enabled) {
            this.enabled = enabled;
            if (!enabled) {
                selection.setSelection(Collections.<Graphic<Graphics2D>>emptySet());
            }
        }
    }

    public AttributeSet getStyle() {
        return selectionBoxStyle;
    }

    public void setStyle(AttributeSet style) {
        this.selectionBoxStyle = checkNotNull(style);
    }

    //</editor-fold>

    @Override
    public void paint(Component component, Graphics2D canvas) {
        if (enabled && selectionBox != null && selectionBox.width > 0 && selectionBox.height > 0) {
            ShapeRenderer.getInstance().render(selectionBox, selectionBoxStyle, canvas);
        }
    }

    //<editor-fold defaultstate="collapsed" desc="MOUSE GESTURE HANDLERS">

    @Override
    public void mouseMoved(MouseEvent e) {
        if (e.isConsumed()) {
            return;
        }
        Graphic g = component.selectableGraphicAt(e.getPoint());
        Graphic gAll = component.functionalGraphicAt(e.getPoint());
        if (gAll == null) {
            // reset to default if there is no active mouse graphic
            component.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
        } else if (g != null) {
            // identify selectable graphics when you mouse over them
            component.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (!enabled || !(e.getButton() == MouseEvent.BUTTON1) || e.isConsumed()) {
            return;
        }
        if (!e.isControlDown()) {
            selection.setSelection(Collections.<Graphic<Graphics2D>>emptySet());
            return;
        }
        Graphic<Graphics2D> g = component.selectableGraphicAt(e.getPoint());
        if (g == null) {
            selection.setSelection(Collections.<Graphic<Graphics2D>>emptySet());
        } else if (e.isShiftDown()) {
            selection.deselect(g);
        } else if (e.isAltDown()) {
            selection.select(g);
        } else {
            selection.toggleSelection(g);
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        if (!enabled || e.isConsumed() || !(e.getButton() == MouseEvent.BUTTON1) || !e.isControlDown()) {
            return;
        }
        pressPt = e.getPoint();
        if (selectionBox == null) {
            selectionBox = new Rectangle2D.Double();
        }
        selectionBox.setFrameFromDiagonal(pressPt, pressPt);
        e.consume();
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (!enabled || e.isConsumed() || selectionBox == null || pressPt == null) {
            return;
        }
        dragPt = e.getPoint();
        selectionBox.setFrameFromDiagonal(pressPt, dragPt);
        if (e.getSource() instanceof Component) {
            ((Component) e.getSource()).repaint();
        }
        e.consume();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        if (!enabled || e.isConsumed() || selectionBox == null || pressPt == null) {
            return;
        }
        Point releasePt = e.getPoint();
        if (component.getInverseTransform() == null) {
            selectionBox.setFrameFromDiagonal(pressPt, releasePt);
        } else {
            selectionBox.setFrameFromDiagonal(component.toGraphicCoordinate(pressPt),
                    component.toGraphicCoordinate(releasePt));
        }
        if (selectionBox.getWidth() > 0 && selectionBox.getHeight() > 0) {
            Set<Graphic<Graphics2D>> gg = component.getGraphicRoot().selectableGraphicsIn(selectionBox);
            if (e.isShiftDown()) {
                Set<Graphic<Graphics2D>> res = Sets.newHashSet(selection.getSelection());
                res.removeAll(gg);
                gg = res;
            } else if (e.isAltDown()) {
                gg.addAll(selection.getSelection());
            }
            selection.setSelection(gg);
        }
        selectionBox = null;
        pressPt = null;
        dragPt = null;
        component.repaint();
        e.consume();
    }

    //</editor-fold>

}