/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotools.swing; import java.awt.Component; import java.awt.FlowLayout; import java.awt.Point; import java.awt.Rectangle; import java.util.ResourceBundle; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; import org.geotools.map.Layer; /** * A custom list cell renderer for items in the JList used by {@linkplain MapLayerTable} * to show map layer names and states. * * @author Michael Bedward * @since 2.6 * * * @source $URL$ * @version $Id$ */ public class MapLayerTableCellRenderer extends JPanel implements ListCellRenderer { private static final long serialVersionUID = 7907189175227502588L; private static final ResourceBundle stringRes = ResourceBundle.getBundle("org/geotools/swing/Text"); /** * Items used to display layer states and controls. Each item has * one or two icons associated with it: one for simple controls, * two for toggle controls. */ public static enum LayerControlItem { /** * Layer visibility - whether the layer will be shown or hidden * when the map display is drawn */ VISIBLE( new ImageIcon(MapLayerTableCellRenderer.class.getResource( "/org/geotools/swing/icons/eye_open.png")), new ImageIcon(MapLayerTableCellRenderer.class.getResource( "/org/geotools/swing/icons/eye_closed.png")) ), /** * Layer selection - the selected status of layers can be used * to include or exclude them in map queries etc. */ SELECTED( new ImageIcon(MapLayerTableCellRenderer.class.getResource( "/org/geotools/swing/icons/tick.png")), new ImageIcon(MapLayerTableCellRenderer.class.getResource( "/org/geotools/swing/icons/cross.png")) ), /** * Layer style - to open a style dialog for the layer */ STYLE( new ImageIcon(MapLayerTableCellRenderer.class.getResource( "/org/geotools/swing/icons/style_layer.png")), null // no off state for this label ), REMOVE( new ImageIcon(MapLayerTableCellRenderer.class.getResource( "/org/geotools/swing/icons/remove_layer.png")), null // no off state for this label ); private ImageIcon onIcon; private ImageIcon offIcon; /** * Private constructor * @param onIcon icon for the 'on' state * @param offIcon icon for the 'off' state */ private LayerControlItem(ImageIcon onIcon, ImageIcon offIcon) { this.onIcon = onIcon; this.offIcon = offIcon; } /** * Get the icon used to signify the 'on' state for toggle controls * or the single icon for non-toggle controls * * @return the icon */ public Icon getIcon() { return onIcon; } /** * Get the icon used to signify the 'off' state. If called for a non-toggle * control this returns the single icon. * * @return the icon */ public Icon getOffIcon() { if (offIcon != null) { return offIcon; } else { return onIcon; } } } private final static int CELL_PADDING = 5; private final static int CELL_HEIGHT; private final static Rectangle SELECT_LABEL_BOUNDS; private final static Rectangle VISIBLE_LABEL_BOUNDS; private final static Rectangle STYLE_LABEL_BOUNDS; private final static Rectangle REMOVE_LABEL_BOUNDS; private final static Rectangle NAME_LABEL_BOUNDS; static { int maxIconHeight = 0; for (LayerControlItem state : LayerControlItem.values()) { maxIconHeight = Math.max(maxIconHeight, state.getIcon().getIconHeight()); } CELL_HEIGHT = maxIconHeight + 2*CELL_PADDING; int x = CELL_PADDING; int h = LayerControlItem.VISIBLE.getIcon().getIconHeight(); int w = LayerControlItem.VISIBLE.getIcon().getIconWidth(); VISIBLE_LABEL_BOUNDS = new Rectangle(x, CELL_PADDING, w, h); x += w + CELL_PADDING; h = LayerControlItem.SELECTED.getIcon().getIconHeight(); w = LayerControlItem.SELECTED.getIcon().getIconWidth(); SELECT_LABEL_BOUNDS = new Rectangle(x, CELL_PADDING, w, h); x += w + CELL_PADDING; h = LayerControlItem.STYLE.getIcon().getIconHeight(); w = LayerControlItem.STYLE.getIcon().getIconWidth(); STYLE_LABEL_BOUNDS = new Rectangle(x, CELL_PADDING, w, h); x += w + CELL_PADDING; h = LayerControlItem.REMOVE.getIcon().getIconHeight(); w = LayerControlItem.REMOVE.getIcon().getIconWidth(); REMOVE_LABEL_BOUNDS = new Rectangle(x, CELL_PADDING, w, h); x += w + CELL_PADDING; NAME_LABEL_BOUNDS = new Rectangle(x, CELL_PADDING, 1000, CELL_HEIGHT - 2*CELL_PADDING); } private JLabel visibleLabel; private JLabel selectedLabel; private JLabel styleLabel; private JLabel removeLayerLabel; private JLabel nameLabel; /** * Get the constant height that will be used for list cells * @return cell height in pixels */ public static int getCellHeight() { return CELL_HEIGHT; } /** * Check if a point representing a mouse click location lies within * the bounds of the layer visibility label * @param p coords of the mouse click; relative to this cell's origin * @return true if the point is within the label bounds; false otherwise */ public static boolean hitVisibilityLabel(Point p) { return VISIBLE_LABEL_BOUNDS.contains(p); } /** * Check if a point representing a mouse click location lies within * the bounds of the layer selection label * @param p coords of the mouse click; relative to this cell's origin * @return true if the point is within the label bounds; false otherwise */ public static boolean hitSelectionLabel(Point p) { return SELECT_LABEL_BOUNDS.contains(p); } /** * Check if a point representing a mouse click location lies within * the bounds of the layer style label * @param p coords of the mouse click; relative to this cell's origin * @return true if the point is within the label bounds; false otherwise */ public static boolean hitStyleLabel(Point p) { return STYLE_LABEL_BOUNDS.contains(p); } /** * Check if a point representing a mouse click location lies within * the bounds of the remove layer label * @param p coords of the mouse click; relative to this cell's origin * @return true if the point is within the label bounds; false otherwise */ public static boolean hitRemoveLabel(Point p) { return REMOVE_LABEL_BOUNDS.contains(p); } public static boolean hitNameLabel(Point p) { return NAME_LABEL_BOUNDS.contains(p); } /** * Constructor */ public MapLayerTableCellRenderer() { super(new FlowLayout(FlowLayout.LEFT, CELL_PADDING, CELL_PADDING)); visibleLabel = new JLabel(); add(visibleLabel); selectedLabel = new JLabel(); add(selectedLabel); styleLabel = new JLabel(LayerControlItem.STYLE.getIcon()); add(styleLabel); removeLayerLabel = new JLabel(LayerControlItem.REMOVE.getIcon()); add(removeLayerLabel); nameLabel = new JLabel(); add(nameLabel); } public Component getListCellRendererComponent( JList list, Object value, // value to display int index, // cell index boolean isSelected, // is the cell selected boolean cellHasFocus) // the list and the cell have the focus { Layer layer = (Layer)value; String name = layer.getTitle(); if (name == null || name.trim().length() == 0) { name = layer.getFeatureSource().getName().getLocalPart(); } nameLabel.setText(name); visibleLabel.setIcon( layer.isVisible() ? LayerControlItem.VISIBLE.getIcon() : LayerControlItem.VISIBLE.getOffIcon()); selectedLabel.setIcon( layer.isSelected() ? LayerControlItem.SELECTED.getIcon() : LayerControlItem.SELECTED.getOffIcon()); if (isSelected) { setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); } else { setBackground(list.getBackground()); setForeground(list.getForeground()); } setEnabled(list.isEnabled()); setFont(list.getFont()); setOpaque(true); return this; } }