add code to launch firemind worker from settings menu

master
projectfiremind 2014-09-03 19:15:41 +02:00
parent c01ecc37c3
commit 3ac35f4375
10 changed files with 925 additions and 9 deletions

View File

@ -9,15 +9,16 @@
<property name="lib" value="release/lib" />
<property name="groovy-version" value="2.3.4" />
<property name="out.dir" value="build/"/>
<path id="classpath">
<pathelement path="build/" />
<fileset dir="${lib}">
<include name="*.jar" />
<include name="**/*.jar" />
</fileset>
</path>
<taskdef name="bundleapp"
classname="com.oracle.appbundler.AppBundlerTask"
classpath="lib/appbundler-1.0.jar" />
<!-- deps - Download dependencies -->
<target name="deps" unless="skip.download">
@ -40,6 +41,10 @@
<get src="http://repo1.maven.org/maven2/org/pushingpixels/trident/1.3/trident-1.3.jar"
dest="${lib}/trident-1.3.jar"
skipexisting="true" />
<echo message="downloading java json library to ${lib}"/>
<get src="http://repo1.maven.org/maven2/org/json/json/20140107/json-20140107.jar"
dest="${lib}/json.jar"
skipexisting="true" />
</target>
<!-- init - Create temporary directory to build the program -->
@ -66,14 +71,18 @@
</fileset>
</copy>
</target>
<manifestclasspath property="lib.list" jarfile="release/Magarena.jar">
<classpath refid="classpath"/>
</manifestclasspath>
<!-- jar (default target) - Create .jar file -->
<target depends="build" name="jar">
<jar destfile="release/Magarena.jar" basedir="build" includes="**/*.*">
<manifest>
<attribute name="Main-Class" value="magic.MagicMain" />
<attribute name="SplashScreen-Image" value="magic/data/textures/logo.jpg" />
<attribute name="Class-Path" value="lib/groovy-all-${groovy-version}.jar lib/miglayout-core-4.2.jar lib/miglayout-swing-4.2.jar lib/commons-io-2.4.jar lib/trident-1.3.jar" />
<attribute name="Class-Path" value="lib/groovy-all-${groovy-version}.jar " />
<attribute name="Class-Path" value="lib/groovy-all-${groovy-version}.jar lib/json.jar lib/jedis-2.1.0.jar lib/mysql-connector-java-5.1.25-bin.jar lib/activejdbc-1.4.6.jar lib/slf4j-api-1.6.4.jar lib/slf4j-simple-1.6.4.jar lib/javalite-common-1.4.6.jar lib/miglayout-core-4.2.jar lib/miglayout-swing-4.2.jar lib/commons-io-2.4.jar lib/trident-1.3.jar" />
<attribute name="Class-Path" value="${lib.list}"/>
</manifest>
</jar>
</target>
@ -82,5 +91,12 @@
<target name="javadoc">
<javadoc sourcepath="src" destdir="javadoc" />
</target>
<target name="instrument" depends="build">
<java classname="org.javalite.instrumentation.Main">
<sysproperty key="outputDirectory" value="${out.dir}"/>
<classpath refid="classpath"/>
</java>
</target>
</project>

View File

@ -0,0 +1,188 @@
package magic;
import magic.ai.MagicAI;
import magic.ai.MagicAIImpl;
import magic.data.DeckUtils;
import magic.data.DuelConfig;
import magic.model.FiremindGameReport;
import magic.model.MagicDuel;
import magic.model.MagicGame;
import magic.model.MagicGameLog;
import magic.model.MagicRandom;
import magic.ui.GameController;
import java.io.IOException;
import java.io.File;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.net.UnknownHostException;
import java.util.Date;
import firemind.Duel;
import firemind.FiremindClient;
public class FiremindQueueWorker {
private static int games;
private static int str1 = 2;
private static int str2 = 2;
private static int life = 20;
private static int seed;
private static String deck1 = "";
private static String deck2 = "";
private static MagicAIImpl ai1 = MagicAIImpl.MCTS;
private static MagicAIImpl ai2 = MagicAIImpl.MCTS;
private static Duel currentDuel;
private static String env;
private static int gameCount = 0;
private static MagicDuel setupDuel() {
// Set the random seed
if (seed != 0) {
MagicRandom.setRNGState(seed);
seed = MagicRandom.nextRNGInt(Integer.MAX_VALUE) + 1;
}
// Set number of games.
final DuelConfig config = new DuelConfig();
config.setNrOfGames(games);
config.setStartLife(life);
// Set difficulty.
final MagicDuel testDuel = new MagicDuel(config);
testDuel.initialize();
testDuel.setDifficulty(0, str1);
testDuel.setDifficulty(1, str2);
// Set the AI
testDuel.setAIs(new MagicAI[] { ai1.getAI(), ai2.getAI() });
testDuel.getPlayer(0).setArtificial(true);
testDuel.getPlayer(1).setArtificial(true);
// Set the deck.
if (deck1.length() > 0) {
DeckUtils.loadDeck(deck1, testDuel.getPlayer(0));
}
if (deck2.length() > 0) {
DeckUtils.loadDeck(deck2, testDuel.getPlayer(1));
}
return testDuel;
}
public static void main(final String[] args) {
// setup the handler for any uncaught exception
try {
if (java.net.InetAddress.getLocalHost().getHostName()
.equals("mike-AndroidDev")) {
env = "development";
} else {
env = "production";
}
} catch (UnknownHostException e1) {
env = "production";
}
if (env == "production") {
FiremindClient.setFiremindHost("https://www.firemind.ch");
} else {
FiremindClient.setFiremindHost("http://192.168.50.10");
}
MagicMain.initializeEngine();
while (true) {
Duel duel = FiremindClient.popDeckJob();
if (duel != null) {
final FiremindGameReport reporter = new FiremindGameReport(
duel.id);
Thread.setDefaultUncaughtExceptionHandler(reporter);
System.out.println(duel.games_to_play + " Games to run");
File theDir = new File("duels/" + duel.id);
theDir.mkdir();
deck1 = saveDeckFile("duels/" + duel.id + "/" + "deck1",
duel.deck1_text);
deck2 = saveDeckFile("duels/" + duel.id + "/" + "deck2",
duel.deck2_text);
currentDuel = duel;
games = duel.games_to_play;
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
runDuel();
if (gameCount > 25) {
System.out
.println("Exceeded max number of games. Shutting down.");
System.exit(0);
}
} else {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("Woken");
}
}
}
}
private static String saveDeckFile(String name, String content) {
try {
File deckFile = new File(name + ".dec");
deckFile.getParentFile().mkdirs();
deckFile.createNewFile();
FileWriter fw = new FileWriter(deckFile.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
return deckFile.getPath();
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
private static void runDuel() {
if (env == "production") {
FiremindClient.setFiremindHost("https://www.firemind.ch");
} else {
FiremindClient.setFiremindHost("http://192.168.50.10");
}
int played = 0;
int wins = 0;
MagicGameLog.initialize();
final MagicDuel testDuel = setupDuel();
Date baseDate = new Date();
baseDate.setTime(0);
long started = System.currentTimeMillis();
while (testDuel.getGamesPlayed() < testDuel.getGamesTotal()) {
final MagicGame game = testDuel.nextGame(false);
game.setArtificial(true);
final GameController controller = new GameController(game);
// maximum duration of a game is 60 minutes
controller.setMaxTestGameDuration(3600000);
controller.runGame();
if (testDuel.getGamesPlayed() > played) {
gameCount++;
played = testDuel.getGamesPlayed();
long diff = System.currentTimeMillis() - started;
String[] vers = MagicMain.VERSION.split("\\.");
String log = MagicGameLog.getLogFileName();
FiremindClient.postGame(currentDuel.id, played, new Date(
baseDate.getTime() + diff),
testDuel.getGamesWon() > wins, Integer
.parseInt(vers[0]), Integer.parseInt(vers[1]),
log);
wins = testDuel.getGamesWon();
started = System.currentTimeMillis();
MagicGameLog.initialize();
}
}
System.out.println("Duel finished " + played + " of "
+ testDuel.getGamesTotal() + " run");
}
}

View File

@ -52,6 +52,7 @@ public class GeneralConfig {
private static final String ANIMATE_GAMEPLAY = "animateGameplay";
private static final String DECK_FILE_MAX_LINES = "deckFileMaxLines";
private static final String PROXY_SETTINGS = "proxySettings";
private static final String FIREMIND_ACCESS_TOKEN = "firemindAccessToken";
// The most common size of card retrieved from http://mtgimage.com.
public static final Dimension PREFERRED_CARD_SIZE = HIGH_QUALITY_IMAGE_SIZE;
@ -123,7 +124,8 @@ public class GeneralConfig {
private boolean animateGameplay = true;
private int deckFileMaxLines = DEFAULT_DECK_FILE_MAX_LINES;
private String proxySettings = DEFAULT_PROXY_SETTINGS;
private String firemindAccessToken;
private GeneralConfig() { }
public Proxy getProxy() {
@ -300,6 +302,14 @@ public class GeneralConfig {
public void setHighlight(final String highlight) {
this.highlight = highlight;
}
public String getFiremindAccessToken() {
return firemindAccessToken;
}
public void setFiremindAccessToken(final String firemindAccessToken) {
this.firemindAccessToken = firemindAccessToken;
}
public boolean getTextView() {
return textView;
@ -477,6 +487,7 @@ public class GeneralConfig {
animateGameplay = Boolean.parseBoolean(properties.getProperty(ANIMATE_GAMEPLAY, "" + true));
deckFileMaxLines = Integer.parseInt(properties.getProperty(DECK_FILE_MAX_LINES, ""+DEFAULT_DECK_FILE_MAX_LINES));
proxySettings = properties.getProperty(PROXY_SETTINGS, "");
firemindAccessToken = properties.getProperty(FIREMIND_ACCESS_TOKEN, "");
}
public void load() {
@ -517,6 +528,7 @@ public class GeneralConfig {
properties.setProperty(CARD_IMAGES_PATH, cardImagesPath);
properties.setProperty(ANIMATE_GAMEPLAY, String.valueOf(animateGameplay));
properties.setProperty(PROXY_SETTINGS, proxySettings);
properties.setProperty(FIREMIND_ACCESS_TOKEN, firemindAccessToken);
}
public void save() {

View File

@ -0,0 +1,10 @@
package firemind;
public class Duel {
public Integer games_to_play;
public Integer id;
public String deck1_text;
public String deck2_text;
}

View File

@ -0,0 +1,136 @@
package firemind;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Date;
import magic.data.GeneralConfig;
import org.json.JSONException;
import org.json.JSONObject;
public class FiremindClient {
protected static final GeneralConfig CONFIG = GeneralConfig.getInstance();
static String firemindHost ;
public static Duel popDeckJob() {
CONFIG.load();
JSONObject obj;
try {
obj = readJsonFromUrl(firemindHost + "/api/v1/duel_jobs");
Duel d = new Duel();
d.id = obj.getInt("id");
d.games_to_play = obj.getInt("games_to_play");
d.deck1_text = obj.getString("deck1_text");
d.deck2_text = obj.getString("deck2_text");
return d;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (FileNotFoundException e) {
// No need to handle the 404 error
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
public static boolean postGame(Integer duel_id, Integer game_number,
Date play_time, boolean win_deck1, Integer magarena_version_major,
Integer magarena_version_minor, String logFile) {
CONFIG.load();
String url = firemindHost + "/api/v1/duel_jobs/" + duel_id + "/games";
System.out.println("Posting game result "+game_number);
URL object;
try {
object = new URL(url);
HttpURLConnection con = (HttpURLConnection) object.openConnection();
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Authorization", "Token token="
+ CONFIG.getFiremindAccessToken());
con.setRequestMethod("POST");
JSONObject parent = new JSONObject();
parent.put("game_number", game_number);
parent.put("play_time", play_time);
parent.put("win_deck1", win_deck1);
parent.put("magarena_version_major", magarena_version_major);
parent.put("magarena_version_minor", magarena_version_minor);
parent.put("log", new String(Files.readAllBytes(Paths.get(logFile))));
con.setDoOutput(true);
con.setDoInput(true);
OutputStreamWriter wr = new OutputStreamWriter(
con.getOutputStream());
wr.write(parent.toString());
wr.flush();
int HttpResult = con.getResponseCode();
if (HttpResult == HttpURLConnection.HTTP_OK) {
return true;
} else {
System.err.println(con.getResponseMessage());
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
public static boolean postFailure(Integer duel_id, String text) {
System.err.println("POST ERROR STUB: "+text);
return true;
}
public static JSONObject readJsonFromUrl(String url) throws IOException,
JSONException {
HttpURLConnection con = (HttpURLConnection) (new URL(url))
.openConnection();
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Authorization", "Token token=" + CONFIG.getFiremindAccessToken());
con.setRequestMethod("DELETE");
con.setDoOutput(true);
con.setDoInput(true);
BufferedReader rd = new BufferedReader(new InputStreamReader(
con.getInputStream(), Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject json = new JSONObject(jsonText);
return json;
}
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
public static void setFiremindHost(String host) {
firemindHost = host;
}
}

View File

@ -0,0 +1,182 @@
package magic.model;
import magic.FiremindQueueWorker;
import magic.MagicMain;
import magic.data.FileIO;
import magic.model.action.MagicAction;
import magic.model.stack.MagicItemOnStack;
import magic.utility.MagicFileSystem;
import magic.utility.MagicFileSystem.DataPath;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.Date;
import firemind.Duel;
import firemind.FiremindClient;
public class FiremindGameReport implements Thread.UncaughtExceptionHandler {
Integer currentDuelId;
public FiremindGameReport(Integer duel_id) {
super();
this.currentDuelId = duel_id;
}
public void uncaughtException(final Thread th, final Throwable ex) {
FiremindGameReport.buildReport(MagicGame.getInstance(), th, ex);
ex.printStackTrace();
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
FiremindClient.postFailure(currentDuelId, sw.toString());
}
private static void buildCard(final MagicGame game, final String place,
final MagicCard card, final StringBuilder report) {
report.append(" - ").append(place).append(" : ")
.append(card.getName()).append("\n");
}
private static void buildPermanent(final MagicGame game,
final MagicPermanent permanent, final StringBuilder report) {
report.append(" - Permanent : ").append(permanent.getName());
if (permanent.isCreature()) {
final MagicPowerToughness pt = permanent.getPowerToughness();
report.append(" Power : ").append(pt.power());
report.append(" Toughness : ").append(pt.toughness());
report.append(" Damage : ").append(permanent.getDamage());
}
if (permanent.hasState(MagicPermanentState.Tapped)) {
report.append(" Tapped");
}
if (permanent.hasState(MagicPermanentState.Summoned)) {
report.append(" Summoned");
}
report.append("\n");
}
private static void buildPlayer(final MagicGame game,
final MagicPlayer player, final StringBuilder report) {
report.append(player.getIndex()).append("] ");
report.append("Player : ").append(player.getName());
report.append(" Life : ").append(player.getLife());
report.append(" Delayed : ").append(player.getBuilderCost());
report.append("\n");
for (final MagicCard card : player.getHand()) {
buildCard(game, "Hand", card, report);
}
for (final MagicCard card : player.getGraveyard()) {
buildCard(game, "Graveyard", card, report);
}
for (final MagicPermanent permanent : player.getPermanents()) {
buildPermanent(game, permanent, report);
}
}
private static void buildStack(final MagicGame game,
final StringBuilder report) {
report.append("Stack : ").append(game.getStack().size()).append('\n');
for (final MagicItemOnStack itemOnStack : game.getStack()) {
report.append(" - Name : ");
report.append(itemOnStack.getName());
report.append(" Player : ");
report.append(itemOnStack.getController().getName());
report.append('\n');
}
}
private static void buildScore(final MagicGame game,
final StringBuilder report) {
int totalScore = 0;
int count = 0;
for (final MagicAction action : game.getActions()) {
final int score = action.getScore(game.getScorePlayer());
totalScore += score;
final String text = action.toString();
if (!text.isEmpty()) {
report.append(++count).append(". ").append(text).append(" = ")
.append(score).append("\n");
}
}
report.append("Score = ").append(totalScore).append("\n");
}
private static String buildReport(final MagicGame game) {
final StringBuilder report = new StringBuilder();
report.append("Turn : ").append(game.getTurn());
report.append(" Phase : ").append(game.getPhase().getType());
report.append(" Step : ").append(game.getStep());
report.append(" Player : ").append(game.getTurnPlayer());
report.append(" Score : ").append(game.getScore());
report.append("\n");
for (final MagicPlayer player : game.getPlayers()) {
buildPlayer(game, player, report);
}
buildStack(game, report);
buildScore(game, report);
return report.toString();
}
public static void buildReport(final MagicGame game, final Thread th,
final Throwable ex) {
final StringBuilder sb = new StringBuilder();
sb.append("CRASH REPORT FOR MAGARENA THREAD " + th);
sb.append('\n');
sb.append("CREATED ON "
+ (new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"))
.format(new Date()));
sb.append('\n');
sb.append("MAGARENA VERSION " + MagicMain.VERSION);
sb.append(", JRE " + System.getProperty("java.version"));
sb.append(", OS " + System.getProperty("os.name"));
sb.append("_" + System.getProperty("os.version"));
sb.append(" " + System.getProperty("os.arch"));
sb.append("\n\n");
try {
// buildReport might throw an exception
if (game != null) {
sb.append(buildReport(game));
sb.append('\n');
}
} catch (final Throwable ex2) {
sb.append("Exception from MagicGameReport.buildReport: "
+ ex2.getMessage());
sb.append('\n');
final StringWriter result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
ex2.printStackTrace(printWriter);
sb.append(result.toString());
sb.append('\n');
}
sb.append("Exception from controller.runGame: " + ex.getMessage());
sb.append('\n');
final StringWriter result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
ex.printStackTrace(printWriter);
sb.append(result.toString());
sb.append('\n');
// print a copy to stderr
System.err.println(sb.toString());
// save a copy to a crash log file
final Path clog = MagicFileSystem.getDataPath(DataPath.LOGS).resolve(
"crash.log");
try {
FileIO.toFile(clog.toFile(), sb.toString(), true);
} catch (final IOException ex3) {
System.err.println("Unable to save crash log");
}
}
}

View File

@ -10,14 +10,17 @@ import magic.utility.MagicFileSystem.DataPath;
public class MagicGameLog {
private MagicGameLog() {}
private static final String gameLog = (System.getProperty("game.log") != null) ?
System.getProperty("game.log") :
MagicFileSystem.getDataPath(DataPath.LOGS).resolve("game.log").toString();
private static PrintWriter writer;
public static String getLogFileName(){
return gameLog;
}
public static void initialize() {
try {
writer = new PrintWriter(gameLog);

View File

@ -0,0 +1,149 @@
package magic.ui.dialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import magic.ui.*;
import magic.ui.theme.Theme;
import magic.ui.theme.ThemeFactory;
import magic.ui.widget.FontsAndBorders;
import magic.ui.widget.firemind.FiremindWorkerPanel;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
public class FiremindWorkerDialog extends JDialog implements ActionListener, PropertyChangeListener {
// not static so that it will reflect theme changes without restart.
private final Theme THEME = ThemeFactory.getInstance().getCurrentTheme();
private final JButton cancelButton = new JButton();
private final JButton backgroundButton = new JButton();
private final FiremindWorkerPanel firemindWorkerPanel = new FiremindWorkerPanel();
public FiremindWorkerDialog(final MagicFrame frame) {
super(frame, true);
firemindWorkerPanel.addPropertyChangeListener("isRunning", this);
setLookAndFeel();
refreshLayout();
setEscapeKeyAsCancelAction();
this.setLocationRelativeTo(frame);
this.setVisible(true);
}
private JPanel getFieldsPanel() {
final JPanel panel = new JPanel(new MigLayout("flowy, insets 8, gapy 10"));
panel.add(firemindWorkerPanel, "w 100%");
return panel;
}
private void setEscapeKeyAsCancelAction() {
final KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
getRootPane().registerKeyboardAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (!backgroundButton.isEnabled()) {
doCancelAndClose();
}
}
}, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
}
private void refreshLayout() {
setLayout(new MigLayout("flowy, gapy 0, insets 0"));
add(getDialogCaptionLabel(), "w 100%, h 26!");
add(getFieldsPanel(), "w 100%");
add(getButtonPanel(), "w 100%, aligny bottom, pushy");
}
private JLabel getDialogCaptionLabel() {
final JLabel lbl = new JLabel(getTitle());
lbl.setOpaque(true);
lbl.setBackground(THEME.getColor(Theme.COLOR_TITLE_BACKGROUND));
lbl.setForeground(THEME.getColor(Theme.COLOR_TITLE_FOREGROUND));
lbl.setFont(FontsAndBorders.FONT1.deriveFont(14f));
lbl.setHorizontalAlignment(SwingConstants.CENTER);
return lbl;
}
private void setLookAndFeel() {
setTitle("Download Card Images");
setResizable(false);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setSize(360, 460);
setUndecorated(true);
((JComponent)getContentPane()).setBorder(BorderFactory.createMatteBorder(0, 8, 8, 8, THEME.getColor(Theme.COLOR_TITLE_BACKGROUND)));
//
backgroundButton.setEnabled(false);
}
private void updateComponentState() {
System.out.println("Update component state"+ (firemindWorkerPanel.isRunning() ? "true" : "false"));
boolean isBackgroundButtonEnabled = false;
final boolean isRunning = firemindWorkerPanel.isRunning();
isBackgroundButtonEnabled = isBackgroundButtonEnabled || isRunning;
backgroundButton.setEnabled(isBackgroundButtonEnabled);
}
private JPanel getButtonPanel() {
// cancel button
cancelButton.setText("Cancel");
cancelButton.setFocusable(false);
cancelButton.addActionListener(this);
// background button
backgroundButton.setText("Run in background...");
backgroundButton.setFocusable(false);
backgroundButton.addActionListener(this);
// layout
final JPanel panel = new JPanel(new MigLayout());
panel.add(backgroundButton, "w 100%, alignx left");
panel.add(cancelButton, "w 100!, alignx right, pushx");
return panel;
}
@Override
public void actionPerformed(final ActionEvent event) {
final Object source=event.getSource();
if (source==cancelButton) {
doCancelAndClose();
} else if (source == backgroundButton) {
setVisible(false);
}
}
private void doCancelAndClose() {
firemindWorkerPanel.doCancel();
dispose();
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("isRunning")) {
updateComponentState();
// final int progressValue = (int)evt.getNewValue();
// progressBar.setIndeterminate(progressValue == 0 && importWorker.getProgressNote() != "");
// progressBar.setValue(progressValue);
// } else if (evt.getPropertyName().equalsIgnoreCase("state")) {
// progressBar.setIndeterminate(!evt.getNewValue().toString().equalsIgnoreCase("done"));
// } else if (evt.getPropertyName().equalsIgnoreCase("progressNote")) {
// taskOutput.append(evt.getNewValue().toString());
}
}
}

View File

@ -1,9 +1,12 @@
package magic.ui.screen;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JPanel;
import magic.ui.dialog.DownloadImagesDialog;
import magic.ui.dialog.FiremindWorkerDialog;
import magic.ui.dialog.ImportDialog;
import magic.ui.screen.widget.MenuPanel;
import net.miginfocom.swing.MigLayout;
@ -12,6 +15,7 @@ import net.miginfocom.swing.MigLayout;
public class SettingsMenuScreen extends AbstractScreen {
private static DownloadImagesDialog downloadDialog;
private static FiremindWorkerDialog firemindWorkerDialog;
public SettingsMenuScreen() {
setContent(getScreenContent());
@ -49,6 +53,18 @@ public class SettingsMenuScreen extends AbstractScreen {
}
}
});
menu.addMenuItem("Run Firemind Worker", new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
if (firemindWorkerDialog == null || !firemindWorkerDialog.isDisplayable()) {
firemindWorkerDialog = new FiremindWorkerDialog(getFrame());
} else {
firemindWorkerDialog.setVisible(true);
}
}
});
menu.addMenuItem("Toggle full-screen", new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {

View File

@ -0,0 +1,204 @@
package magic.ui.widget.firemind;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.net.Proxy;
import java.nio.file.Path;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import magic.FiremindQueueWorker;
import magic.data.GeneralConfig;
import magic.data.IconImages;
import magic.utility.MagicFileSystem;
import magic.utility.MagicFileSystem.DataPath;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
public class FiremindWorkerPanel extends JPanel {
protected final GeneralConfig CONFIG = GeneralConfig.getInstance();
private final JTextField accessKeyTextField = new JTextField();
private final MigLayout migLayout = new MigLayout();
protected final JLabel captionLabel = getCaptionLabel(getProgressCaption());
private final JButton runButton = new JButton();
private final JButton cancelButton = new JButton("Cancel");
@SuppressWarnings("unused")
private boolean isCancelled = false;
private SwingWorker<String, Void> firemindWorker;
private boolean isRunning = false;
protected SwingWorker<String, Void> getFiremindWorker(final Proxy proxy) {
return new FiremindWorkerRunner(); //TODO (downloadList, CONFIG.getProxy());
}
protected String getProgressCaption(){
if(isRunning){
return "Running";
}else{
return "Not running";
}
}
protected String getLogFilename() {
return "fireindWorker.log";
}
protected String getStartButtonCaption() {
return "Start Firemind Worker";
}
public FiremindWorkerPanel() {
CONFIG.load();
setLookAndFeel();
refreshLayout();
setActions();
// buildDownloadImagesList();
}
public boolean isRunning() {
return this.isRunning;
}
protected void saveDownloadLog(final List<String> downloadLog) {
final Path logPath = MagicFileSystem.getDataPath(DataPath.LOGS).resolve(getLogFilename());
System.out.println("saving log : " + logPath);
try (final PrintWriter writer = new PrintWriter(logPath.toFile())) {
for (String cardName : downloadLog) {
writer.println(cardName);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
private void setActions() {
runButton.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
CONFIG.setFiremindAccessToken(accessKeyTextField.getText().trim());
CONFIG.save();
setRunningState();
notifyStatusChanged(true);
firemindWorker = getFiremindWorker(CONFIG.getProxy());
firemindWorker.execute();
}
});
cancelButton.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
doCancelFiremindWorker();
}
});
}
public void doCancel() {
isCancelled = true;
doCancelFiremindWorker();
}
private void doCancelFiremindWorker() {
if (firemindWorker != null && !firemindWorker.isCancelled() & !firemindWorker.isDone()) {
firemindWorker.cancel(true);
setButtonState(false);
}
}
// protected final void buildDownloadImagesList() {
// if (!isCancelled) {
// captionLabel.setIcon(IconImages.BUSY16);
// captionLabel.setText(getProgressCaption());
// imagesScanner = new ImagesScanner();
// imagesScanner.execute();
// downloadButton.setEnabled(false);
// notifyStatusChanged(DownloaderState.SCANNING);
// }
// }
protected void setButtonState(final boolean isRunning) {
runButton.setVisible(!isRunning);
cancelButton.setVisible(isRunning);
refreshLayout();
}
private void setRunningState() {
setButtonState(true);
captionLabel.setIcon(IconImages.BUSY16);
}
private void refreshLayout() {
removeAll();
migLayout.setLayoutConstraints("flowy, insets 2, gapy 0");
accessKeyTextField.setText(CONFIG.getFiremindAccessToken());
add(accessKeyTextField, "w 100%");
add(runButton.isVisible() ? runButton : cancelButton, "w 100%");
}
private void setLookAndFeel() {
// Layout manager.
setLayout(migLayout);
// download button
runButton.setEnabled(true);
runButton.setText(getStartButtonCaption());
}
private JLabel getCaptionLabel(final String text) {
final ImageIcon ii = IconImages.BUSY16;
final JLabel lbl = new JLabel(ii);
lbl.setText(text);
lbl.setHorizontalAlignment(SwingConstants.LEFT);
lbl.setHorizontalTextPosition(SwingConstants.LEADING);
lbl.setOpaque(false);
lbl.setFont(lbl.getFont().deriveFont(Font.BOLD));
return lbl;
}
protected void notifyStatusChanged(boolean newValue) {
assert SwingUtilities.isEventDispatchThread();
final boolean oldState = this.isRunning;
this.isRunning = newValue;
firePropertyChange("isRunning", oldState, newValue);
}
private class FiremindWorkerRunner extends SwingWorker<String, Void> {
@Override
protected String doInBackground() throws Exception {
String[] arguments = new String[]{""};
FiremindQueueWorker.main(arguments);
return "finished";
}
@Override
protected void done() {
// try {
// files = get();
// } catch (InterruptedException | ExecutionException ex) {
// throw new RuntimeException(ex);
// } catch (CancellationException ex) {
//// System.out.println("ImagesScanner cancelled by user!");
// }
// if (!isCancelled) {
// downloadButton.setEnabled(files.size() > 0);
// captionLabel.setIcon(null);
// captionLabel.setText(getProgressCaption() + files.size());
// }
// notifyStatusChanged(DownloaderState.STOPPED);
}
}
}