/*
* TabbedCaptionSupport.java
*
* Created on Dec 11, 2007, 2:20:48 PM
*
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.visualvm.core.ui.components;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Stroke;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageProducer;
import java.util.HashSet;
import java.util.Set;
import javax.swing.BorderFactory;
import javax.swing.DefaultButtonModel;
import javax.swing.GrayFilter;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
/**
*
* @author Jiri Sedlacek
*/
class DisplayAreaSupport {
static final Color BORDER_COLOR_NORMAL = new Color(192, 192, 192);
static final Color BORDER_COLOR_HIGHLIGHT = new Color(128, 128, 128);
static final Color BACKGROUND_COLOR_NORMAL = new Color(245, 245, 245);
static final Color BACKGROUND_COLOR_HIGHLIGHT = new Color(235, 235, 235);
static final Color COLOR_NONE = new Color(0, 0, 0);
static final Color TABS_SEPARATOR = new Color(UIManager.getColor("Label.foreground").getRGB()); // NOI18N
static final int TABBUTTON_MARGIN_TOP = 3;
static final int TABBUTTON_MARGIN_LEFT = 8;
static final int TABBUTTON_MARGIN_BOTTOM = 3;
static final int TABBUTTON_MARGIN_RIGHT = 8;
private static final Color TABBUTTON_FOCUS_COLOR = Color.BLACK;
private static final Stroke TABBUTTON_FOCUS_STROKE = new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0, new float[] {0, 2}, 0);
static class TabButton extends JButton {
TabButton(String text, String description) {
super(text);
setModel(new DefaultButtonModel() {
public boolean isPressed() { return false; }
});
setOpaque(false);
setFocusPainted(false);
setBorderPainted(false);
setContentAreaFilled(false);
setBorder(BorderFactory.createEmptyBorder(TABBUTTON_MARGIN_TOP, TABBUTTON_MARGIN_LEFT, TABBUTTON_MARGIN_BOTTOM, TABBUTTON_MARGIN_RIGHT));
setToolTipText(description);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension size = getSize();
Graphics2D g2 = (Graphics2D)g;
if( hasFocus() && isEnabled() ) {
g2.setStroke(TABBUTTON_FOCUS_STROKE);
g2.setColor(TABBUTTON_FOCUS_COLOR);
g2.drawRect(2, 2, size.width - 5, size.height - 5);
}
}
}
static class TabButtonContainer extends JPanel {
private TabButton tabButton;
TabButtonContainer(TabButton tabButton) {
this.tabButton = tabButton;
setOpaque(true);
setLayout(new FlowLayout(FlowLayout.LEADING, 0, 0));
setBackground(BACKGROUND_COLOR_NORMAL);
setBorder(TabbedCaptionBorder.get(null, null, null, null));
add(tabButton, BorderLayout.CENTER);
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
tabButton.setEnabled(enabled);
}
void updateTabButton(int index, int selectedIndex, int buttonsCount) {
if (buttonsCount == 1) {
tabButton.setFocusable(false);
tabButton.setCursor(Cursor.getDefaultCursor());
setBackground(BACKGROUND_COLOR_NORMAL);
setBorder(TabbedCaptionBorder.get(BORDER_COLOR_NORMAL, BORDER_COLOR_NORMAL, COLOR_NONE, COLOR_NONE));
} else if (index == selectedIndex) {
tabButton.setFocusable(true);
tabButton.setCursor(Cursor.getDefaultCursor());
setBackground(BACKGROUND_COLOR_HIGHLIGHT);
setBorder(TabbedCaptionBorder.get(BORDER_COLOR_HIGHLIGHT, BORDER_COLOR_HIGHLIGHT, COLOR_NONE, BORDER_COLOR_HIGHLIGHT));
} else {
tabButton.setFocusable(true);
tabButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
setBackground(BACKGROUND_COLOR_NORMAL);
Color topColor = BORDER_COLOR_NORMAL;
Color leftColor = index == 0 ? BORDER_COLOR_NORMAL : null;
Color bottomColor = BORDER_COLOR_HIGHLIGHT;
Color rightColor = index == selectedIndex - 1 ? null : index == buttonsCount - 1 ? COLOR_NONE : TABS_SEPARATOR;
setBorder(TabbedCaptionBorder.get(topColor, leftColor, bottomColor, rightColor));
}
}
}
static class TabbedCaptionBorder implements Border {
private static final Set<TabbedCaptionBorder> borders = new HashSet();
private Color COLOR_TOP;
private Color COLOR_LEFT;
private Color COLOR_BOTTOM;
private Color COLOR_RIGHT;
private Insets insets;
static TabbedCaptionBorder get(Color colorTop, Color colorLeft, Color colorBottom, Color colorRight) {
for (TabbedCaptionBorder border : borders)
// Note: identity must be used for the comparison!
if (border.COLOR_TOP == colorTop &&
border.COLOR_LEFT == colorLeft &&
border.COLOR_BOTTOM == colorBottom &&
border.COLOR_RIGHT == colorRight) return border;
TabbedCaptionBorder border = new TabbedCaptionBorder(colorTop, colorLeft, colorBottom, colorRight);
borders.add(border);
return border;
}
private TabbedCaptionBorder(Color colorTop, Color colorLeft, Color colorBottom, Color colorRight) {
COLOR_TOP = colorTop;
COLOR_LEFT = colorLeft;
COLOR_BOTTOM = colorBottom;
COLOR_RIGHT = colorRight;
insets = new Insets(
COLOR_TOP == null ? 0 : 1,
COLOR_LEFT == null ? 0 : 1,
COLOR_BOTTOM == null ? 0 : 1,
COLOR_RIGHT == null ? 0 : 1);
}
public Insets getBorderInsets(Component c) { return insets; }
public boolean isBorderOpaque() { return true; }
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
if (COLOR_LEFT != null && COLOR_LEFT != COLOR_NONE) {
g.setColor(COLOR_LEFT);
if (COLOR_LEFT == TABS_SEPARATOR) {
g.drawLine(x, y + TABBUTTON_MARGIN_TOP + 2, x, y + height - TABBUTTON_MARGIN_BOTTOM - 4);
} else {
g.drawLine(x, y, x, y + height - 1);
}
}
if (COLOR_RIGHT != null && COLOR_RIGHT != COLOR_NONE) {
g.setColor(COLOR_RIGHT);
if (COLOR_RIGHT == TABS_SEPARATOR) {
g.drawLine(x + width - 1, y + TABBUTTON_MARGIN_TOP + 2, x + width - 1, y + height - TABBUTTON_MARGIN_BOTTOM - 4);
} else {
g.drawLine(x + width - 1, y, x + width - 1, y + height - 1);
}
}
if (COLOR_TOP != null && COLOR_TOP != COLOR_NONE) {
g.setColor(COLOR_TOP);
g.drawLine(x, y, x + width - 1, y);
}
if (COLOR_BOTTOM != null && COLOR_BOTTOM != COLOR_NONE) {
g.setColor(COLOR_BOTTOM);
g.drawLine(x, y + height - 1, x + width - 1, y + height - 1);
}
}
}
private static class ThinBevelBorder extends BevelBorder {
//~ Constructors ---------------------------------------------------------------------------------------------------------
private ThinBevelBorder(int bevelType, Color highlight, Color shadow) {
super(bevelType, highlight.brighter(), highlight, shadow, shadow.brighter());
}
//~ Methods --------------------------------------------------------------------------------------------------------------
public Insets getBorderInsets(Component c) {
return new Insets(1, 1, 1, 1);
}
public Insets getBorderInsets(Component c, Insets insets) {
insets.left = insets.top = insets.right = insets.bottom = 1;
return insets;
}
protected void paintLoweredBevel(Component c, Graphics g, int x, int y, int width, int height) {
if (!c.isEnabled()) {
return;
}
Color oldColor = g.getColor();
int h = height;
int w = width;
g.translate(x, y);
g.setColor(getShadowOuterColor(c));
g.drawLine(0, 0, 0, h - 1);
g.drawLine(1, 0, w - 1, 0);
g.setColor(getHighlightInnerColor(c));
g.drawLine(1, h - 1, w - 1, h - 1);
g.drawLine(w - 1, 1, w - 1, h - 2);
g.translate(-x, -y);
g.setColor(oldColor);
}
protected void paintRaisedBevel(Component c, Graphics g, int x, int y, int width, int height) {
if (!c.isEnabled()) {
return;
}
Color oldColor = g.getColor();
int h = height;
int w = width;
g.translate(x, y);
g.setColor(getHighlightInnerColor(c));
g.drawLine(0, 0, 0, h - 1);
g.drawLine(1, 0, w - 1, 0);
g.setColor(getShadowOuterColor(c));
g.drawLine(0, h - 1, w - 1, h - 1);
g.drawLine(w - 1, 0, w - 1, h - 2);
g.translate(-x, -y);
g.setColor(oldColor);
}
}
static class ImageIconButton extends JButton implements MouseListener {
//~ Instance fields ------------------------------------------------------------------------------------------------------
private static final Border EMPTY_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1);
private static final Border LOWERED_BORDER = new ThinBevelBorder(BevelBorder.LOWERED, Color.WHITE, Color.GRAY);
private static final Border RAISED_BORDER = new ThinBevelBorder(BevelBorder.RAISED, Color.WHITE, Color.GRAY);
private boolean rollover = false;
private boolean pressed = false;
//~ Constructors ---------------------------------------------------------------------------------------------------------
ImageIconButton(ImageIcon icon) {
super();
GrayFilter enabledFilter = new GrayFilter(true, 35);
ImageProducer prod = new FilteredImageSource(icon.getImage().getSource(), enabledFilter);
Icon grayIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(prod));
GrayFilter disabledFilter = new GrayFilter(true, 60);
prod = new FilteredImageSource(icon.getImage().getSource(), disabledFilter);
Icon disabledIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(prod));
setIcon(grayIcon);
setRolloverIcon(icon);
setPressedIcon(icon);
setDisabledIcon(disabledIcon);
setIconTextGap(0);
setBorder(EMPTY_BORDER);
setFocusPainted(false);
setContentAreaFilled(false);
addMouseListener(this);
}
//~ Methods --------------------------------------------------------------------------------------------------------------
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
rollover = true;
if (pressed) {
setBorder(LOWERED_BORDER);
} else {
setBorder(RAISED_BORDER);
}
}
public void mouseExited(MouseEvent e) {
rollover = false;
setBorder(EMPTY_BORDER);
}
public void mousePressed(MouseEvent e) {
pressed = true;
setBorder(LOWERED_BORDER);
}
public void mouseReleased(MouseEvent e) {
pressed = false;
if (rollover) {
setBorder(RAISED_BORDER);
} else {
setBorder(EMPTY_BORDER);
}
}
public Dimension getPreferredSize() {
return new Dimension(TABBUTTON_MARGIN_LEFT + TABBUTTON_MARGIN_RIGHT, TABBUTTON_MARGIN_LEFT + TABBUTTON_MARGIN_RIGHT);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension size = getSize();
Graphics2D g2 = (Graphics2D)g;
if( hasFocus() && isEnabled() ) {
g2.setStroke(TABBUTTON_FOCUS_STROKE);
g2.setColor(TABBUTTON_FOCUS_COLOR);
g2.drawRect(2, 2, size.width - 5, size.height - 5);
}
}
}
}