Package edu.mit.blocks.codeblockutil

Source Code of edu.mit.blocks.codeblockutil.GlassCard$GlassButton

package edu.mit.blocks.codeblockutil;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JComponent;

import edu.mit.blocks.codeblockutil.CScrollPane.ScrollPolicy;

/**
* A GlassCard is used by glass explorers explorers as a
* mediator to their canvases.
*
* It wraps a button, a scrollpane, and a invoker.
*
* The button uses information about the current color
* and highlight of the canvas to dipict itself.  The
* scrollpane takes the canvas and puts it inside a scroll
* pane so that users can navigate a very large canvas
* in small space.  The invoker respnds to button presses
* and invokes the right method in the explorer.
*/
public class GlassCard implements ActionListener, PropertyChangeListener {

    /** the index of the button in the explorer */
    private int index;
    /** the parent explorer */
    private Explorer explorer;
    /** the canvas that is wrapped by this card */
    private Canvas canvas;
    /** The button of this */
    private CButton button;
    /** The scroll that canvas lives in */
    private CScrollPane scroll;
    private final static int SCROLLBAR_WIDTH = 18;

    /**
     * constructor
     * @param i
     * @param canvas
     * @param ex
     */
    GlassCard(int i, Canvas canvas, GlassExplorer ex) {
        this.index = i;
        this.explorer = ex;
        this.canvas = canvas;
        this.button = new GlassButton(canvas.getColor(), canvas.getColor().brighter().brighter().brighter(), canvas.getName());
        //this.button.setMaximumSize(new Dimension(0,10));
        //this.button.setPreferredSize(new Dimension(0,10));
        this.scroll = new CGlassScrollPane(
                canvas.getJComponent(),
                ScrollPolicy.VERTICAL_BAR_AS_NEEDED,
                ScrollPolicy.HORIZONTAL_BAR_NEVER,
                SCROLLBAR_WIDTH, canvas.getColor(),
                new Color(100, 100, 100, 100));
        canvas.getJComponent().setOpaque(false);
        button.addActionListener(this);
        canvas.getJComponent().addPropertyChangeListener(this);
        this.scroll.setPreferredSize(
                new Dimension(canvas.getJComponent().getPreferredSize().width + SCROLLBAR_WIDTH,
                canvas.getJComponent().getPreferredSize().height));
    }

    /**
     * When the user presses the button, the explorer selects the
     * corresponding canvas
     */
    public void actionPerformed(ActionEvent e) {
        explorer.selectCanvas(index);
    }

    /**
     * @return the button
     */
    JComponent getButton() {
        return button;
    }

    /**
     * @return the scroll
     */
    JComponent getScroll() {
        return scroll;
    }

    /**
     * @return the background color of the glass pane
     */
    Color getBackgorundColor() {
        return new Color(
                canvas.getColor().getRed(),
                canvas.getColor().getGreen(),
                canvas.getColor().getBlue(), 150);
    }

    public void propertyChange(PropertyChangeEvent e) {
        if (e.getPropertyName().equals(Canvas.LABEL_CHANGE)) {
            button.repaint();
        }
        if (e.getSource().equals(canvas) && e.getPropertyName().equals("preferredSize")) {
            this.scroll.setPreferredSize(
                    new Dimension(canvas.getJComponent().getPreferredSize().width + SCROLLBAR_WIDTH,
                    canvas.getJComponent().getPreferredSize().height));
        }
    }

    private class GlassButton extends CButton {

        private static final long serialVersionUID = 328149080429L;
        //To get the shadow effect the text must be displayed multiple times at
        //multiple locations.  x represents the center, white label.
        // o is color values (0,0,0,0.5f) and b is black.
        //        o o
        //      o x b o
        //      o b o
        //        o
        //offsetArrays representing the translation movement needed to get from
        // the center location to a specific offset location given in {{x,y},{x,y}....}
        //..........................................grey points.............................................black points
        private final int[][] shadowPositionArray = {{0, -1}, {1, -1}, {-1, 0}, {2, 0}, {-1, 1}, {1, 1}, {0, 2}, {1, 0}, {0, 1}};
        private final float[] shadowColorArray = {0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0, 0};
        private double offsetSize = 1;

        public GlassButton(Color buttonColor, Color selectedColor, String text) {
            super(buttonColor, selectedColor, text);
        }

        public void paint(Graphics g) {
            // Set up graphics and buffer
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            BufferedImage buffer = GraphicsManager.gc.createCompatibleImage(this.getWidth(), this.getHeight(), Transparency.TRANSLUCENT);
            Graphics2D gb = buffer.createGraphics();
            gb.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // Set up first layer
            int buttonHeight = this.getHeight() - INSET * 2;
            int buttonWidth = this.getWidth() - INSET * 2;
            int arc = buttonHeight;

            if (this.pressed || this.selected) {
                g2.setPaint(new GradientPaint(0, -buttonHeight, Color.darkGray, 0, buttonHeight, canvas.getColor(), false));
                g2.fillRoundRect(INSET, INSET, buttonWidth, buttonHeight, arc, arc);
                g2.setColor(Color.darkGray);
                g2.drawRoundRect(INSET, INSET, buttonWidth, buttonHeight, arc, arc);
            } else {
                //paint highlightlayer
                if (this.focus) {
                    gb.setColor(Color.yellow);
                    gb.setStroke(new BasicStroke(3));
                    gb.drawRoundRect(INSET, INSET, buttonWidth, buttonHeight, arc, arc);
                    gb.setStroke(new BasicStroke(1));
                }
                // Paint the first layer
                gb.setColor(canvas.getColor().darker());
                gb.fillRoundRect(INSET, INSET, buttonWidth, buttonHeight, arc, arc);
                gb.setColor(Color.darkGray);
                gb.drawRoundRect(INSET, INSET, buttonWidth, buttonHeight, arc, arc);

                // set up paint data fields for second layer

                int highlightHeight = buttonHeight * 2 / 3;
                int highlightWidth = buttonWidth;
                int highlightArc = highlightHeight;

                // Paint the second layer
                gb.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .8f));

                gb.setColor(canvas.getColor());
                gb.setClip(new RoundRectangle2D.Float(INSET, INSET, highlightWidth, highlightHeight, highlightArc, highlightArc));
                gb.fillRoundRect(INSET, INSET, buttonWidth, buttonHeight, arc, arc);

                // Blur
                ConvolveOp blurOp = new ConvolveOp(new Kernel(3, 3, BLUR));
                BufferedImage blurredImage = blurOp.filter(buffer, null);

                // Draw button
                g2.drawImage(blurredImage, 1, 1, null);
            }
            // Draw the text (if any)
            String text = canvas.getName();
            if (text != null && buttonHeight > 4) {
                //Font font = g2.getFont().deriveFont((float)(((float)this.getHeight()) * .6));
                Font font = g2.getFont().deriveFont((float) (this.getHeight() - INSET * 2 - 2) * .7f);
                g2.setFont(font);
                FontMetrics metrics = g2.getFontMetrics();
                Rectangle2D textBounds = metrics.getStringBounds(text, g2);
                float x = (float) ((this.getWidth() / 2) - (textBounds.getWidth() / 2));
                float y = (float) ((this.getHeight() / 2) + (textBounds.getHeight() / 2)) - metrics.getDescent();

                g.setColor(Color.black);
                for (int i = 0; i < shadowPositionArray.length; i++) {
                    int dx = shadowPositionArray[i][0];
                    int dy = shadowPositionArray[i][1];
                    g2.setColor(new Color(0, 0, 0, shadowColorArray[i]));
                    g2.drawString(text, x + (int) ((dx) * offsetSize), y + (int) ((dy) * offsetSize));
                }
                if (canvas.getHighlight() != null) {
                    g.setColor(canvas.getHighlight());
                } else {
                    g.setColor(Color.white);
                }
                g2.drawString(text, x, y);
            }
            if (canvas.getHighlight() != null) {
                g2.setStroke(new BasicStroke(3));
                g2.setColor(canvas.getHighlight());
                g2.drawRoundRect(INSET + 1, INSET + 1, buttonWidth - 2, buttonHeight - 2, arc, arc);
                g2.setStroke(new BasicStroke(1));
            }
        }
    }
}
TOP

Related Classes of edu.mit.blocks.codeblockutil.GlassCard$GlassButton

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.