blob: ce8ee90a2597a25f5512f387a126280c01388250 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* BSI Business Systems Integration AG - initial API and implementation
******************************************************************************/
package org.eclipse.scout.rt.ui.swing.ext;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Stroke;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.AbstractBorder;
import javax.swing.plaf.ColorUIResource;
import org.eclipse.scout.commons.NumberUtility;
import org.eclipse.scout.commons.StringUtility;
import org.eclipse.scout.commons.TypeCastUtility;
public class HyperlinkBorder extends AbstractBorder {
private static final long serialVersionUID = 1L;
private static Insets borderInsets = new Insets(1, 3, 1, 3);
private static final Color DEFAULT_LINE_COLOR = new Color(68, 85, 153);
@Override
public Insets getBorderInsets(Component c) {
return getBorderInsets(c, new Insets(0, 0, 0, 0));
}
@Override
public Insets getBorderInsets(Component c, Insets insets) {
insets.top = borderInsets.top;
insets.left = borderInsets.left;
insets.bottom = borderInsets.bottom;
insets.right = borderInsets.right;
return insets;
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
JLabel label = (JLabel) c;
Rectangle viewR = new Rectangle(borderInsets.left, borderInsets.top, c.getWidth() - borderInsets.left - borderInsets.right, c.getHeight() - borderInsets.top - borderInsets.bottom);
Rectangle iconR = new Rectangle();
Rectangle textR = new Rectangle();
FontMetrics fm = label.getFontMetrics(label.getFont());
SwingUtilities.layoutCompoundLabel(
label,
fm,
label.getText(),
label.getIcon(),
label.getVerticalAlignment(),
label.getHorizontalAlignment(),
label.getVerticalTextPosition(),
label.getHorizontalTextPosition(),
viewR,
iconR,
textR,
label.getIconTextGap()
);
x = textR.x;
y = textR.y;
w = textR.width;
h = textR.height;
g.setColor(getForegroundColor(c));
if (!StringUtility.isNullOrEmpty(label.getText())) {
if (c.isEnabled() && c.isFocusOwner()) {
drawFocus(g, x - 1, y, w + 2, h);
}
if (c.isEnabled() && c.getMousePosition() != null) {
g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
}
}
}
/**
* We cannot rely on the foreground color, because when the foreground color is instance of ColorUIResource,
* the foreground color is chosen by the look & feel. Which means getForeground() may return "black"
* (and is istanceof ColorUIResource) but on the screen the widget is red (because this color was chosen
* by the look & feel. Best thing we can do here is to lookup a color in the UIDefaults when the
* foreground is not defined for the widget.
*
* @param c
* @return
*/
private Color getForegroundColor(Component c) {
if (c.getForeground() instanceof ColorUIResource) {
Color defaultLineColor = UIManager.getDefaults().getColor("Hyperlink.foreground");
if (defaultLineColor == null) {
defaultLineColor = DEFAULT_LINE_COLOR;
}
return defaultLineColor;
}
else {
return c.getForeground();
}
}
private static void drawFocus(Graphics g, int x, int y, int w, int h) {
Graphics2D g2d = (Graphics2D) g;
Stroke old = g2d.getStroke();
float pattern0 = NumberUtility.nvl(TypeCastUtility.castValue(UIManager.getLookAndFeelDefaults().get("Hyperlink.borderPattern0"), Float.class), Float.valueOf(1)).floatValue();
float pattern1 = NumberUtility.nvl(TypeCastUtility.castValue(UIManager.getLookAndFeelDefaults().get("Hyperlink.borderPattern1"), Float.class), Float.valueOf(2)).floatValue();
g2d.setStroke(new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 1f, new float[]{pattern0, pattern1}, 1));
g2d.drawLine(x, y, x + w - 1, y);
g2d.drawLine(x, y + h, x + w - 1, y + h);
g2d.drawLine(x, y, x, y + h - 1);
g2d.drawLine(x + w, y, x + w, y + h - 1);
g2d.setStroke(old);
}
}