mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
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:
105
src/main/java/forge/gui/toolbox/FHyperlink.java
Normal file
105
src/main/java/forge/gui/toolbox/FHyperlink.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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   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   {@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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user