/* Copyright (C) 2006 Christian Schneider
*
* This file is part of Nomad.
*
* Nomad 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 2 of the License, or
* (at your option) any later version.
*
* Nomad 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 Nomad; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.sf.nmedit.nomad.core.swing;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import net.sf.nmedit.nmutils.Platform;
import net.sf.nmedit.nomad.core.misc.FocusStroke;
public class LinkLabel extends JLabel
{
/**
*
*/
private static final long serialVersionUID = -864966524391235612L;
private boolean hovered = false;
private String plainTitle;
private String hoverTitle;
public LinkLabel(String title)
{
super(title);
setCursor(getHandCursor());
setBorder(FocusStroke.getFocusStrokeBorder(this, Color.BLACK));
this.plainTitle = title == null ? "" : title;
this.hoverTitle = title == null ? "" : underline(title);
setForeground(Color.BLUE);
(new EventHandler()).install(this);
}
private static transient Cursor handCursor;
private static Cursor getHandCursor()
{
if (handCursor == null)
handCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
return handCursor;
}
public void addActionListener(ActionListener l)
{
listenerList.add(ActionListener.class, l);
}
public void removeActionListener(ActionListener l)
{
listenerList.remove(ActionListener.class, l);
}
protected void setHovered(boolean hovered)
{
if (this.hovered != hovered)
{
this.hovered = hovered;
setText(hovered ? hoverTitle : plainTitle);
}
}
public void jump()
{
ActionEvent actionEvent = null;
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ActionListener.class) {
// Lazily create the event:
if (actionEvent == null)
actionEvent = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "jump");
((ActionListener)listeners[i+1]).actionPerformed(actionEvent);
}
}
}
private static class EventHandler extends MouseAdapter implements KeyListener
{
public void install(LinkLabel label)
{
label.setFocusable(true);
label.addMouseListener(this);
label.addKeyListener(this);
}
public void mousePressed(MouseEvent e)
{
((LinkLabel) e.getComponent()).requestFocus();
}
public void mouseExited(MouseEvent e)
{
((LinkLabel) e.getComponent()).setHovered(false);
}
public void mouseEntered(MouseEvent e)
{
((LinkLabel) e.getComponent()).setHovered(true);
}
public void mouseClicked(MouseEvent e)
{
if (Platform.isLeftMouseButtonOnly(e))
((LinkLabel)e.getComponent()).jump();
}
public void keyPressed(KeyEvent e)
{
if (e.getModifiers() == 0 && e.getKeyCode() == KeyEvent.VK_ENTER)
((LinkLabel)e.getComponent()).jump();
}
public void keyReleased(KeyEvent e)
{
// no op
}
public void keyTyped(KeyEvent e)
{
// no op
}
}
public static String underline(String title)
{
return styleLabel(false, true, false, title);
}
public static String styleLabel(boolean bold, boolean underline, boolean italic, String text)
{
StringBuilder sb = new StringBuilder("<html><body>");
if (bold) sb.append("<b>");
if (underline) sb.append("<u>");
if (italic) sb.append("<i>");
sb.append(text);
if (italic) sb.append("</i>");
if (underline) sb.append("</u>");
if (bold) sb.append("</b>");
sb.append("</body></html>");
return sb.toString();
}
}