/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * 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 3 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, see http://www.gnu.org/licenses/ */ package org.esa.snap.ui.tool; import com.jidesoft.swing.JideButton; import com.jidesoft.swing.JideToggleButton; import org.esa.snap.ui.UIUtils; import javax.swing.AbstractButton; import javax.swing.Action; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.UIManager; import java.awt.Color; import java.awt.Dimension; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.FilteredImageSource; import java.awt.image.RGBImageFilter; import java.util.EventObject; //import UIUtils; /** * The <code>ToolButtonFactory</code> can be used to create tool bar buttons which have a consistent look and feel. * * @author Norman Fomferra * @version $Revision$ $Date$ */ public class ToolButtonFactory { public static final Color SELECTED_BORDER_COLOR = new Color(8, 36, 107); private static final Color SELECTED_BACKGROUND_COLOR = new Color(130, 146, 185); private static final Color ROLLOVER_BACKGROUND_COLOR = new Color(181, 190, 214); private static final int BUTTON_MIN_SIZE = 16; private static ImageIcon _separatorIcon; public static AbstractButton createButton(Icon icon, boolean toggle) { AbstractButton button = createButton(toggle); button.setIcon(icon); configure(button); return button; } public static AbstractButton createButton(Action action, boolean toggle) { AbstractButton button = createButton(toggle); setButtonName(button, action); button.setAction(action); configure(button); return button; } private static AbstractButton createButton(boolean toggle) { JideButton button; if (toggle) { button = new JideToggleButton(); // <JIDE/> } else { button = new JideButton(); // <JIDE/> } return button; } private static void configure(AbstractButton button) { RolloverButtonEventListener l = new RolloverButtonEventListener(); button.addMouseListener(l); button.addItemListener(l); if (button.getAction() != null) { if (button.getIcon() != null) { button.putClientProperty("hideActionText", Boolean.TRUE); } Object largeIcon = button.getAction().getValue("_largeIcon"); if (largeIcon instanceof Icon) { button.setIcon((Icon) largeIcon); } } Icon icon = button.getIcon(); int minWidth = BUTTON_MIN_SIZE; int minHeight = BUTTON_MIN_SIZE; if (icon != null) { button.setText(null); minWidth = Math.max(icon.getIconWidth(), BUTTON_MIN_SIZE); minHeight = Math.max(icon.getIconHeight(), BUTTON_MIN_SIZE); if (icon instanceof ImageIcon) { button.setRolloverIcon(createRolloverIcon((ImageIcon) icon)); } } else { button.setText("[?]"); } final int space = 3; Dimension prefSize = new Dimension(minWidth + space, minHeight + space); Dimension minSize = new Dimension(minWidth, minHeight); Dimension maxSize = new Dimension(minWidth + space, minHeight + space); button.setPreferredSize(prefSize); button.setMaximumSize(maxSize); button.setMinimumSize(minSize); } public static JComponent createToolBarSeparator() { if (_separatorIcon == null) { _separatorIcon = UIUtils.loadImageIcon("icons/Separator24.gif"); } return new JLabel(_separatorIcon); } public static ImageIcon createRolloverIcon(ImageIcon imageIcon) { return new ImageIcon(createRolloverImage(imageIcon.getImage())); } private static Image createRolloverImage(Image image) { return Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), new BrightBlueFilter())); } private static class BrightBlueFilter extends RGBImageFilter { public BrightBlueFilter() { canFilterIndexColorModel = true; } @Override public int filterRGB(int x, int y, int rgb) { int a = (rgb & 0xff000000) >> 24; int r = (rgb & 0x00ff0000) >> 16; int g = (rgb & 0x0000ff00) >> 8; int b = rgb & 0x000000ff; int i = (r + g + b) / 3; r = g = i; b = 255; return a << 24 | r << 16 | g << 8 | b; } } private static class RolloverButtonEventListener extends MouseAdapter implements ItemListener { public RolloverButtonEventListener() { } public AbstractButton getButton(EventObject e) { return (AbstractButton) e.getSource(); } /** * Invoked when a mouse button has been pressed on a component. */ @Override public void mousePressed(MouseEvent e) { setSelectedState(getButton(e)); } /** * Invoked when a mouse button has been released on a component. */ @Override public void mouseReleased(MouseEvent e) { setDefaultState(getButton(e)); } /** * Invoked when the mouse enters a component. */ @Override public void mouseEntered(MouseEvent e) { setRolloverStateState(getButton(e)); } /** * Invoked when the mouse exits a component. */ @Override public void mouseExited(MouseEvent e) { setDefaultState(getButton(e)); } private void setDefaultState(AbstractButton b) { if (b.isSelected()) { setSelectedState(b); } else { setNormalState(b); } } private void setNormalState(AbstractButton b) { b.setBorderPainted(false); // b.setForeground(getDefaultForeground()); b.setBackground(getDefaultBackground()); } private void setSelectedState(AbstractButton b) { if (b.isEnabled()) { b.setBorderPainted(true); b.setBackground(SELECTED_BACKGROUND_COLOR); } else { b.setBorderPainted(false); b.setBackground(getDefaultBackground().darker()); } } private void setRolloverStateState(AbstractButton b) { if (b.isEnabled()) { b.setBorderPainted(true); b.setBackground(ROLLOVER_BACKGROUND_COLOR); } } /** * Invoked when an item has been selected or deselected. The code written for this method performs the * operations that need to occur when an item is selected (or deselected). */ public void itemStateChanged(ItemEvent e) { setDefaultState((AbstractButton) e.getSource()); } private Color getDefaultBackground() { Color color = null; String[] keys = new String[]{"Button.background", "Label.background", "Panel.background"}; for (String key : keys) { color = UIManager.getLookAndFeel().getDefaults().getColor(key); } if (color == null) { color = new Color(238, 238, 238); } return color; } } private static void setButtonName(AbstractButton button, Action action) { if (button.getName() == null) { String name = null; Object value = action.getValue(Action.ACTION_COMMAND_KEY); if (value != null) { name = value.toString(); } else { value = action.getValue(Action.NAME); if (value != null) { name = value.toString(); } } if (name != null) { button.setName(name); } } } }