mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
GUI: added old what's new page (build-in window on startup);
This commit is contained in:
parent
e04306c51f
commit
8f7abe2dc5
12 changed files with 540 additions and 24 deletions
|
|
@ -144,6 +144,24 @@
|
|||
<version>1.17</version>
|
||||
</dependency>
|
||||
<!-- svg support END -->
|
||||
|
||||
<!-- JavaFX support (build-in browser) START -->
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>11.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-swing</artifactId>
|
||||
<version>11.0.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-web</artifactId>
|
||||
<version>11.0.2</version>
|
||||
</dependency>
|
||||
<!-- JavaFX support (build-in browser) END -->
|
||||
</dependencies>
|
||||
|
||||
<!-- to get the reference to local repository with com\googlecode\jspf\jspf-core\0.9.1\ -->
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.SocketException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Executors;
|
||||
|
|
@ -109,6 +111,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
private static CallbackClient callbackClient;
|
||||
private static final Preferences PREFS = Preferences.userNodeForPackage(MageFrame.class);
|
||||
private final JPanel fakeTopPanel;
|
||||
private WhatsNewDialog whatsNewDialog; // can be null
|
||||
private JLabel title;
|
||||
private Rectangle titleRectangle;
|
||||
private static final MageVersion VERSION = new MageVersion(MageFrame.class);
|
||||
|
|
@ -306,6 +309,15 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
errorDialog.setLocation(100, 100);
|
||||
desktopPane.add(errorDialog, JLayeredPane.MODAL_LAYER);
|
||||
|
||||
try {
|
||||
this.whatsNewDialog = new WhatsNewDialog();
|
||||
} catch (Throwable e) {
|
||||
// example: JavaFX is not supported on old MacOS with OpenJDK
|
||||
// https://bugs.openjdk.java.net/browse/JDK-8202132
|
||||
LOGGER.error("JavaFX is not supported by your system. What's new page will be disabled.", e);
|
||||
this.whatsNewDialog = null;
|
||||
}
|
||||
|
||||
PING_SENDER_EXECUTOR.scheduleAtFixedRate(SessionHandler::ping, TablesPanel.PING_SERVER_SECS, TablesPanel.PING_SERVER_SECS, TimeUnit.SECONDS);
|
||||
|
||||
updateMemUsageTask = new UpdateMemUsageTask(jMemUsageLabel);
|
||||
|
|
@ -384,6 +396,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
setWindowTitle();
|
||||
});
|
||||
|
||||
// run what's new checks (loading in background)
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
showWhatsNewDialog(false);
|
||||
});
|
||||
}
|
||||
|
||||
private void bootstrapSetsAndFormats() {
|
||||
|
|
@ -1861,8 +1878,14 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
updateTooltipContainerSizes();
|
||||
}
|
||||
|
||||
public static void showWhatsNewDialog() {
|
||||
AppUtil.openUrlInBrowser("https://jaydi85.github.io/xmage-web-news/news.html");
|
||||
public void showWhatsNewDialog(boolean forceToShowPage) {
|
||||
if (whatsNewDialog != null) {
|
||||
// build-in browser
|
||||
whatsNewDialog.checkUpdatesAndShow(forceToShowPage);
|
||||
} else {
|
||||
// system browser
|
||||
AppUtil.openUrlInSystemBrowser(WhatsNewDialog.WHATS_NEW_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isGameFrameActive(UUID gameId) {
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ public class AboutDialog extends MageDialog {
|
|||
}//GEN-LAST:event_btnOkActionPerformed
|
||||
|
||||
private void btnWhatsNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnWhatsNewActionPerformed
|
||||
MageFrame.showWhatsNewDialog();
|
||||
MageFrame.getInstance().showWhatsNewDialog(true);
|
||||
}//GEN-LAST:event_btnWhatsNewActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import mage.utils.StreamUtils;
|
|||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
|
@ -739,11 +738,11 @@ public class ConnectDialog extends MageDialog {
|
|||
}//GEN-LAST:event_btnFlagSearchActionPerformed
|
||||
|
||||
private void btnCheckStatusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckStatusActionPerformed
|
||||
AppUtil.openUrlInBrowser("http://xmage.today/servers/");
|
||||
AppUtil.openUrlInSystemBrowser("http://xmage.today/servers/");
|
||||
}//GEN-LAST:event_btnCheckStatusActionPerformed
|
||||
|
||||
private void btnWhatsNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnWhatsNewActionPerformed
|
||||
MageFrame.showWhatsNewDialog();
|
||||
MageFrame.getInstance().showWhatsNewDialog(true);
|
||||
}//GEN-LAST:event_btnWhatsNewActionPerformed
|
||||
|
||||
private void btnFindMainActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindMainActionPerformed
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public class ErrorDialog extends MageDialog {
|
|||
CardUtil.urlEncode(title),
|
||||
CardUtil.urlEncode(body)
|
||||
);
|
||||
AppUtil.openUrlInBrowser(url);
|
||||
AppUtil.openUrlInSystemBrowser(url);
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="panelData" max="32767" attributes="0"/>
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="buttonRefresh" min="-2" pref="100" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="buttonCancel" min="-2" pref="100" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="panelData" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="buttonCancel" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
|
||||
<Component id="buttonRefresh" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="buttonCancel">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Close"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonCancelActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="buttonRefresh">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Refresh"/>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="buttonRefreshActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="panelData">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
411
Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.java
Normal file
411
Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.java
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
package mage.client.dialog;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.concurrent.Worker;
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.web.WebEngine;
|
||||
import javafx.scene.web.WebView;
|
||||
import mage.client.MageFrame;
|
||||
import mage.client.remote.XmageURLConnection;
|
||||
import mage.client.util.AppUtil;
|
||||
import mage.client.util.GUISizeHelper;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.w3c.dom.events.EventListener;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.*;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* App GUI: what's new dialog with latest news.
|
||||
* Uses system browser. Shows on app's start after page ready.
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class WhatsNewDialog extends MageDialog {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(WhatsNewDialog.class);
|
||||
|
||||
// cookies store tester: https://setcookie.net/
|
||||
public static final String WHATS_NEW_PAGE = "https://jaydi85.github.io/xmage-web-news/news.html";
|
||||
private static final String WHATS_NEW_VERSION_PAGE = "https://jaydi85.github.io/xmage-web-news/news_version.html"; // increment version=123 to auto-shown for all users
|
||||
private static final int WHATS_NEW_MAX_LOAD_TIMEOUT_SECS = 20; // timeout for page loading (example: no network)
|
||||
private static final boolean WHATS_NEW_DEBUG_ENABLE_CONTROLS = false; // default: false, enable it for debug/test
|
||||
|
||||
private final JFXPanel fxPanel;
|
||||
private WebView webView;
|
||||
private WebEngine engine;
|
||||
private boolean isPageReady = false;
|
||||
|
||||
private SwingWorker<Void, Void> lastWaitingWorker = null;
|
||||
|
||||
public WhatsNewDialog() {
|
||||
initComponents();
|
||||
this.setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
|
||||
fxPanel = new JFXPanel();
|
||||
panelData.add(fxPanel);
|
||||
webView = null;
|
||||
engine = null;
|
||||
|
||||
createWebView();
|
||||
}
|
||||
|
||||
private void showDialog() {
|
||||
this.setModal(true);
|
||||
this.setResizable(true);
|
||||
|
||||
getRootPane().setDefaultButton(buttonCancel);
|
||||
this.setSize(GUISizeHelper.dialogGuiScaleSize(new Dimension(800, 600)));
|
||||
|
||||
// windows settings
|
||||
MageFrame.getDesktop().remove(this);
|
||||
if (this.isModal()) {
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.MODAL_LAYER);
|
||||
} else {
|
||||
MageFrame.getDesktop().add(this, JLayeredPane.PALETTE_LAYER);
|
||||
}
|
||||
this.makeWindowCentered();
|
||||
|
||||
// Close on "ESC"
|
||||
registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||
|
||||
this.setVisible(true);
|
||||
}
|
||||
|
||||
private final SwingWorker<Void, Void> checkUpdatesWorker = new SwingWorker<Void, Void>() {
|
||||
private String newVersion = "";
|
||||
|
||||
@Override
|
||||
public Void doInBackground() {
|
||||
// download version
|
||||
String newsVersion = XmageURLConnection.downloadText(WHATS_NEW_VERSION_PAGE);
|
||||
if (newsVersion.startsWith("version=")) {
|
||||
newVersion = newsVersion.substring("version=".length());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
String oldVersion = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEWS_PAGE_LAST_VERSION, "1");
|
||||
|
||||
boolean isHaveUpdates = newVersion.isEmpty() || !newVersion.equals(oldVersion);
|
||||
if (isHaveUpdates) {
|
||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEWS_PAGE_LAST_VERSION, newVersion);
|
||||
startBrowser(WHATS_NEW_PAGE);
|
||||
startWaitingWorker();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private void startWaitingWorker() {
|
||||
// wait page ready and open it on complete
|
||||
if (this.lastWaitingWorker != null) {
|
||||
this.lastWaitingWorker.cancel(true);
|
||||
}
|
||||
|
||||
this.lastWaitingWorker = new SwingWorker<Void, Void>() {
|
||||
@Override
|
||||
public Void doInBackground() {
|
||||
// waiting page loading
|
||||
int waitedSecs = 0;
|
||||
while (!isPageReady && waitedSecs <= WHATS_NEW_MAX_LOAD_TIMEOUT_SECS) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return null;
|
||||
}
|
||||
|
||||
waitedSecs++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done() {
|
||||
if (isPageReady) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
showDialog();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
this.lastWaitingWorker.execute();
|
||||
}
|
||||
|
||||
public void checkUpdatesAndShow(boolean forceToShowPage) {
|
||||
// lazy loading in background
|
||||
// shows it on page ready or by force
|
||||
|
||||
if (!forceToShowPage) {
|
||||
// checks version -> start loading -> show on isPageReady
|
||||
checkUpdatesWorker.execute();
|
||||
return;
|
||||
}
|
||||
|
||||
// direct open
|
||||
if (isPageReady) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
showDialog();
|
||||
});
|
||||
} else {
|
||||
checkUpdatesWorker.cancel(true);
|
||||
startBrowser(WHATS_NEW_PAGE);
|
||||
startWaitingWorker();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store cookies in preferences
|
||||
*/
|
||||
private static class PersistentCookieStore implements CookieStore, Runnable {
|
||||
private final CookieStore store;
|
||||
|
||||
public PersistentCookieStore() {
|
||||
// improved store with save/load feature
|
||||
store = new CookieManager().getCookieStore();
|
||||
|
||||
// load on startup
|
||||
loadFromPrefs();
|
||||
|
||||
// save on app close
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this));
|
||||
}
|
||||
|
||||
private void saveToPrefs() {
|
||||
// convert cookie to version 1, so it will get full data before save
|
||||
// example: xxx
|
||||
List<String> v1Cookies = store.getCookies().stream()
|
||||
.peek(c -> c.setVersion(1))
|
||||
.map(HttpCookie::toString)
|
||||
.collect(Collectors.toList());
|
||||
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEWS_PAGE_COOKIES, new Gson().toJson(v1Cookies));
|
||||
}
|
||||
|
||||
private void loadFromPrefs() {
|
||||
Type type = new TypeToken<List<String>>() {
|
||||
}.getType();
|
||||
try {
|
||||
String savedData = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEWS_PAGE_COOKIES, "");
|
||||
List<String> savedCookies = new Gson().fromJson(savedData, type);
|
||||
if (savedCookies != null) {
|
||||
savedCookies.forEach(savedCookie -> {
|
||||
// load as version 1, but convert back to version 0 for compatibility
|
||||
List<HttpCookie> v1Cookies = HttpCookie.parse("set-cookie2:" + savedCookie.replace("$", ""));
|
||||
v1Cookies.forEach(realCookie -> {
|
||||
realCookie.setVersion(0);
|
||||
store.add(URI.create(realCookie.getDomain()), realCookie);
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("News page: catch broken cookies", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
saveToPrefs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(URI uri, HttpCookie cookie) {
|
||||
store.add(uri, cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpCookie> get(URI uri) {
|
||||
return store.get(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HttpCookie> getCookies() {
|
||||
return store.getCookies();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<URI> getURIs() {
|
||||
return store.getURIs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(URI uri, HttpCookie cookie) {
|
||||
return store.remove(uri, cookie);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll() {
|
||||
return store.removeAll();
|
||||
}
|
||||
}
|
||||
|
||||
private void createWebView() {
|
||||
|
||||
// init web engine and events
|
||||
// https://docs.oracle.com/javafx/2/swing/swing-fx-interoperability.htm
|
||||
|
||||
// workaround for empty dialog on 2+ opens - keep jfx thread alive (by default it exits on parent window close)
|
||||
// see https://stackoverflow.com/a/32104851
|
||||
Platform.setImplicitExit(false);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
webView = new WebView();
|
||||
engine = webView.getEngine();
|
||||
engine.setJavaScriptEnabled(true);
|
||||
engine.setUserAgent(engine.getUserAgent() + " " + XmageURLConnection.getDefaultUserAgent()); // keep system user-agent too
|
||||
if (!WHATS_NEW_DEBUG_ENABLE_CONTROLS) {
|
||||
webView.contextMenuEnabledProperty().setValue(false);
|
||||
}
|
||||
|
||||
CookieManager cookieManager = new CookieManager(new PersistentCookieStore(), CookiePolicy.ACCEPT_ALL);
|
||||
CookieHandler.setDefault(cookieManager);
|
||||
|
||||
// on error
|
||||
engine.getLoadWorker().exceptionProperty().addListener(new ChangeListener<Throwable>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Throwable> o, Throwable old, final Throwable value) {
|
||||
if (engine.getLoadWorker().getState() == Worker.State.FAILED
|
||||
|| engine.getLoadWorker().getState() == Worker.State.CANCELLED) {
|
||||
LOGGER.error("News page: can't load page", value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// on completed
|
||||
engine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
|
||||
@Override
|
||||
public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
|
||||
if (newState != Worker.State.SUCCEEDED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WHATS_NEW_DEBUG_ENABLE_CONTROLS) {
|
||||
// 1. open all page links in real browser, not build-in window
|
||||
EventListener listener = new EventListener() {
|
||||
@Override
|
||||
public void handleEvent(org.w3c.dom.events.Event ev) {
|
||||
String href = ((org.w3c.dom.Element) ev.getTarget()).getAttribute("href");
|
||||
ev.preventDefault();
|
||||
|
||||
// open browser (must check href on null anyway)
|
||||
if (href != null && href.startsWith("http")) {
|
||||
SwingUtilities.invokeLater(() -> AppUtil.openUrlInSystemBrowser(href));
|
||||
}
|
||||
}
|
||||
};
|
||||
org.w3c.dom.Document doc = engine.getDocument();
|
||||
org.w3c.dom.NodeList listA = doc.getElementsByTagName("a");
|
||||
for (int i = 0; i < listA.getLength(); i++) {
|
||||
((org.w3c.dom.events.EventTarget) listA.item(i)).addEventListener("click", listener, false);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. all done, build-in browser ready to show
|
||||
isPageReady = true;
|
||||
}
|
||||
});
|
||||
|
||||
fxPanel.setScene(new Scene(webView));
|
||||
});
|
||||
}
|
||||
|
||||
public void startBrowser(final String startingUrl) {
|
||||
Platform.runLater(() -> {
|
||||
String link = startingUrl;
|
||||
if (!link.startsWith("http")) {
|
||||
link = "http://" + link;
|
||||
}
|
||||
engine.load(link);
|
||||
});
|
||||
}
|
||||
|
||||
private void onCancel() {
|
||||
this.hideDialog();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
buttonCancel = new JButton();
|
||||
buttonRefresh = new JButton();
|
||||
panelData = new JPanel();
|
||||
|
||||
buttonCancel.setText("Close");
|
||||
buttonCancel.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
buttonCancelActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
buttonRefresh.setText("Refresh");
|
||||
buttonRefresh.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
buttonRefreshActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
panelData.setLayout(new BorderLayout());
|
||||
|
||||
GroupLayout layout = new GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addComponent(panelData, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(buttonRefresh, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(buttonCancel, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(panelData, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(buttonCancel, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(buttonRefresh, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void buttonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCancelActionPerformed
|
||||
onCancel();
|
||||
}//GEN-LAST:event_buttonCancelActionPerformed
|
||||
|
||||
private void buttonRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonRefreshActionPerformed
|
||||
startBrowser(WHATS_NEW_PAGE);
|
||||
}//GEN-LAST:event_buttonRefreshActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private JButton buttonCancel;
|
||||
private JButton buttonRefresh;
|
||||
private JPanel panelData;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
|
@ -141,10 +141,13 @@ public class XmageURLConnection {
|
|||
this.connection.setRequestProperty("Accept-Encoding", "gzip");
|
||||
}
|
||||
|
||||
this.connection.setRequestProperty("User-Agent", getDefaultUserAgent());
|
||||
}
|
||||
|
||||
public static String getDefaultUserAgent() {
|
||||
// user agent due standard notation User-Agent: <product> / <product-version> <comment>
|
||||
// warning, dot not add os, language and other details
|
||||
this.connection.setRequestProperty("User-Agent", String.format("XMage/%s build: %s",
|
||||
version.toString(false), version.getBuildTime()));
|
||||
return String.format("XMage/%s build: %s", version.toString(false), version.getBuildTime());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1752,7 +1752,7 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
}//GEN-LAST:event_btnStateFinishedActionPerformed
|
||||
|
||||
private void buttonWhatsNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonWhatsNewActionPerformed
|
||||
MageFrame.showWhatsNewDialog();
|
||||
MageFrame.getInstance().showWhatsNewDialog(true);
|
||||
}//GEN-LAST:event_buttonWhatsNewActionPerformed
|
||||
|
||||
private void btnQuickStart2PlayerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartDuelActionPerformed
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public class AppUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static void openUrlInBrowser(String url) {
|
||||
public static void openUrlInSystemBrowser(String url) {
|
||||
Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
|
||||
if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
package mage.client.util;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import javax.swing.*;
|
||||
|
||||
|
|
@ -48,14 +44,7 @@ public class URLHandler {
|
|||
return;
|
||||
}
|
||||
if (e.getClickCount() > 0) {
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
Desktop desktop = Desktop.getDesktop();
|
||||
try {
|
||||
URI uri = new URI(url);
|
||||
desktop.browse(uri);
|
||||
} catch (IOException | URISyntaxException ignore) {
|
||||
}
|
||||
}
|
||||
AppUtil.openUrlInSystemBrowser(url);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
2
pom.xml
2
pom.xml
|
|
@ -343,7 +343,7 @@
|
|||
<!-- json support -->
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.8</version>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- extended lib from google (collections, io, etc) -->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue