// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 - 2005 Jon Olav Hauglid
// See LICENSE.txt for license information
package org.infinity.gui;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingConstants;
import org.infinity.NearInfinity;
import org.infinity.datatype.ResourceRef;
import org.infinity.resource.ResourceFactory;
import org.infinity.resource.key.ResourceEntry;
import org.infinity.updater.Utils;
/**
* A JLabel-based control which supports either internal game resources or external URLs.
*/
final public class LinkButton extends JLabel implements MouseListener, ActionListener
{
private static final String CMD_OPEN = "OPEN"; // open resource in same window
private static final String CMD_OPEN_NEW = "OPEN_NEW"; // open resource in new window
private static final String CMD_BROWSE = "BROWSE"; // open URL in system-default browser
private final List<ActionListener> listeners = new ArrayList<ActionListener>();
private ResourceEntry entry;
private String url;
private boolean isResource;
/**
* Creates a link button which points to an internal game resource as specified by the argument.
* @param resourceRef The game resource as ResourceRef object.
*/
public LinkButton(ResourceRef resourceRef)
{
super();
setHorizontalAlignment(SwingConstants.LEFT);
setResource(resourceRef);
}
/**
* Creates a link button which points to an internal game resource as specified by the argument.
* @param resourceName The game resource as string.
*/
public LinkButton(String resourceName)
{
super();
setHorizontalAlignment(SwingConstants.LEFT);
setResource(resourceName);
}
/**
* Creates a link button which points to an external URL.
* @param text The display name of the link.
* @param url The actual URL of the link.
*/
public LinkButton(String text, String url)
{
super();
setHorizontalAlignment(SwingConstants.LEFT);
setUrl(text, url);
}
/** Creates a link from the specified resource reference. */
public void setResource(ResourceRef resourceRef)
{
if (resourceRef != null) {
setResource(resourceRef, resourceRef.toString());
} else {
setResource(null, "");
}
}
/** Attempts to create a link from the specified resource name. */
public void setResource(String resourceName)
{
setResource(null, resourceName);
}
// Uses either ResourceRef or String to create a link
private void setResource(ResourceRef resource, String resourceName)
{
isResource = true;
removeActionListener(this);
if (resource != null) {
entry = ResourceFactory.getResourceEntry(resource.getResourceName());
if (resourceName == null) {
resourceName = resource.toString();
}
} else {
entry = ResourceFactory.getResourceEntry(resourceName);
if (resourceName == null) {
resourceName = "";
}
}
if (entry != null) {
addActionListener(this);
setLink(resourceName, entry.getResourceName(), true);
setEnabled(true);
setToolTipText(null);
} else {
setLink(resourceName, null, false);
setEnabled(false);
setToolTipText("Resource not found");
}
}
// Sets link or label text, depending on arguments
private void setLink(String text, String resource, boolean asLink)
{
removeMouseListener(this);
setCursor(null);
if (text == null) {
text = resource;
}
if (!asLink) {
setText(text);
} else if (resource != null && !resource.isEmpty()) {
setText("<html><a href=\"" + resource + "\">" + text + "</a></html");
addMouseListener(this);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
} else {
setText("");
}
}
/** Creates a link to an external URL. */
public void setUrl(String text, String url)
{
isResource = false;
if (url == null || url.isEmpty()) {
url = "about:blank";
}
if (text == null || text.isEmpty()) {
text = url;
}
this.url = url;
addActionListener(this);
setLink(text, url, true);
setEnabled(true);
}
/** Returns the external link or internal resource entry as string. */
public String getUrl()
{
if (isResource) {
return entry.toString();
} else {
return url;
}
}
// --------------------- Begin Interface ActionListener ---------------------
@Override
public void actionPerformed(ActionEvent e)
{
String cmd = e.getActionCommand();
if ((cmd == null) || cmd.equals(CMD_OPEN_NEW)) {
new ViewFrame(((LinkButton)e.getSource()).getTopLevelAncestor(),
ResourceFactory.getResource(entry));
} else if (cmd.equals(CMD_OPEN)) {
NearInfinity.getInstance().showResourceEntry(entry);
} else if (cmd.equals(CMD_BROWSE)) {
try {
Utils.openWebPage(new URL(getUrl()));
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(((LinkButton)e.getSource()).getTopLevelAncestor(),
"Error opening link in browser.", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
}
// --------------------- End Interface ActionListener ---------------------
// --------------------- Begin Interface MouseListener ---------------------
@Override
public void mouseClicked(MouseEvent e)
{
String cmd;
if (isResource) {
if ((e.getButton() == MouseEvent.BUTTON2)
|| (e.getButton() == MouseEvent.BUTTON3)) {
cmd = CMD_OPEN;
} else {
cmd = CMD_OPEN_NEW;
}
} else {
cmd = CMD_BROWSE;
}
ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, cmd);
for (int i = 0; i < listeners.size(); i++)
listeners.get(i).actionPerformed(event);
}
@Override
public void mousePressed(MouseEvent e)
{
}
@Override
public void mouseReleased(MouseEvent e)
{
}
@Override
public void mouseEntered(MouseEvent e)
{
}
@Override
public void mouseExited(MouseEvent e)
{
}
// --------------------- End Interface MouseListener ---------------------
public void removeActionListener(ActionListener listener)
{
listeners.remove(listener);
}
private void addActionListener(ActionListener listener)
{
listeners.add(listener);
}
}