Skip to content

Instantly share code, notes, and snippets.

@xmedeko
Last active December 28, 2015 04:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xmedeko/7446284 to your computer and use it in GitHub Desktop.
Save xmedeko/7446284 to your computer and use it in GitHub Desktop.
Java Swing JLinkButton draws a button like JLabel with blue color and underlined font on mouse hover. Disclaimer: inspired by a few others similar solutions.
import java.awt.Color;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.util.Map;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
/**
* JLinkButton draws a button like JLabel. Default foreground color is blue and the text is underlined on mouse hover
* (behaviour depends on {@link #underlineMode}). Shows the hand cursor.
*
* @author xmedeko
*/
public class JLinkButton extends JButton {
/**
* Type of underline mode.
*/
public enum UnderlineMode {
NONE, ALWAYS, HOVER
};
private UnderlineMode underlineMode = UnderlineMode.HOVER;
public JLinkButton() {
super();
}
public JLinkButton(Action a) {
super(a);
}
public JLinkButton(Icon icon) {
super(icon);
}
public JLinkButton(String text, Icon icon) {
super(text, icon);
}
public JLinkButton(String text) {
super(text);
}
@Override
protected void init(String text, Icon icon) {
super.init(text, icon);
setFocusPainted(false);
setMargin(null);
setContentAreaFilled(false);
setBorderPainted(false);
setBorder(BorderFactory.createEmptyBorder());
setOpaque(false);
setHorizontalAlignment(SwingConstants.LEFT);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
setForeground(Color.BLUE);
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
if (getUnderlineMode() == UnderlineMode.HOVER) {
setUnderlineFont(true);
}
}
@Override
public void mouseExited(MouseEvent e) {
if (getUnderlineMode() == UnderlineMode.HOVER) {
setUnderlineFont(false);
}
}
});
}
/**
* set or reset the underline font.
*/
protected void setUnderlineFont(boolean underline) {
@SuppressWarnings("unchecked")
Map<TextAttribute, Object> map = (Map<TextAttribute, Object>) getFont().getAttributes();
if (underline) {
map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
} else {
map.remove(TextAttribute.UNDERLINE);
}
Font newFont = new Font(map);
setFont(newFont);
}
/**
* @return underline mode
*/
public UnderlineMode getUnderlineMode() {
return underlineMode;
}
/**
* Set underline mode.
*
* @return this, just for fluent API.
*/
public JLinkButton setUnderlineMode(UnderlineMode underlineMode) {
this.underlineMode = underlineMode;
switch (underlineMode) {
case ALWAYS:
setUnderlineFont(true);
break;
case NONE:
setUnderlineFont(false);
break;
case HOVER: // nothing
break;
}
return this;
}
// test
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(new JLinkButton("Hover").setUnderlineMode(UnderlineMode.HOVER));
frame.add(new JLinkButton("None").setUnderlineMode(UnderlineMode.NONE));
frame.add(new JLinkButton("Always").setUnderlineMode(UnderlineMode.ALWAYS));
JLinkButton disabled = new JLinkButton("Disabled");
disabled.setEnabled(false);
frame.add(disabled);
frame.pack();
frame.setVisible(true);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment