/* * org.openmicroscopy.shoola.util.ui * *------------------------------------------------------------------------------ * Copyright (C) 2006-2008 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.util.ui; //Java imports import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.swing.JPanel; //Third-party libraries //Application-internal dependencies /** * The component where the rating levels are painted. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * <small> * (<b>Internal version:</b> $Revision: $Date: $) * </small> * @since OME3.0 */ class RatingCanvas extends JPanel implements MouseMotionListener { /** The number of pixels between two stars. */ static final int SPACE = 2; /** Reference to the model. */ private RatingComponent model; /** Collection of rectangles where the selected stars are located. */ private List<Rectangle> stars; /** Handles the mouse release. */ private MouseAdapter handler; /** Flag indicating an on-going dragging or not.*/ private boolean dragging; /** Flag indicating the mouse has been pressed.*/ private boolean pressed; /** * Sets the number of selected stars depending on the location * of the mouse click. * * @param p The location of the mouse click. */ private void handleClick(Point p) { if (!isEnabled()) return; boolean found = false; Rectangle r; for (int i = 0; i < stars.size(); i++) { r = stars.get(i); if (r.contains(p)) { found = true; model.setValue(i+1); break; } } if (found) return; r = stars.get(0); if (p.x < r.x) { model.setValue(RatingComponent.MIN_VALUE); return; } r = stars.get(stars.size()-1); if (p.x > (r.x+r.width)) model.setValue(RatingComponent.MAX_VALUE); } /** Installs the listeners. */ private void installListeners() { addMouseListener(handler); addMouseMotionListener(this); } /** Removes the listeners. */ private void uninstallListeners() { removeMouseListener(handler); removeMouseMotionListener(this); } /** * Invokes when the mouse is released. * * @param p The mouse location. */ private void handleMouseReleased(Point p) { if (dragging || pressed) { handleClick(p); //model.onMouseReleased(); dragging = false; pressed = false; } } /** * Creates a new instance. * * @param model Reference to the model. Mustn't be <code>null</code>. */ RatingCanvas(RatingComponent model) { if (model == null) throw new IllegalArgumentException("No model"); this.model = model; setDoubleBuffered(true); stars = new ArrayList<Rectangle>(); handler = new MouseAdapter() { /** * Increases or decreases the number of selected stars * depending on the location of the mouse click. */ public void mouseReleased(MouseEvent e) { //super.mouseReleased(e); handleMouseReleased(e.getPoint()); } public void mousePressed(MouseEvent e) { //super.mouseReleased(e); pressed = true; handleMouseReleased(e.getPoint()); } }; installListeners(); } /** * Overridden to add or remove the listeners * @see javax.swing.JComponent#setEnabled(boolean) */ public void setEnabled(boolean enabled) { super.setEnabled(enabled); if (enabled) installListeners(); else uninstallListeners(); } /** * Overridden to paint the stars used to rate the image. * @see javax.swing.JComponent#paintComponent(Graphics) */ public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2D = (Graphics2D) g; g.setColor(getBackground()); int x = 0; int w, h; List<Image> l = model.getPlus(); Iterator<Image> i = l.iterator(); Image img; stars.clear(); while (i.hasNext()) { img = (Image) i.next(); w = img.getWidth(null); h = img.getHeight(null); stars.add(new Rectangle(x, 0, w, h)); g2D.drawImage(img, x, 0, w, h, null); x += w+SPACE; } l = model.getMinus(); i = l.iterator(); while (i.hasNext()) { img = (Image) i.next(); w = img.getWidth(null); h = img.getHeight(null); stars.add(new Rectangle(x, 0, w, h)); g2D.drawImage(img, x, 0, w, h, null); x += w+SPACE; } } /** * Sets the rating values when dragging the mouse over the component. * @see MouseMotionListener#mouseDragged(MouseEvent) */ public void mouseDragged(MouseEvent e) { //dragging = true; //pressed = false; //handleClick(e.getPoint()); } /** * Required by the {@link MouseMotionListener} I/F but no-operation * implementation needed in our case. * @see MouseMotionListener#mouseMoved(MouseEvent) */ public void mouseMoved(MouseEvent e) {} }