add hyperlink widget that opens a URL in the default browser (or copies it in to the clipboard if browsing functionality is not available on the current platform)

This commit is contained in:
myk
2013-02-20 01:42:40 +00:00
parent 5a12903bcf
commit a7f67248d4
2 changed files with 120 additions and 18 deletions

View File

@@ -0,0 +1,105 @@
package forge.gui.toolbox;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import forge.Command;
@SuppressWarnings("serial")
public class FHyperlink extends FLabel {
public static class Builder extends FLabel.Builder {
private String bldUrl;
public Builder() {
bldHoverable = true;
bldReactOnMouseDown = true;
bldCmd = null;
}
public FHyperlink build() {
StringBuilder sb = new StringBuilder();
sb.append("<html><a href='").append(bldUrl).append("'>");
sb.append((null == bldText || bldText.isEmpty()) ? bldUrl : bldText);
sb.append("</a></html>");
final boolean browsingSupported = _isBrowsingSupported();
if (browsingSupported) {
tooltip(bldUrl);
} else {
tooltip(bldUrl + " (click to copy to clipboard)");
}
final URI uri;
try {
uri = new URI(bldUrl);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
// overwrite whatever command is there -- we could chain them if we wanted to, though
cmdClick(new Command() {
@Override
public void execute() {
if (browsingSupported) {
// open link in default browser
new _LinkRunner(uri).execute();
} else {
// copy link to clipboard
StringSelection ss = new StringSelection(bldUrl);
try {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
} catch (IllegalStateException ex) {
JOptionPane.showMessageDialog(null,
"Sorry, a problem occurred while copying this link to your system clipboard.",
"A problem occured", JOptionPane.ERROR_MESSAGE);
}
}
}
});
return new FHyperlink(this);
}
public Builder url(String url) { bldUrl = url; return this; }
private static boolean _isBrowsingSupported() {
if (!Desktop.isDesktopSupported()) {
return false;
}
return Desktop.getDesktop().isSupported(Desktop.Action.BROWSE);
}
}
// Call this using FLabel.Builder()...
private FHyperlink(final Builder b) {
super(b);
setCursor(new Cursor(Cursor.HAND_CURSOR));
}
private static class _LinkRunner extends SwingWorker<Void, Void> {
private final URI uri;
private _LinkRunner(URI u) {
if (u == null) {
throw new NullPointerException();
}
uri = u;
}
@Override
protected Void doInBackground() throws Exception {
Desktop.getDesktop().browse(uri);
return null;
}
}
}

View File

@@ -71,12 +71,12 @@ public class FLabel extends JLabel implements ILocalRepaint {
protected boolean bldOpaque = false;
private boolean bldIconInBackground = false;
private boolean bldIconScaleAuto = true;
private boolean reactOnMouseDown = false;
protected boolean bldReactOnMouseDown = false;
private String bldText, bldToolTip;
protected String bldText, bldToolTip;
private ImageIcon bldIcon;
private int bldFontAlign;
private Command bldCmd;
protected Command bldCmd;
// Build!
/** @return {@link forge.gui.toolbox.FLabel} */
@@ -121,7 +121,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
/**@param b0 &emsp; boolean that controls when the label responds to mouse events
* @return {@link forge.gui.toolbox.Builder} */
public Builder reactOnMouseDown(final boolean b0) { this.reactOnMouseDown = b0; return this; }
public Builder reactOnMouseDown(final boolean b0) { this.bldReactOnMouseDown = b0; return this; }
public Builder reactOnMouseDown() { reactOnMouseDown(true); return this; }
/**@param c0 &emsp; {@link forge.Command} to execute if clicked
@@ -173,11 +173,8 @@ public class FLabel extends JLabel implements ILocalRepaint {
}
//========== Constructors
/** Must have protected constructor to allow Builder to subclass. */
protected FLabel() { }
// Call this using FLabel.Builder()...
private FLabel(final Builder b0) {
protected FLabel(final Builder b0) {
super(b0.bldText);
// Init fields from builder
@@ -195,7 +192,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
this.setFontSize(b0.bldFontSize);
this.setUnhoveredAlpha(b0.bldUnhoveredAlpha);
this.setCommand(b0.bldCmd);
this.setReactOnMouseDown(b0.reactOnMouseDown);
this.setReactOnMouseDown(b0.bldReactOnMouseDown);
this.setFontAlign(b0.bldFontAlign);
this.setToolTipText(b0.bldToolTip);
this.setHoverable(b0.bldHoverable);
@@ -293,7 +290,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
private void _doMouseAction() {
if (selectable) { setSelected(!selected); }
if (cmdClick != null && FLabel.this.isEnabled()) {
if (cmdClick != null && isEnabled()) {
hovered = false;
repaintSelf();
cmdClick.execute();
@@ -447,7 +444,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
/** Major performance kicker - won't repaint whole screen! */
@Override
public void repaintSelf() {
final Dimension d = FLabel.this.getSize();
final Dimension d = getSize();
repaint(0, 0, d.width, d.height);
}
@@ -546,7 +543,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
int w = (int) (h * iar);
if (w == 0 || h == 0) { return; }
FLabel.super.setIcon(new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH)));
super.setIcon(new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH)));
}
}
}