From cb268a25ee64a38e6f762539e6120f5e01cfb4cd Mon Sep 17 00:00:00 2001
From: Alex Vasile <48962821+Alex-Vasile@users.noreply.github.com>
Date: Mon, 25 Jul 2022 09:09:43 -0400
Subject: [PATCH] Removed dependency on JavaFX. What's New button now opens the
link in the system browser.
---
.../src/main/java/mage/client/MageFrame.java | 30 +-
.../java/mage/client/dialog/AboutDialog.java | 2 +-
.../mage/client/dialog/ConnectDialog.java | 2 +-
.../mage/client/dialog/WhatsNewDialog.form | 73 ---
.../mage/client/dialog/WhatsNewDialog.java | 436 ------------------
.../java/mage/client/table/TablesPanel.java | 2 +-
6 files changed, 16 insertions(+), 529 deletions(-)
delete mode 100644 Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.form
delete mode 100644 Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.java
diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java
index 1100c708d60..f747ae528df 100644
--- a/Mage.Client/src/main/java/mage/client/MageFrame.java
+++ b/Mage.Client/src/main/java/mage/client/MageFrame.java
@@ -70,6 +70,8 @@ import java.awt.image.BufferedImage;
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;
@@ -101,7 +103,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
private static MageFrame instance;
private final ConnectDialog connectDialog;
- private WhatsNewDialog whatsNewDialog; // can be null
private final ErrorDialog errorDialog;
private static CallbackClient callbackClient;
private static final Preferences PREFS = Preferences.userNodeForPackage(MageFrame.class);
@@ -270,14 +271,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
SessionHandler.startSession(this);
callbackClient = new CallbackClientImpl(this);
connectDialog = new ConnectDialog();
- try {
- whatsNewDialog = new WhatsNewDialog();
- } catch (NoClassDefFoundError e) {
- // 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);
- whatsNewDialog = null;
- }
desktopPane.add(connectDialog, JLayeredPane.MODAL_LAYER);
errorDialog = new ErrorDialog();
errorDialog.setLocation(100, 100);
@@ -359,11 +352,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
SystemUtil.toggleMacOSFullScreenMode(this);
}
}
-
- // run what's new checks (loading in background)
- SwingUtilities.invokeLater(() -> {
- showWhatsNewDialog(false);
- });
}
private void setWindowTitle() {
@@ -1655,9 +1643,17 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
updateTooltipContainerSizes();
}
- public void showWhatsNewDialog(boolean forceToShowPage) {
- if (whatsNewDialog != null) {
- whatsNewDialog.checkUpdatesAndShow(forceToShowPage);
+ public static void showWhatsNewDialog() {
+ try {
+ URI newsURI = new URI("https://jaydi85.github.io/xmage-web-news/news.html");
+ Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
+ if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
+ desktop.browse(newsURI);
+ }
+ } catch (URISyntaxException e) {
+ LOGGER.error("URI Syntax error when creating news link", e);
+ } catch (IOException e) {
+ LOGGER.error("IOException while loading news page", e);
}
}
diff --git a/Mage.Client/src/main/java/mage/client/dialog/AboutDialog.java b/Mage.Client/src/main/java/mage/client/dialog/AboutDialog.java
index 4e1ac407315..a5e4a0032fe 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/AboutDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/AboutDialog.java
@@ -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.getInstance().showWhatsNewDialog(true);
+ MageFrame.showWhatsNewDialog();
}//GEN-LAST:event_btnWhatsNewActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
index 04b881738fb..0b05b82a61c 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
@@ -817,7 +817,7 @@ public class ConnectDialog extends MageDialog {
}//GEN-LAST:event_btnCheckStatusActionPerformed
private void btnWhatsNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnWhatsNewActionPerformed
- MageFrame.getInstance().showWhatsNewDialog(true);
+ MageFrame.getInstance().showWhatsNewDialog();
}//GEN-LAST:event_btnWhatsNewActionPerformed
private void btnFindMainActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindMainActionPerformed
diff --git a/Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.form b/Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.form
deleted file mode 100644
index af26b1a5408..00000000000
--- a/Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.form
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
diff --git a/Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.java b/Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.java
deleted file mode 100644
index 4c00fc76a2a..00000000000
--- a/Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.java
+++ /dev/null
@@ -1,436 +0,0 @@
-package mage.client.dialog;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-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.utils.MageVersion;
-import org.apache.log4j.Logger;
-import org.w3c.dom.events.EventListener;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.KeyEvent;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Type;
-import java.net.*;
-import java.util.List;
-import java.util.Scanner;
-import java.util.concurrent.TimeUnit;
-
-/**
- * App GUI: show latest xmage news from the web page
- *
- * @author JayDi85
- */
-public class WhatsNewDialog extends MageDialog {
-
- private static final Logger LOGGER = Logger.getLogger(WhatsNewDialog.class);
- private static final MageVersion CLIENT_VERSION = new MageVersion(WhatsNewDialog.class);
-
- // cookies tester: http://www.html-kit.com/tools/cookietester/
- private 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_LOAD_TIMEOUT_SECS = 20; // timeout for page loading
-
- private final JFXPanel fxPanel;
- private WebView webView;
- private WebEngine engine;
- private boolean isPageReady = false;
-
- private final SwingWorker backgroundWorker = new SwingWorker() {
- @Override
- public Void doInBackground() {
- try {
- int maxWait = WHATS_NEW_LOAD_TIMEOUT_SECS;
- int currentWait = 0;
- while (!isPageReady) {
- TimeUnit.SECONDS.sleep(1);
- currentWait++;
- if (currentWait > maxWait) {
- LOGGER.error("Can't load news page: " + WHATS_NEW_PAGE);
- break;
- }
- }
- } catch (InterruptedException e) {
- LOGGER.error("Checking news was interrupted", e);
- Thread.currentThread().interrupt();
- }
- return null;
- }
-
- @Override
- public void done() {
- SwingUtilities.invokeLater(() -> {
- if (isPageReady) {
- showDialog();
- }
- });
- }
- };
-
- private final SwingWorker backgroundUpdatesWorker = new SwingWorker() {
-
- private String newVersion = "";
-
- @Override
- public Void doInBackground() {
- try {
- // download version
- URLConnection connection = new URL(WHATS_NEW_VERSION_PAGE).openConnection();
- connection.setRequestProperty("user-agent", "xmage");
- InputStream download = connection.getInputStream();
- Scanner s = new Scanner(download).useDelimiter("\\A");
- String result = s.hasNext() ? s.next() : "";
-
- // check version (default: always have new version)
- if (result.startsWith("version=")) {
- newVersion = result.substring("version=".length());
- }
- } catch (MalformedURLException e) {
- LOGGER.error("Checking updates got wrong url " + WHATS_NEW_VERSION_PAGE, e);
- } catch (IOException e) {
- LOGGER.error("Checking updates got error", e);
- }
- return null;
- }
-
- @Override
- public void done() {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- 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);
- loadURL(WHATS_NEW_PAGE);
- backgroundWorker.execute();
- }
- }
- });
- }
- };
-
- public WhatsNewDialog() {
- initComponents();
- this.setDefaultCloseOperation(HIDE_ON_CLOSE);
-
- fxPanel = new JFXPanel();
- panelData.add(fxPanel);
- webView = null;
- engine = null;
-
- createWebView();
- }
-
- public void checkUpdatesAndShow(boolean forceToShowPage) {
- // lazy loading in background
- // shows it on page ready or by force
-
- isPageReady = false;
- if (forceToShowPage) {
- // direct open
- loadURL(WHATS_NEW_PAGE);
- if (!backgroundUpdatesWorker.isDone()) backgroundUpdatesWorker.cancel(true);
- if (!backgroundWorker.isDone()) backgroundWorker.cancel(true);
-
- showDialog();
- } else {
- // checks version -> loads on new
- backgroundUpdatesWorker.execute();
- }
- }
-
- private void showDialog() {
- this.setModal(true);
- this.setResizable(true);
- getRootPane().setDefaultButton(buttonCancel);
- this.setSize(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);
- }
-
-
- /**
- * Store cookies in preferences
- */
- private class PersistentCookieStore implements CookieStore, Runnable {
- private final CookieStore store;
-
- public PersistentCookieStore() {
- store = new CookieManager().getCookieStore();
-
- // restore data
- loadFromPrefs();
-
- // save data on app close
- Runtime.getRuntime().addShutdownHook(new Thread(this));
- }
-
- private void loadFromPrefs() {
- String sourceValue = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEWS_PAGE_COOKIES, "");
-
- Gson gson = new GsonBuilder().create();
- List httpCookies;
- Type type = new TypeToken>() {
- }.getType();
- try {
- httpCookies = gson.fromJson(sourceValue, type);
- if (httpCookies != null) {
- for (HttpCookie cookie : httpCookies) {
- store.add(URI.create(cookie.getDomain()), cookie);
- }
- }
- } catch (Exception e) {
- LOGGER.error("Wrong news page cookies", e);
- }
- }
-
- private void saveToPrefs() {
- List httpCookies = store.getCookies();
- Gson gson = new GsonBuilder().create();
- String destValue = gson.toJson(httpCookies);
- PreferencesDialog.saveValue(PreferencesDialog.KEY_NEWS_PAGE_COOKIES, destValue);
- }
-
- @Override
- public void run() {
- saveToPrefs();
- }
-
- @Override
- public void add(URI uri, HttpCookie cookie) {
- store.add(uri, cookie);
- }
-
- @Override
- public List get(URI uri) {
- return store.get(uri);
- }
-
- @Override
- public List getCookies() {
- return store.getCookies();
- }
-
- @Override
- public List 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
-
- Platform.runLater(new Runnable() {
- @Override
- public void run() {
-
- webView = new WebView();
- engine = webView.getEngine();
- engine.setUserAgent(engine.getUserAgent() + " XMage/" + CLIENT_VERSION.toString(false));
- webView.contextMenuEnabledProperty().setValue(false);
-
- CookieManager cookieManager = new CookieManager(new PersistentCookieStore(), CookiePolicy.ACCEPT_ALL);
- CookieHandler.setDefault(cookieManager);
-
- // on error
- engine.getLoadWorker().exceptionProperty().addListener(new ChangeListener() {
- @Override
- public void changed(ObservableValue extends Throwable> o, Throwable old, final Throwable value) {
- if (engine.getLoadWorker().getState() == Worker.State.FAILED) {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- LOGGER.error("Can't load news page: " + (value != null ? value.getMessage() : "null"), value);
- }
- });
- }
- }
- });
-
- // on completed
- engine.getLoadWorker().stateProperty().addListener(new ChangeListener() {
- @Override
- public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
- if (newState == Worker.State.SUCCEEDED) {
-
- // 1. replace urls with custom click processing
- // all classes from org.w3c.dom
- org.w3c.dom.events.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();
-
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- if (Desktop.isDesktopSupported()) {
- Desktop desktop = Desktop.getDesktop();
- try {
- URI uri = new URI(href);
- desktop.browse(uri);
- } catch (IOException | URISyntaxException ex) {
- // do nothing
- }
- }
- }
- });
- }
- };
- 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. page can be shown
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- isPageReady = true;
- }
- });
- }
- }
- });
-
- fxPanel.setScene(new Scene(webView));
- }
- });
- }
-
- public void loadURL(final String url) {
- Platform.runLater(new Runnable() {
- @Override
- public void run() {
- String tmp = toURL(url);
- if (url == null) {
- tmp = toURL("http://" + url);
- }
- engine.load(tmp);
- }
- });
- }
-
- private static String toURL(String str) {
- try {
- return new URL(str).toExternalForm();
- } catch (MalformedURLException exception) {
- return null;
- }
- }
-
-
- 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")
- // //GEN-BEGIN:initComponents
- private void initComponents() {
-
- buttonCancel = new javax.swing.JButton();
- buttonRefresh = new javax.swing.JButton();
- panelData = new javax.swing.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 java.awt.BorderLayout());
-
- javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
- getContentPane().setLayout(layout);
- layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(panelData, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(layout.createSequentialGroup()
- .addComponent(buttonRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(buttonCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
- .addContainerGap())
- );
- layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addComponent(panelData, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(buttonCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(buttonRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addContainerGap())
- );
-
- pack();
- }// //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
- loadURL(WHATS_NEW_PAGE);
- }//GEN-LAST:event_buttonRefreshActionPerformed
-
- // Variables declaration - do not modify//GEN-BEGIN:variables
- private javax.swing.JButton buttonCancel;
- private javax.swing.JButton buttonRefresh;
- private javax.swing.JPanel panelData;
- // End of variables declaration//GEN-END:variables
-}
diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
index 6b53a9097ac..8282e14b8e2 100644
--- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
+++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
@@ -1760,7 +1760,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.getInstance().showWhatsNewDialog(true);
+ MageFrame.showWhatsNewDialog();
}//GEN-LAST:event_buttonWhatsNewActionPerformed
private void btnQuickStart2PlayerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuickStartDuelActionPerformed