package com.limegroup.gnutella.gui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.plaf.metal.MetalLabelUI;
/**
* This class uses a timer to continually switch the hyperlink and label.
* The link is displayed as a standard <tt>JLabel</tt> with a blue foreground
* and an overridden paint method to provide underlining.
*/
final class StatusLinkHandler {
/**
* Constant array of <tt>LabelURLPair</tt> instances.
*/
private final LabelURLPair[] LABEL_URLS = {
new LabelURLPair(GUIMediator.getStringResource("SUPPORT_LIMEWIRE_01"),
"http://www.limewire.com/index.jsp/pro&21"),
new LabelURLPair(GUIMediator.getStringResource("SUPPORT_LIMEWIRE_02"),
"http://www.limewire.com/index.jsp/pro&22"),
new LabelURLPair(GUIMediator.getStringResource("SUPPORT_LIMEWIRE_03"),
"http://www.limewire.com/index.jsp/pro&23"),
new LabelURLPair(GUIMediator.getStringResource("SUPPORT_LIMEWIRE_04"),
"http://www.limewire.com/index.jsp/pro&24"),
new LabelURLPair(GUIMediator.getStringResource("SUPPORT_LIMEWIRE_05"),
"http://www.limewire.com/index.jsp/pro&25"),
new LabelURLPair(GUIMediator.getStringResource("SUPPORT_LIMEWIRE_06"),
"http://www.limewire.com/index.jsp/pro&26"),
new LabelURLPair(GUIMediator.getStringResource("SUPPORT_LIMEWIRE_07"),
"http://www.limewire.com/index.jsp/pro&27"),
new LabelURLPair(GUIMediator.getStringResource("SUPPORT_LIMEWIRE_08"),
"http://www.limewire.com/index.jsp/pro&28"),
new LabelURLPair(GUIMediator.getStringResource("SUPPORT_LIMEWIRE_09"),
"http://www.limewire.com/index.jsp/pro&29"),
};
/**
* The index of the currently displayed <tt>LabelURLPair</tt> in the array.
*/
private int _curLabelIndex = 0;
/**
* Constant for the <tt>JLabel</tt> instance that displays the link.
*/
private final JLabel LABEL = new JLabel("", SwingConstants.CENTER);
/**
* The constructor creates the labels, the <tt>Timer</tt> instance,
* and the listeners.
*/
StatusLinkHandler() {
LABEL.setUI(new LinkLabelUI());
FontMetrics fm = LABEL.getFontMetrics(LABEL.getFont());
int width = fm.stringWidth("123456789/123456789/1");
//check if any of the current labels are larger than default and adjust
//it's quite possible the future labels will vary in length
//the layout manager will prevent us from going to large, preferred isn't fixed
if (LABEL_URLS != null)
for (int i = LABEL_URLS.length; --i >= 0; )
width = Math.max(width,fm.stringWidth(LABEL_URLS[i].getLabel()));
Dimension dim = new Dimension(width, fm.getHeight());
LABEL.setForeground(Color.blue); //link color, could grab system attribute as well
LABEL.setPreferredSize(dim);
LABEL.setMaximumSize(dim);
LABEL.setText(getNextLabelURLPair().getLabel());
LABEL.addMouseListener( new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
StatusLinkHandler.this.handleLinkClick();
}
//simulate active cursor, we could choose another cursor though
public void mouseEntered(MouseEvent e) {
e.getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
//go back to normal
public void mouseExited(MouseEvent e) {
e.getComponent().setCursor(Cursor.getDefaultCursor());
}
});
//only build and start timer if there are labels to cycle through
if (LABEL_URLS.length > 1) {
new Timer(30 * 1000, new LabelTimerListener()).start();
}
}
/**
* Private class for handling a change in the link/labal pair.
*/
private class LabelTimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
StatusLinkHandler.this.handleLinkChange();
}
}
/**
* This class wraps a label for the link and the url to link to.
*/
private static final class LabelURLPair {
/**
* Constant for the label string for this pair.
*/
private final String LABEL_STRING;
/**
* Constant for the url for this pair.
*/
private final String URL;
/**
* Creates a new <tt>LabelURLPair</tt> instance with the
* specified label and url.
*
* @param label the label for the link
* @param url to url to link to
*/
private LabelURLPair(final String label, final String url) {
LABEL_STRING = label;
URL = url;
}
/**
* Returns the label's text
* previous implementation returned the text in html format
* to simulate a hyperlink look; the new label provides the
* framework to simulate this work at a substantial reduction
* in memory and processor cost; the jvm treats any html as a
* possible full blown document and sets up the structures to
* process hyper text formatting for just these couple of words
* every 30 seconds (no reuse either). Also, the old html link
* wasn't truly clickable, we use a mouse listener to provide
* mouse clicking action support; <font color=blue>LABEL_STRING</font>
* would have provided the same effect (or affect :)
* previous: return "<html><a href=\"\">"+LABEL_STRING+"</a></html>";
*
* @return the label
*/
private String getLabel() {
return LABEL_STRING;
}
/**
* Returns the url to link to.
*
* @return the url to link to
*/
private String getURL() {
return URL;
}
}
/**
* Returns the <tt>Component</tt> that contains all of the hyperlink.
*
* @return the <tt>Component</tt> the hyperlink
*/
Component getComponent() {
return LABEL;
}
/**
* Returns the next <tt>LabelURLPair</tt> in the list.
*
* @return the next <tt>LabelURLPair</tt> in the list
*/
private LabelURLPair getNextLabelURLPair() {
if(_curLabelIndex == LABEL_URLS.length - 1) {
_curLabelIndex = -1; //reset index
}
_curLabelIndex++;
return LABEL_URLS[_curLabelIndex];
}
/**
* Handle a change in the current <tt>LabelURLPair</tt> pair.
*/
private void handleLinkChange() {
String label = getNextLabelURLPair().getLabel();
LABEL.setText(label);
FontMetrics fm = LABEL.getFontMetrics(LABEL.getFont());
int width = fm.stringWidth(label);
int height = fm.getHeight();
Dimension preferred = new Dimension(width, height);
LABEL.setPreferredSize(preferred);
GUIMediator.instance().getStatusLine().refresh();
}
/**
* Handles a click on the current link by opening the appropriate web
* page.
*/
private void handleLinkClick() {
GUIMediator.openURL(LABEL_URLS[_curLabelIndex].getURL());
}
/**
* This class is a specialized UI class for drawing the link label
* with an underline.
*/
private class LinkLabelUI extends MetalLabelUI {
/**
* Paint clippedText at textX, textY with the labels foreground color.
*
* @see #paint
* @see #paintDisabledText
*/
protected void paintEnabledText(JLabel l, Graphics g, String s,
int textX, int textY) {
super.paintEnabledText(l, g, s, textX, textY);
if (LABEL.getText() == null) return;
FontMetrics fm = g.getFontMetrics();
g.fillRect(textX, fm.getAscent()+2,
fm.stringWidth(LABEL.getText()) -
LABEL.getInsets().right, 1); //X,Y,WIDTH,HEIGHT
}
}
}