Java/Swing Components/Link Button
Another Link button
/**
* $ $ License.
*
* Copyright $ L2FProd.ru
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruposite;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ruponentUI;
import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.plaf.basic.BasicGraphicsUtils;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
/**
* A button targeted to be used as an hyperlink. Most UI will make it
* transparent and it will react on mouse over by changing the cursor to the
* hand cursor.
*
* @javabean.class name="JLinkButton" shortDescription="A button looking as an
* hyperlink." stopClass="java.awt.ruponent"
*
* @javabean.attribute name="isContainer" value="Boolean.FALSE" rtexpr="true"
*
* @javabean.icons mono16="JLinkButton16-mono.gif" color16="JLinkButton16.gif"
* mono32="JLinkButton32-mono.gif" color32="JLinkButton32.gif"
*/
public class AnotherLinkButton extends JButton {
public AnotherLinkButton() {
super();
}
public AnotherLinkButton(String text) {
super(text);
}
public AnotherLinkButton(String text, Icon icon) {
super(text, icon);
}
public AnotherLinkButton(Action a) {
super(a);
}
public AnotherLinkButton(Icon icon) {
super(icon);
}
public void updateUI() {
setUI(new WindowsLinkButtonUI());
}
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame("JLinkButton");
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add("Center", new AnotherLinkButton("www.jexp.ru"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocation(100, 100);
frame.setVisible(true);
}
}
class BasicLinkButtonUI extends BasicButtonUI {
public static ComponentUI createUI(JComponent c) {
return new BasicLinkButtonUI();
}
private static Rectangle viewRect = new Rectangle();
private static Rectangle textRect = new Rectangle();
private static Rectangle iconRect = new Rectangle();
private static MouseListener handCursorListener = new HandCursor();
protected int dashedRectGapX;
protected int dashedRectGapY;
protected int dashedRectGapWidth;
protected int dashedRectGapHeight;
private Color focusColor;
protected void installDefaults(AbstractButton b) {
super.installDefaults(b);
b.setOpaque(false);
b.setBorderPainted(false);
b.setRolloverEnabled(true);
dashedRectGapX = UIManager.getInt("ButtonUI.dashedRectGapX");
dashedRectGapY = UIManager.getInt("ButtonUI.dashedRectGapY");
dashedRectGapWidth = UIManager.getInt("ButtonUI.dashedRectGapWidth");
dashedRectGapHeight = UIManager.getInt("ButtonUI.dashedRectGapHeight");
focusColor = UIManager.getColor("ButtonUI.focus");
b.setHorizontalAlignment(AbstractButton.LEFT);
}
protected void installListeners(AbstractButton b) {
super.installListeners(b);
b.addMouseListener(handCursorListener);
}
protected void uninstallListeners(AbstractButton b) {
super.uninstallListeners(b);
b.removeMouseListener(handCursorListener);
}
protected Color getFocusColor() {
return focusColor;
}
public void paint(Graphics g, JComponent c) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
FontMetrics fm = g.getFontMetrics();
Insets i = c.getInsets();
viewRect.x = i.left;
viewRect.y = i.top;
viewRect.width = b.getWidth() - (i.right + viewRect.x);
viewRect.height = b.getHeight() - (i.bottom + viewRect.y);
textRect.x = textRect.y = textRect.width = textRect.height = 0;
iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
Font f = c.getFont();
g.setFont(f);
// layout the text and icon
String text = SwingUtilities.layoutCompoundLabel(c, fm, b.getText(), b
.getIcon(), b.getVerticalAlignment(), b
.getHorizontalAlignment(), b.getVerticalTextPosition(), b
.getHorizontalTextPosition(), viewRect, iconRect, textRect, b
.getText() == null ? 0 : b.getIconTextGap());
clearTextShiftOffset();
// perform UI specific press action, e.g. Windows L&F shifts text
if (model.isArmed() && model.isPressed()) {
paintButtonPressed(g, b);
}
// Paint the Icon
if (b.getIcon() != null) {
paintIcon(g, c, iconRect);
}
Composite oldComposite = ((Graphics2D) g).getComposite();
if (model.isRollover()) {
((Graphics2D) g).setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.5f));
}
if (text != null && !text.equals("")) {
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
if (v != null) {
textRect.x += getTextShiftOffset();
textRect.y += getTextShiftOffset();
v.paint(g, textRect);
textRect.x -= getTextShiftOffset();
textRect.y -= getTextShiftOffset();
} else {
paintText(g, b, textRect, text);
}
}
if (b.isFocusPainted() && b.hasFocus()) {
// paint UI specific focus
paintFocus(g, b, viewRect, textRect, iconRect);
}
((Graphics2D) g).setComposite(oldComposite);
}
protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect,
Rectangle textRect, Rectangle iconRect) {
if (b.getParent() instanceof JToolBar) {
// Windows doesn"t draw the focus rect for buttons in a toolbar.
return;
}
// focus painted same color as text
int width = b.getWidth();
int height = b.getHeight();
g.setColor(getFocusColor());
BasicGraphicsUtils.drawDashedRect(g, dashedRectGapX, dashedRectGapY,
width - dashedRectGapWidth, height - dashedRectGapHeight);
}
protected void paintButtonPressed(Graphics g, AbstractButton b) {
setTextShiftOffset();
}
static class HandCursor extends MouseAdapter {
public void mouseEntered(MouseEvent e) {
e.getComponent().setCursor(
Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
public void mouseExited(MouseEvent e) {
e.getComponent().setCursor(Cursor.getDefaultCursor());
}
}
}
class WindowsLinkButtonUI extends BasicLinkButtonUI {
private static WindowsLinkButtonUI buttonUI = new WindowsLinkButtonUI();
public static ComponentUI createUI(JComponent c) {
return buttonUI;
}
protected void paintButtonPressed(Graphics g, AbstractButton b) {
setTextShiftOffset();
}
}
Hyper Link component
HyperLink in Table
LinkButton
import java.awt.Color;
import java.awt.Cursor;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.net.URL;
import javax.swing.Action;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.plaf.ruponentUI;
import javax.swing.plaf.metal.MetalButtonUI;
public class JLinkButton extends JButton {
private static final String uiString = "LinkButtonUI";
public static final int ALWAYS_UNDERLINE = 0;
public static final int HOVER_UNDERLINE = 1;
public static final int NEVER_UNDERLINE = 2;
public static final int SYSTEM_DEFAULT = 3;
private int linkBehavior;
private Color linkColor;
private Color colorPressed;
private Color visitedLinkColor;
private Color disabledLinkColor;
private URL buttonURL;
private Action defaultAction;
private boolean isLinkVisited;
public static void main(String[] a) {
JFrame f = new JFrame();
f.getContentPane().setLayout(new GridLayout(0,2));
f.getContentPane().add(new JLinkButton("www.jexp.ru"));
f.getContentPane().add(new JLinkButton("www.jexp.ru/ExampleCode/CatalogExampleCode.htm"));
f.setSize(600, 200);
f.setVisible(true);
}
public JLinkButton() {
this(null, null, null);
}
public JLinkButton(Action action) {
this();
setAction(action);
}
public JLinkButton(Icon icon) {
this(null, icon, null);
}
public JLinkButton(String s) {
this(s, null, null);
}
public JLinkButton(URL url) {
this(null, null, url);
}
public JLinkButton(String s, URL url) {
this(s, null, url);
}
public JLinkButton(Icon icon, URL url) {
this(null, icon, url);
}
public JLinkButton(String text, Icon icon, URL url) {
super(text, icon);
linkBehavior = SYSTEM_DEFAULT;
linkColor = Color.blue;
colorPressed = Color.red;
visitedLinkColor = new Color(128, 0, 128);
if (text == null && url != null)
setText(url.toExternalForm());
setLinkURL(url);
setCursor(Cursor.getPredefinedCursor(12));
setBorderPainted(false);
setContentAreaFilled(false);
setRolloverEnabled(true);
addActionListener(defaultAction);
}
public void updateUI() {
setUI(BasicLinkButtonUI.createUI(this));
}
private void setDefault() {
UIManager.getDefaults().put("LinkButtonUI", "BasicLinkButtonUI");
}
public String getUIClassID() {
return "LinkButtonUI";
}
protected void setupToolTipText() {
String tip = null;
if (buttonURL != null)
tip = buttonURL.toExternalForm();
setToolTipText(tip);
}
public void setLinkBehavior(int bnew) {
checkLinkBehaviour(bnew);
int old = linkBehavior;
linkBehavior = bnew;
firePropertyChange("linkBehavior", old, bnew);
repaint();
}
private void checkLinkBehaviour(int beha) {
if (beha != ALWAYS_UNDERLINE && beha != HOVER_UNDERLINE
&& beha != NEVER_UNDERLINE && beha != SYSTEM_DEFAULT)
throw new IllegalArgumentException("Not a legal LinkBehavior");
else
return;
}
public int getLinkBehavior() {
return linkBehavior;
}
public void setLinkColor(Color color) {
Color colorOld = linkColor;
linkColor = color;
firePropertyChange("linkColor", colorOld, color);
repaint();
}
public Color getLinkColor() {
return linkColor;
}
public void setActiveLinkColor(Color colorNew) {
Color colorOld = colorPressed;
colorPressed = colorNew;
firePropertyChange("activeLinkColor", colorOld, colorNew);
repaint();
}
public Color getActiveLinkColor() {
return colorPressed;
}
public void setDisabledLinkColor(Color color) {
Color colorOld = disabledLinkColor;
disabledLinkColor = color;
firePropertyChange("disabledLinkColor", colorOld, color);
if (!isEnabled())
repaint();
}
public Color getDisabledLinkColor() {
return disabledLinkColor;
}
public void setVisitedLinkColor(Color colorNew) {
Color colorOld = visitedLinkColor;
visitedLinkColor = colorNew;
firePropertyChange("visitedLinkColor", colorOld, colorNew);
repaint();
}
public Color getVisitedLinkColor() {
return visitedLinkColor;
}
public URL getLinkURL() {
return buttonURL;
}
public void setLinkURL(URL url) {
URL urlOld = buttonURL;
buttonURL = url;
setupToolTipText();
firePropertyChange("linkURL", urlOld, url);
revalidate();
repaint();
}
public void setLinkVisited(boolean flagNew) {
boolean flagOld = isLinkVisited;
isLinkVisited = flagNew;
firePropertyChange("linkVisited", flagOld, flagNew);
repaint();
}
public boolean isLinkVisited() {
return isLinkVisited;
}
public void setDefaultAction(Action actionNew) {
Action actionOld = defaultAction;
defaultAction = actionNew;
firePropertyChange("defaultAction", actionOld, actionNew);
}
public Action getDefaultAction() {
return defaultAction;
}
protected String paramString() {
String str;
if (linkBehavior == ALWAYS_UNDERLINE)
str = "ALWAYS_UNDERLINE";
else if (linkBehavior == HOVER_UNDERLINE)
str = "HOVER_UNDERLINE";
else if (linkBehavior == NEVER_UNDERLINE)
str = "NEVER_UNDERLINE";
else
str = "SYSTEM_DEFAULT";
String colorStr = linkColor == null ? "" : linkColor.toString();
String colorPressStr = colorPressed == null ? "" : colorPressed
.toString();
String disabledLinkColorStr = disabledLinkColor == null ? ""
: disabledLinkColor.toString();
String visitedLinkColorStr = visitedLinkColor == null ? ""
: visitedLinkColor.toString();
String buttonURLStr = buttonURL == null ? "" : buttonURL.toString();
String isLinkVisitedStr = isLinkVisited ? "true" : "false";
return super.paramString() + ",linkBehavior=" + str + ",linkURL="
+ buttonURLStr + ",linkColor=" + colorStr + ",activeLinkColor="
+ colorPressStr + ",disabledLinkColor=" + disabledLinkColorStr
+ ",visitedLinkColor=" + visitedLinkColorStr
+ ",linkvisitedString=" + isLinkVisitedStr;
}
}
class BasicLinkButtonUI extends MetalButtonUI {
private static final BasicLinkButtonUI ui = new BasicLinkButtonUI();
public BasicLinkButtonUI() {
}
public static ComponentUI createUI(JComponent jcomponent) {
return ui;
}
protected void paintText(Graphics g, JComponent com, Rectangle rect,
String s) {
JLinkButton bn = (JLinkButton) com;
ButtonModel bnModel = bn.getModel();
Color color = bn.getForeground();
Object obj = null;
if (bnModel.isEnabled()) {
if (bnModel.isPressed())
bn.setForeground(bn.getActiveLinkColor());
else if (bn.isLinkVisited())
bn.setForeground(bn.getVisitedLinkColor());
else
bn.setForeground(bn.getLinkColor());
} else {
if (bn.getDisabledLinkColor() != null)
bn.setForeground(bn.getDisabledLinkColor());
}
super.paintText(g, com, rect, s);
int behaviour = bn.getLinkBehavior();
boolean drawLine = false;
if (behaviour == JLinkButton.HOVER_UNDERLINE) {
if (bnModel.isRollover())
drawLine = true;
} else if (behaviour == JLinkButton.ALWAYS_UNDERLINE || behaviour == JLinkButton.SYSTEM_DEFAULT)
drawLine = true;
if (!drawLine)
return;
FontMetrics fm = g.getFontMetrics();
int x = rect.x + getTextShiftOffset();
int y = (rect.y + fm.getAscent() + fm.getDescent() + getTextShiftOffset()) - 1;
if (bnModel.isEnabled()) {
g.setColor(bn.getForeground());
g.drawLine(x, y, (x + rect.width) - 1, y);
} else {
g.setColor(bn.getBackground().brighter());
g.drawLine(x, y, (x + rect.width) - 1, y);
}
}
}