components/visual-panels/core/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/timezone/LocationPicker.java
changeset 827 0944d8c0158b
equal deleted inserted replaced
826:c6aad84d2493 827:0944d8c0158b
       
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     4  * The contents of this file are subject to the terms of the
       
     5  * Common Development and Distribution License (the "License").
       
     6  * You may not use this file except in compliance with the License.
       
     7  *
       
     8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
     9  * or http://www.opensolaris.org/os/licensing.
       
    10  * See the License for the specific language governing permissions
       
    11  * and limitations under the License.
       
    12  *
       
    13  * When distributing Covered Code, include this CDDL HEADER in each
       
    14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    15  * If applicable, add the following below this CDDL HEADER, with the
       
    16  * fields enclosed by brackets "[]" replaced with your own identifying
       
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
       
    18  *
       
    19  * CDDL HEADER END
       
    20  */
       
    21 
       
    22 /*
       
    23  * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
       
    24  */
       
    25 
       
    26 package com.oracle.solaris.vp.panel.swing.timezone;
       
    27 
       
    28 import java.awt.*;
       
    29 import java.awt.event.*;
       
    30 import java.awt.geom.Point2D;
       
    31 import java.util.*;
       
    32 import javax.swing.*;
       
    33 import com.oracle.solaris.vp.util.swing.ScaledIcon;
       
    34 
       
    35 public class LocationPicker<T> extends JLabel
       
    36     implements MouseListener, MouseMotionListener
       
    37 {
       
    38     static final int LOC_OFFSET = 2;
       
    39     static final int LOC_SIZE = LOC_OFFSET * 2 + 1;
       
    40 
       
    41     /**
       
    42      * Maps a normalized 2D location (0..1, 0..1) to a pixel location
       
    43      * using the provided image dimensions.
       
    44      *
       
    45      * @param dim the dimension of the image to map into
       
    46      * @param point the normalized 2D location
       
    47      * @return the discrete pixel location within the image
       
    48      */
       
    49     private static Point normToPixel(Dimension dim, Point2D point)
       
    50     {
       
    51 	double width = dim.getWidth();
       
    52 	double height = dim.getHeight();
       
    53 	return new Point((int)(width * point.getX()),
       
    54 	    (int)(height * point.getY()));
       
    55     }
       
    56 
       
    57     private class LocationLabel extends JLabel
       
    58     {
       
    59 	private final T object_;
       
    60 	private final String label_;
       
    61 	private final Point2D center_;
       
    62 	private Point pixelCenter_;
       
    63 	private boolean highlit_;
       
    64 	private boolean selected_;
       
    65 
       
    66 	LocationLabel(T object)
       
    67 	{
       
    68 	    object_ = object;
       
    69 	    label_ = mapper_.getLabel(object);
       
    70 	    center_ = mapper_.map(object);
       
    71 
       
    72 	    setSize(LOC_SIZE, LOC_SIZE);
       
    73 	}
       
    74 
       
    75 	@Override
       
    76 	public void paint(Graphics g)
       
    77 	{
       
    78 	    Graphics2D g2 = (Graphics2D)g;
       
    79 	    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
       
    80 		RenderingHints.VALUE_ANTIALIAS_ON);
       
    81 
       
    82 	    g.setColor(Color.black);
       
    83 	    g.fillRect(1, 1, LOC_SIZE - 2, LOC_SIZE - 2);
       
    84 	    g.setColor(selected_ ?
       
    85 		Color.yellow : highlit_ ? Color.cyan : Color.red.darker());
       
    86 	    g.fillRect(0, 0, LOC_SIZE - 2, LOC_SIZE - 2);
       
    87 	}
       
    88 
       
    89 	Point2D getCenter()
       
    90 	{
       
    91 	    return (center_);
       
    92 	}
       
    93 
       
    94 	Point getPixelCenter()
       
    95 	{
       
    96 	    return (pixelCenter_);
       
    97 	}
       
    98 
       
    99 	void setPixelCenter(Point pixelCenter)
       
   100 	{
       
   101 	    pixelCenter_ = pixelCenter;
       
   102 	    setLocation(pixelCenter.x - LOC_OFFSET, pixelCenter.y - LOC_OFFSET);
       
   103 	}
       
   104 
       
   105 	T getObject()
       
   106 	{
       
   107 	    return (object_);
       
   108 	}
       
   109 
       
   110 	String getToolTip()
       
   111 	{
       
   112 	    return (label_);
       
   113 	}
       
   114 
       
   115 	void setHighlit(boolean highlit)
       
   116 	{
       
   117 	    highlit_ = highlit;
       
   118 	    repaint(getVisibleRect());
       
   119 	}
       
   120 
       
   121 	void setSelected(boolean selected)
       
   122 	{
       
   123 	    selected_ = selected;
       
   124 	    repaint(getVisibleRect());
       
   125 	}
       
   126     }
       
   127 
       
   128     private class LocationLayout implements LayoutManager
       
   129     {
       
   130 	public void addLayoutComponent(String name, Component comp)
       
   131 	{
       
   132 	}
       
   133 
       
   134 	public void removeLayoutComponent(Component comp)
       
   135 	{
       
   136 	}
       
   137 
       
   138 	public Dimension preferredLayoutSize(Container parent)
       
   139 	{
       
   140 	    return (new Dimension(0, 0));
       
   141 	}
       
   142 
       
   143 	public Dimension minimumLayoutSize(Container parent)
       
   144 	{
       
   145 	    return (new Dimension(0, 0));
       
   146 	}
       
   147 
       
   148 	public void layoutContainer(Container parent)
       
   149 	{
       
   150 	    int nComps = parent.getComponentCount();
       
   151 
       
   152 	    Dimension size = parent.getSize();
       
   153 	    for (int i = 0; i < nComps; i++) {
       
   154 		Component c = parent.getComponent(i);
       
   155 		if (!c.isVisible())
       
   156 		    continue;
       
   157 		LocationLabel label = (LocationLabel)c;
       
   158 		label.setPixelCenter(normToPixel(size, label.getCenter()));
       
   159 	    }
       
   160 	}
       
   161     }
       
   162 
       
   163     private LocationMapper<T> mapper_;
       
   164     private Map<T, LocationLabel> objects_ = new HashMap<T, LocationLabel>();
       
   165     private LocationLabel current_;
       
   166     private LocationLabel selection_;
       
   167 
       
   168     private LocationSelectionListeners<T> selectionListeners_ =
       
   169 	new LocationSelectionListeners<T>();
       
   170 
       
   171     private LocationSelectionListeners<T> highlightListeners_ =
       
   172 	new LocationSelectionListeners<T>();
       
   173 
       
   174     private ScaledIcon icon_;
       
   175 
       
   176     //
       
   177     // Constructors
       
   178     //
       
   179 
       
   180     public LocationPicker(Icon background, LocationMapper<T> mapper) {
       
   181 
       
   182 	icon_ = new ScaledIcon(background);
       
   183 	setIcon(icon_);
       
   184 	mapper_ = mapper;
       
   185 	current_ = null;
       
   186 
       
   187 	setLayout(new LocationLayout());
       
   188 
       
   189 	addMouseMotionListener(this);
       
   190 	addMouseListener(this);
       
   191     }
       
   192 
       
   193     @Override
       
   194     public Dimension getPreferredSize() {
       
   195 	if (isPreferredSizeSet()) {
       
   196 	    return super.getPreferredSize();
       
   197 	}
       
   198 
       
   199 	Insets insets = getInsets();
       
   200 	Icon icon = icon_.getIcon();
       
   201 	int width = icon.getIconWidth() + insets.left + insets.right;
       
   202 	int height = icon.getIconHeight() + insets.top + insets.bottom;
       
   203 
       
   204 	return new Dimension(width, height);
       
   205     }
       
   206 
       
   207     @Override
       
   208     public void setBounds(int x, int y, int width, int height)
       
   209     {
       
   210 	super.setBounds(x, y, width, height);
       
   211 	icon_.setIconWidth(width);
       
   212 	icon_.setIconHeight(height);
       
   213     }
       
   214 
       
   215     /*
       
   216      * MouseListener methods
       
   217      */
       
   218 
       
   219     public void mouseClicked(MouseEvent e)
       
   220     {
       
   221 	/* Theoretically, motion could be lost or not occur. */
       
   222 	mouseMoved(e);
       
   223 	setSelection(current_);
       
   224     }
       
   225 
       
   226     public void mousePressed(MouseEvent e)
       
   227     {
       
   228 	return;
       
   229     }
       
   230 
       
   231     public void mouseReleased(MouseEvent e)
       
   232     {
       
   233 	return;
       
   234     }
       
   235 
       
   236     public void mouseEntered(MouseEvent e)
       
   237     {
       
   238 	return;
       
   239     }
       
   240 
       
   241     public void mouseExited(MouseEvent e)
       
   242     {
       
   243 	return;
       
   244     }
       
   245 
       
   246     /*
       
   247      * MouseMotionListener methods
       
   248      */
       
   249 
       
   250     public void mouseDragged(MouseEvent e)
       
   251     {
       
   252 	return;
       
   253     }
       
   254 
       
   255     public void mouseMoved(MouseEvent e)
       
   256     {
       
   257 	double mindist = Double.MAX_VALUE;
       
   258 	LocationLabel closest = null;
       
   259 
       
   260 	/*
       
   261 	 * Simple but sufficient.
       
   262 	 */
       
   263 	Point target = e.getPoint();
       
   264 	for (LocationLabel ll : objects_.values()) {
       
   265 	    double dist = target.distanceSq(ll.getPixelCenter());
       
   266 	    if (dist < mindist) {
       
   267 		mindist = dist;
       
   268 		closest = ll;
       
   269 	    }
       
   270 	}
       
   271 	setCurrent(closest);
       
   272     }
       
   273 
       
   274     /*
       
   275      * LocationPicker methods
       
   276      */
       
   277 
       
   278     private void sendEvent(LocationSelectionListeners<T> listeners,
       
   279 	LocationSelectionEvent.Type type, LocationLabel location)
       
   280     {
       
   281 	LocationSelectionEvent<T> event =
       
   282 	    new LocationSelectionEvent<T>(this, type,
       
   283 	    location == null ? null : location.getObject());
       
   284 
       
   285 	listeners.locationChanged(event);
       
   286     }
       
   287 
       
   288     private void setCurrent(LocationLabel newloc)
       
   289     {
       
   290 	if (newloc != current_) {
       
   291 	    if (current_ != null)
       
   292 		current_.setHighlit(false);
       
   293 	    if (newloc != null) {
       
   294 		newloc.setHighlit(true);
       
   295 		setToolTipText(newloc.getToolTip());
       
   296 	    } else {
       
   297 		setToolTipText(null);
       
   298 	    }
       
   299 
       
   300 	    current_ = newloc;
       
   301 
       
   302 	    sendEvent(highlightListeners_,
       
   303 		LocationSelectionEvent.Type.HIGHLIGHT, selection_);
       
   304 	}
       
   305     }
       
   306 
       
   307     private void setSelection(LocationLabel newloc)
       
   308     {
       
   309 	if (newloc != selection_) {
       
   310 	    if (selection_ != null)
       
   311 		selection_.setSelected(false);
       
   312 	    if (newloc != null)
       
   313 		newloc.setSelected(true);
       
   314 
       
   315 	    selection_ = newloc;
       
   316 
       
   317 	    sendEvent(selectionListeners_,
       
   318 		LocationSelectionEvent.Type.SELECTION, selection_);
       
   319 	}
       
   320     }
       
   321 
       
   322     public void setSelection(T object)
       
   323     {
       
   324 	LocationLabel ll = objects_.get(object);
       
   325 	if (ll == null && object != null)
       
   326 	    throw (new IllegalArgumentException("Object not in display"));
       
   327 	setSelection(ll);
       
   328     }
       
   329 
       
   330     public T getSelection()
       
   331     {
       
   332 	return ((selection_ == null) ? null : selection_.getObject());
       
   333     }
       
   334 
       
   335     public void addSelectionListener(LocationSelectionListener<T> listener)
       
   336     {
       
   337 	selectionListeners_.add(listener);
       
   338     }
       
   339 
       
   340     public boolean removeSelectionListener(
       
   341 	LocationSelectionListener<T> listener)
       
   342     {
       
   343 	return selectionListeners_.remove(listener);
       
   344     }
       
   345 
       
   346     public void addHighlightListener(LocationSelectionListener<T> listener)
       
   347     {
       
   348 	highlightListeners_.add(listener);
       
   349     }
       
   350 
       
   351     public boolean removeHighlightListener(
       
   352 	LocationSelectionListener<T> listener)
       
   353     {
       
   354 	return highlightListeners_.remove(listener);
       
   355     }
       
   356 
       
   357     public void setObjects(Set<T> objects) {
       
   358 	if (!objects_.isEmpty()) {
       
   359 	    for (LocationLabel label : objects_.values())
       
   360 		remove(label);
       
   361 	    objects_.clear();
       
   362 	}
       
   363 
       
   364 	for (T o : objects) {
       
   365 	    LocationLabel l = new LocationLabel(o);
       
   366 	    add(l);
       
   367 	    objects_.put(o, l);
       
   368 	}
       
   369     }
       
   370 }