mirror of
https://github.com/correl/mage.git
synced 2025-01-12 19:25:44 +00:00
* UI: added "what's new" page dialog with latest news (auto-loads on startup or from about dialog);
This commit is contained in:
parent
5a3fd7c558
commit
d45e63d946
5 changed files with 492 additions and 55 deletions
|
@ -92,6 +92,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
||||||
private static MageFrame instance;
|
private static MageFrame instance;
|
||||||
|
|
||||||
private final ConnectDialog connectDialog;
|
private final ConnectDialog connectDialog;
|
||||||
|
private final WhatsNewDialog whatsNewDialog;
|
||||||
private final ErrorDialog errorDialog;
|
private final ErrorDialog errorDialog;
|
||||||
private static CallbackClient callbackClient;
|
private static CallbackClient callbackClient;
|
||||||
private static final Preferences PREFS = Preferences.userNodeForPackage(MageFrame.class);
|
private static final Preferences PREFS = Preferences.userNodeForPackage(MageFrame.class);
|
||||||
|
@ -243,6 +244,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
||||||
SessionHandler.startSession(this);
|
SessionHandler.startSession(this);
|
||||||
callbackClient = new CallbackClientImpl(this);
|
callbackClient = new CallbackClientImpl(this);
|
||||||
connectDialog = new ConnectDialog();
|
connectDialog = new ConnectDialog();
|
||||||
|
whatsNewDialog = new WhatsNewDialog();
|
||||||
desktopPane.add(connectDialog, JLayeredPane.MODAL_LAYER);
|
desktopPane.add(connectDialog, JLayeredPane.MODAL_LAYER);
|
||||||
errorDialog = new ErrorDialog();
|
errorDialog = new ErrorDialog();
|
||||||
errorDialog.setLocation(100, 100);
|
errorDialog.setLocation(100, 100);
|
||||||
|
@ -329,6 +331,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
||||||
SystemUtil.toggleMacOSFullScreenMode(this);
|
SystemUtil.toggleMacOSFullScreenMode(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// run what's new checks (loading in background)
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
whatsNewDialog.checkUpdatesAndShow(false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setWindowTitle() {
|
private void setWindowTitle() {
|
||||||
|
@ -1523,6 +1530,10 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
||||||
|
|
||||||
addTooltipContainer();
|
addTooltipContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WhatsNewDialog getWhatsNewDialog() {
|
||||||
|
return whatsNewDialog;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MagePaneMenuItem extends JCheckBoxMenuItem {
|
class MagePaneMenuItem extends JCheckBoxMenuItem {
|
||||||
|
|
|
@ -27,14 +27,23 @@
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="1" attributes="0">
|
<Group type="103" groupAlignment="1" attributes="0">
|
||||||
<Component id="jLabel3" alignment="0" max="32767" attributes="0"/>
|
<Component id="jLabel3" alignment="0" max="32767" attributes="0"/>
|
||||||
|
<Group type="102" alignment="1" attributes="0">
|
||||||
|
<Component id="btnWhatsNew" min="-2" pref="100" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
|
<Component id="btnOk" min="-2" pref="100" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Component id="jLabel4" alignment="0" max="32767" attributes="0"/>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="1" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="lblVersion" min="-2" max="-2" attributes="0"/>
|
<Component id="lblVersion" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="btnOk" alignment="1" min="-2" max="-2" attributes="0"/>
|
</Group>
|
||||||
<Component id="jLabel4" alignment="0" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
|
@ -54,8 +63,11 @@
|
||||||
<Component id="jLabel3" min="-2" pref="21" max="-2" attributes="0"/>
|
<Component id="jLabel3" min="-2" pref="21" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
|
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace pref="71" max="32767" attributes="0"/>
|
<EmptySpace pref="68" max="32767" attributes="0"/>
|
||||||
<Component id="btnOk" min="-2" max="-2" attributes="0"/>
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="btnOk" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
|
||||||
|
<Component id="btnWhatsNew" alignment="3" min="-2" pref="30" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
|
@ -64,7 +76,7 @@
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Component class="javax.swing.JButton" name="btnOk">
|
<Component class="javax.swing.JButton" name="btnOk">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="text" type="java.lang.String" value="OK"/>
|
<Property name="text" type="java.lang.String" value="Close"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
<Events>
|
<Events>
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnOkActionPerformed"/>
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnOkActionPerformed"/>
|
||||||
|
@ -95,5 +107,13 @@
|
||||||
<Property name="text" type="java.lang.String" value="fireshoes, lunaskyrise, mnapoleon, jgod, LoneFox."/>
|
<Property name="text" type="java.lang.String" value="fireshoes, lunaskyrise, mnapoleon, jgod, LoneFox."/>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component class="javax.swing.JButton" name="btnWhatsNew">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" value="What's new"/>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnWhatsNewActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
@ -1,26 +1,18 @@
|
||||||
|
|
||||||
|
|
||||||
package mage.client.dialog;
|
package mage.client.dialog;
|
||||||
|
|
||||||
|
import mage.client.MageFrame;
|
||||||
import mage.utils.MageVersion;
|
import mage.utils.MageVersion;
|
||||||
|
|
||||||
/*
|
import javax.swing.*;
|
||||||
* AboutDialog.java
|
import java.awt.event.KeyEvent;
|
||||||
*
|
|
||||||
* Created on Mar 10, 2010, 8:19:41 AM
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @author JayDi85
|
||||||
* @author BetaSteward_at_googlemail.com
|
|
||||||
*/
|
*/
|
||||||
public class AboutDialog extends MageDialog {
|
public class AboutDialog extends MageDialog {
|
||||||
|
|
||||||
/** Creates new form AboutDialog */
|
|
||||||
public AboutDialog() {
|
public AboutDialog() {
|
||||||
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
|
||||||
initComponents();
|
initComponents();
|
||||||
this.modal = false;
|
this.modal = false;
|
||||||
}
|
}
|
||||||
|
@ -28,10 +20,28 @@ public class AboutDialog extends MageDialog {
|
||||||
public void showDialog(MageVersion version) {
|
public void showDialog(MageVersion version) {
|
||||||
this.lblVersion.setText(version.toString());
|
this.lblVersion.setText(version.toString());
|
||||||
this.setLocation(100, 100);
|
this.setLocation(100, 100);
|
||||||
|
|
||||||
|
// 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);
|
this.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This method is called from within the constructor to
|
private void onCancel() {
|
||||||
|
this.hideDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to
|
||||||
* initialize the form.
|
* initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is
|
* WARNING: Do NOT modify this code. The content of this method is
|
||||||
* always regenerated by the Form Editor.
|
* always regenerated by the Form Editor.
|
||||||
|
@ -46,12 +56,17 @@ public class AboutDialog extends MageDialog {
|
||||||
jLabel2 = new javax.swing.JLabel();
|
jLabel2 = new javax.swing.JLabel();
|
||||||
jLabel3 = new javax.swing.JLabel();
|
jLabel3 = new javax.swing.JLabel();
|
||||||
jLabel4 = new javax.swing.JLabel();
|
jLabel4 = new javax.swing.JLabel();
|
||||||
|
btnWhatsNew = new javax.swing.JButton();
|
||||||
|
|
||||||
setMaximizable(true);
|
setMaximizable(true);
|
||||||
setTitle("About XMage");
|
setTitle("About XMage");
|
||||||
|
|
||||||
btnOk.setText("OK");
|
btnOk.setText("Close");
|
||||||
btnOk.addActionListener(this::btnOkActionPerformed);
|
btnOk.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
btnOkActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
jLabel1.setText("XMage client");
|
jLabel1.setText("XMage client");
|
||||||
|
|
||||||
|
@ -59,8 +74,16 @@ public class AboutDialog extends MageDialog {
|
||||||
|
|
||||||
jLabel2.setText("Courtesy: BetaSteward@googlemail.com. Site: http://XMage.de/");
|
jLabel2.setText("Courtesy: BetaSteward@googlemail.com. Site: http://XMage.de/");
|
||||||
|
|
||||||
jLabel3.setText("Devs: BetaSteward, Noxx, Eugen.Rivniy, North, LevelX2, Jeff, Plopman, dustinconrad, emerald000,");
|
jLabel3.setText("Devs: BetaSteward, Noxx, Eugen.Rivniy, North, LevelX2, Jeff, Plopman, dustinconrad, emerald000.,");
|
||||||
jLabel4.setText("fireshoes, lunaskyrise, mnapoleon, jgod, LoneFox, drmDev, spjspj, TheElk801, L_J, JayDi85.");
|
|
||||||
|
jLabel4.setText("fireshoes, lunaskyrise, mnapoleon, jgod, LoneFox.");
|
||||||
|
|
||||||
|
btnWhatsNew.setText("What's new");
|
||||||
|
btnWhatsNew.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
btnWhatsNewActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||||
getContentPane().setLayout(layout);
|
getContentPane().setLayout(layout);
|
||||||
|
@ -70,13 +93,19 @@ public class AboutDialog extends MageDialog {
|
||||||
.addContainerGap()
|
.addContainerGap()
|
||||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
.addComponent(jLabel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(jLabel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(btnWhatsNew, 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(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
|
.addComponent(jLabel4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
|
||||||
.addComponent(jLabel1)
|
.addComponent(jLabel1)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(lblVersion))
|
.addComponent(lblVersion))
|
||||||
.addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING)
|
.addComponent(jLabel2, javax.swing.GroupLayout.Alignment.LEADING))
|
||||||
.addComponent(btnOk)
|
.addGap(0, 0, Short.MAX_VALUE)))
|
||||||
.addComponent(jLabel4, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
|
@ -92,8 +121,10 @@ public class AboutDialog extends MageDialog {
|
||||||
.addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addComponent(jLabel4)
|
.addComponent(jLabel4)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 71, Short.MAX_VALUE)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 68, Short.MAX_VALUE)
|
||||||
.addComponent(btnOk)
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||||
|
.addComponent(btnWhatsNew, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||||
.addContainerGap())
|
.addContainerGap())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -101,11 +132,16 @@ public class AboutDialog extends MageDialog {
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed
|
private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOkActionPerformed
|
||||||
this.removeDialog();
|
onCancel();
|
||||||
}//GEN-LAST:event_btnOkActionPerformed
|
}//GEN-LAST:event_btnOkActionPerformed
|
||||||
|
|
||||||
|
private void btnWhatsNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnWhatsNewActionPerformed
|
||||||
|
MageFrame.getInstance().getWhatsNewDialog().checkUpdatesAndShow(true);
|
||||||
|
}//GEN-LAST:event_btnWhatsNewActionPerformed
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JButton btnOk;
|
private javax.swing.JButton btnOk;
|
||||||
|
private javax.swing.JButton btnWhatsNew;
|
||||||
private javax.swing.JLabel jLabel1;
|
private javax.swing.JLabel jLabel1;
|
||||||
private javax.swing.JLabel jLabel2;
|
private javax.swing.JLabel jLabel2;
|
||||||
private javax.swing.JLabel jLabel3;
|
private javax.swing.JLabel jLabel3;
|
||||||
|
|
|
@ -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>
|
297
Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.java
Normal file
297
Mage.Client/src/main/java/mage/client/dialog/WhatsNewDialog.java
Normal file
|
@ -0,0 +1,297 @@
|
||||||
|
package mage.client.dialog;
|
||||||
|
|
||||||
|
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.net.MalformedURLException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JayDi85
|
||||||
|
*/
|
||||||
|
public class WhatsNewDialog extends MageDialog {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(WhatsNewDialog.class);
|
||||||
|
private static final MageVersion clientVersion = new MageVersion(WhatsNewDialog.class);
|
||||||
|
|
||||||
|
private static final String WHATS_NEW_PAGE = "https://jaydi85.github.io/xmage-web-news/news.html";
|
||||||
|
private static final int WHATS_NEW_LOAD_TIMEOUT_SECS = 20; // timeout for page loading
|
||||||
|
|
||||||
|
final JFXPanel fxPanel;
|
||||||
|
private WebEngine engine;
|
||||||
|
private boolean isPageReady = false;
|
||||||
|
|
||||||
|
private final SwingWorker<Void, Void> backgroundWorker = new SwingWorker<Void, Void>() {
|
||||||
|
@Override
|
||||||
|
public Void doInBackground() {
|
||||||
|
try {
|
||||||
|
logger.info("Checking news...");
|
||||||
|
int maxWait = WHATS_NEW_LOAD_TIMEOUT_SECS;
|
||||||
|
int currentWait = 0;
|
||||||
|
while (!isPageReady) {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
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(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (isPageReady) {
|
||||||
|
showDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public WhatsNewDialog() {
|
||||||
|
initComponents();
|
||||||
|
|
||||||
|
fxPanel = new JFXPanel();
|
||||||
|
panelData.add(fxPanel);
|
||||||
|
|
||||||
|
createWebView();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkUpdatesAndShow(boolean forceToShowPage) {
|
||||||
|
// lazy loading in background
|
||||||
|
// shows it on page ready or by force
|
||||||
|
|
||||||
|
isPageReady = false;
|
||||||
|
loadURL(WHATS_NEW_PAGE);
|
||||||
|
|
||||||
|
if (forceToShowPage) {
|
||||||
|
if (!backgroundWorker.isDone()) {
|
||||||
|
backgroundWorker.cancel(true);
|
||||||
|
}
|
||||||
|
showDialog();
|
||||||
|
} else {
|
||||||
|
backgroundWorker.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 view = new WebView();
|
||||||
|
engine = view.getEngine();
|
||||||
|
engine.setUserAgent(engine.getUserAgent() + " XMage/" + clientVersion.toString(false));
|
||||||
|
view.contextMenuEnabledProperty().setValue(false);
|
||||||
|
|
||||||
|
// on error
|
||||||
|
engine.getLoadWorker().exceptionProperty().addListener(new ChangeListener<Throwable>() {
|
||||||
|
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"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// on completed
|
||||||
|
engine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
|
||||||
|
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() {
|
||||||
|
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(view));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//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();
|
||||||
|
}// </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
|
||||||
|
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
|
||||||
|
}
|
Loading…
Reference in a new issue