/* * * GlassUI.java version 0.1 * * Copyright (C) 2008 Piet Blok. * * 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. * * Created on 4 aug 2008 */ package org.pbjar.jxlayer.test; import java.awt.Color; import java.awt.Graphics2D; import java.awt.MultipleGradientPaint; import java.awt.Paint; import java.awt.RadialGradientPaint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import org.jdesktop.jxlayer.JXLayer; /** * Shows a magnification glass on top of a component. * * @author Piet Blok */ public class MagnifierUI extends GeneralLayerUI { private class MyState extends GeneralLayerUI.StateObject { private int radius = radiusOptions[6]; private double magnifyingFactor = magnificationOptions[5]; private Point2D point = new Point2D.Double(); public double getMagnifyingFactor() { return magnifyingFactor; } public Point2D getPoint() { return point; } public int getRadius() { return radius; } public void setMagnifyingFactor(double magnifyingFactor) { this.magnifyingFactor = magnifyingFactor; } public void setPoint(Point2D point) { this.point.setLocation(point); } public void setRadius(int radius) { this.radius = radius; } } private static final Integer[] radiusOptions = new Integer[] { 20, 40, 60, 80, 100, 120, 140, 160, 180, 200 }; private static final Double[] magnificationOptions = new Double[] { 0.25, 0.5, 0.75, 1.0, 2.0, 4.0, 8.0, 16.0 }; @Override public List getActions(final JXLayer layer) { ArrayList actionList = new ArrayList(); actionList.addAll(super.getActions(layer)); /* * Set the magnifying factor */ actionList.add(new AbstractAction("Set magnification factor") { private static final long serialVersionUID = 1L; @SuppressWarnings("unchecked") @Override public void actionPerformed(ActionEvent event) { MyState state = (MyState) getStateObject(layer); Double current = state.getMagnifyingFactor(); int optionIndex = JOptionPane.showOptionDialog(layer, "Choose a magnification factor", "Choose magnification", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, magnificationOptions, current); if (optionIndex != JOptionPane.CLOSED_OPTION) { state .setMagnifyingFactor(magnificationOptions[optionIndex]); } } }); /* * Set the glass radius */ actionList.add(new AbstractAction("Set glass radius") { private static final long serialVersionUID = 1L; @Override public void actionPerformed(ActionEvent event) { MyState state = (MyState) getStateObject(layer); Integer current = state.getRadius(); int optionIndex = JOptionPane.showOptionDialog(layer, "Choose a glass radius", "Choose glass radius", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, radiusOptions, current); if (optionIndex != JOptionPane.CLOSED_OPTION) { state.setRadius(radiusOptions[optionIndex]); } } }); return actionList; } private Paint createPaint(Ellipse2D glass, boolean transparent) { Point2D center = new Point2D.Double(glass.getCenterX(), glass .getCenterY()); float radius = (float) (glass.getCenterX() - glass.getX()); Point2D focus = new Point2D.Double(center.getX() - 0.5 * radius, center .getY() - 0.5 * radius); Color[] colors = new Color[] { transparent ? new Color(255, 255, 255, 128) : Color.WHITE, transparent ? new Color(0, 255, 255, 32) : Color.CYAN }; float[] fractions = new float[] { 0f, 1f }; RadialGradientPaint paint = new RadialGradientPaint(center, radius, focus, fractions, colors, MultipleGradientPaint.CycleMethod.NO_CYCLE); return paint; } @Override protected StateObject createStateObject(JXLayer layer) { return new MyState(); } protected void paintLayer(Graphics2D g2, JXLayer layer) { super.paintLayer(g2, layer); MyState state = (MyState) getStateObject(layer); Point2D point = state.getPoint(); double scale = state.getMagnifyingFactor(); double baseRadius = state.getRadius(); double scaledRadius = (baseRadius / scale); double strokeAdjust = 0.5; double drawSize = 2 * (baseRadius + strokeAdjust); double clipSize = 2 * scaledRadius; Ellipse2D drawGlass = new Ellipse2D.Double(-strokeAdjust, -strokeAdjust, drawSize, drawSize); Ellipse2D clipGlass = new Ellipse2D.Double(0, 0, clipSize, clipSize); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); g2.translate(point.getX() - baseRadius, point.getY() - baseRadius); Color oldColor = g2.getColor(); g2.setPaint(createPaint(drawGlass, false)); g2.fill(drawGlass); g2.setColor(oldColor); g2.draw(drawGlass); AffineTransform oldTransform = g2.getTransform(); Shape oldClip = g2.getClip(); g2.scale(scale, scale); g2.clip(clipGlass); g2.translate(scaledRadius - point.getX(), scaledRadius - point.getY()); layer.paint(g2); g2.setTransform(oldTransform); g2.setClip(oldClip); g2.setPaint(createPaint(drawGlass, true)); g2.fill(drawGlass); } @Override protected void processMouseEvent(MouseEvent e, JXLayer layer) { super.processMouseEvent(e, layer); MyState state = (MyState) getStateObject(layer); state.setPoint(SwingUtilities.convertPoint(e.getComponent(), e .getPoint(), layer)); setDirty(true); } @Override protected void processMouseMotionEvent(MouseEvent e, JXLayer layer) { super.processMouseMotionEvent(e, layer); MyState state = (MyState) getStateObject(layer); state.setPoint(SwingUtilities.convertPoint(e.getComponent(), e .getPoint(), layer)); setDirty(true); } // @Override // protected void processMouseWheelEvent(MouseWheelEvent e, // JXLayer layer) { // super.processMouseWheelEvent(e, layer); // MyState state = (MyState) getStateObject(layer); // state.setPoint(SwingUtilities.convertPoint(e.getComponent(), e // .getPoint(), layer)); // System.out.println("Magnifier processed event"); // setDirty(true); // } }