mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Refactor gui downloaders to be reusable by mobile app
This commit is contained in:
10
.gitattributes
vendored
10
.gitattributes
vendored
@@ -705,10 +705,6 @@ forge-gui-desktop/src/main/java/forge/deckchooser/DecksComboBoxEvent.java -text
|
|||||||
forge-gui-desktop/src/main/java/forge/deckchooser/FDeckChooser.java -text
|
forge-gui-desktop/src/main/java/forge/deckchooser/FDeckChooser.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/deckchooser/FDeckViewer.java -text
|
forge-gui-desktop/src/main/java/forge/deckchooser/FDeckViewer.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/deckchooser/IDecksComboBoxListener.java -text
|
forge-gui-desktop/src/main/java/forge/deckchooser/IDecksComboBoxListener.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/download/GuiDownloadPicturesLQ.java -text
|
|
||||||
forge-gui-desktop/src/main/java/forge/download/GuiDownloadPrices.java -text
|
|
||||||
forge-gui-desktop/src/main/java/forge/download/GuiDownloadQuestImages.java -text
|
|
||||||
forge-gui-desktop/src/main/java/forge/download/GuiDownloadSetPicturesLQ.java -text
|
|
||||||
forge-gui-desktop/src/main/java/forge/download/GuiDownloader.java -text
|
forge-gui-desktop/src/main/java/forge/download/GuiDownloader.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/download/package-info.java -text
|
forge-gui-desktop/src/main/java/forge/download/package-info.java -text
|
||||||
forge-gui-desktop/src/main/java/forge/error/BugReportDialog.java -text
|
forge-gui-desktop/src/main/java/forge/error/BugReportDialog.java -text
|
||||||
@@ -16331,6 +16327,11 @@ forge-gui/src/main/java/forge/deck/DeckgenUtil.java -text
|
|||||||
forge-gui/src/main/java/forge/deck/io/DeckHtmlSerializer.java -text
|
forge-gui/src/main/java/forge/deck/io/DeckHtmlSerializer.java -text
|
||||||
forge-gui/src/main/java/forge/deck/io/DeckPreferences.java -text
|
forge-gui/src/main/java/forge/deck/io/DeckPreferences.java -text
|
||||||
forge-gui/src/main/java/forge/deck/io/OldDeckParser.java -text
|
forge-gui/src/main/java/forge/deck/io/OldDeckParser.java -text
|
||||||
|
forge-gui/src/main/java/forge/download/GuiDownloadPicturesLQ.java -text
|
||||||
|
forge-gui/src/main/java/forge/download/GuiDownloadPrices.java -text
|
||||||
|
forge-gui/src/main/java/forge/download/GuiDownloadQuestImages.java -text
|
||||||
|
forge-gui/src/main/java/forge/download/GuiDownloadService.java -text
|
||||||
|
forge-gui/src/main/java/forge/download/GuiDownloadSetPicturesLQ.java -text
|
||||||
forge-gui/src/main/java/forge/error/BugReporter.java -text
|
forge-gui/src/main/java/forge/error/BugReporter.java -text
|
||||||
forge-gui/src/main/java/forge/error/ExceptionHandler.java svneol=native#text/plain
|
forge-gui/src/main/java/forge/error/ExceptionHandler.java svneol=native#text/plain
|
||||||
forge-gui/src/main/java/forge/error/package-info.java svneol=native#text/plain
|
forge-gui/src/main/java/forge/error/package-info.java svneol=native#text/plain
|
||||||
@@ -16343,6 +16344,7 @@ forge-gui/src/main/java/forge/gauntlet/GauntletIO.java -text
|
|||||||
forge-gui/src/main/java/forge/interfaces/IButton.java -text
|
forge-gui/src/main/java/forge/interfaces/IButton.java -text
|
||||||
forge-gui/src/main/java/forge/interfaces/IGuiBase.java -text
|
forge-gui/src/main/java/forge/interfaces/IGuiBase.java -text
|
||||||
forge-gui/src/main/java/forge/interfaces/IProgressBar.java -text
|
forge-gui/src/main/java/forge/interfaces/IProgressBar.java -text
|
||||||
|
forge-gui/src/main/java/forge/interfaces/ITextField.java -text
|
||||||
forge-gui/src/main/java/forge/itemmanager/ColumnDef.java -text
|
forge-gui/src/main/java/forge/itemmanager/ColumnDef.java -text
|
||||||
forge-gui/src/main/java/forge/itemmanager/GroupDef.java -text
|
forge-gui/src/main/java/forge/itemmanager/GroupDef.java -text
|
||||||
forge-gui/src/main/java/forge/itemmanager/IItemManager.java -text
|
forge-gui/src/main/java/forge/itemmanager/IItemManager.java -text
|
||||||
|
|||||||
@@ -448,4 +448,9 @@ public class GuiDesktop implements IGuiBase {
|
|||||||
public void startAltSoundSystem(String filename, boolean isSynchronized) {
|
public void startAltSoundSystem(String filename, boolean isSynchronized) {
|
||||||
new AltSoundSystem(filename, isSynchronized).start();
|
new AltSoundSystem(filename, isSynchronized).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearImageCache() {
|
||||||
|
ImageCache.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,89 +17,51 @@
|
|||||||
*/
|
*/
|
||||||
package forge.download;
|
package forge.download;
|
||||||
|
|
||||||
import com.esotericsoftware.minlog.Log;
|
|
||||||
|
|
||||||
import forge.UiCommand;
|
import forge.UiCommand;
|
||||||
import forge.ImageCache;
|
|
||||||
import forge.assets.FSkinProp;
|
import forge.assets.FSkinProp;
|
||||||
import forge.error.BugReporter;
|
|
||||||
import forge.gui.SOverlayUtils;
|
import forge.gui.SOverlayUtils;
|
||||||
import forge.toolbox.*;
|
import forge.toolbox.*;
|
||||||
import forge.util.FileUtil;
|
|
||||||
import forge.util.MyRandom;
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.channels.Channels;
|
|
||||||
import java.nio.channels.ReadableByteChannel;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public abstract class GuiDownloader extends DefaultBoundedRangeModel implements Runnable {
|
public class GuiDownloader extends DefaultBoundedRangeModel {
|
||||||
public static final Proxy.Type[] TYPES = Proxy.Type.values();
|
public static final Proxy.Type[] TYPES = Proxy.Type.values();
|
||||||
|
|
||||||
// Actions and commands
|
|
||||||
private final ActionListener actStartDownload = new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent e) {
|
|
||||||
// invalidate image cache so newly downloaded images will be loaded
|
|
||||||
ImageCache.clear();
|
|
||||||
new Thread(GuiDownloader.this).start();
|
|
||||||
btnStart.setEnabled(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final ActionListener actOK = new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(final ActionEvent e) {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final UiCommand cmdClose = new UiCommand() { @Override
|
|
||||||
public void run() { close(); } };
|
|
||||||
|
|
||||||
// Swing components
|
// Swing components
|
||||||
private final FPanel pnlDialog = new FPanel(new MigLayout("insets 0, gap 0, wrap, ax center, ay center"));
|
private final FPanel pnlDialog = new FPanel(new MigLayout("insets 0, gap 0, wrap, ax center, ay center"));
|
||||||
private final FProgressBar barProgress = new FProgressBar();
|
private final FProgressBar barProgress = new FProgressBar();
|
||||||
private final FButton btnStart = new FButton("Start");
|
private final FButton btnStart = new FButton("Start");
|
||||||
private final JTextField txfAddr = new JTextField("Proxy Address");
|
private final FTextField txtAddress = new FTextField.Builder().ghostText("Proxy Address").build();
|
||||||
private final JTextField txfPort = new JTextField("Proxy Port");
|
private final FTextField txtPort = new FTextField.Builder().ghostText("Proxy Port").build();
|
||||||
|
|
||||||
|
private final UiCommand cmdClose = new UiCommand() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
service.setCancel(true);
|
||||||
|
|
||||||
|
// Kill overlay
|
||||||
|
SOverlayUtils.hideOverlay();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final FLabel btnClose = new FLabel.Builder().text("X")
|
private final FLabel btnClose = new FLabel.Builder().text("X")
|
||||||
.hoverable(true).fontAlign(SwingConstants.CENTER).cmdClick(cmdClose).build();
|
.hoverable(true).fontAlign(SwingConstants.CENTER).cmdClick(cmdClose).build();
|
||||||
|
|
||||||
private final JRadioButton radProxyNone = new FRadioButton("No Proxy");
|
private final FRadioButton radProxyNone = new FRadioButton("No Proxy");
|
||||||
private final JRadioButton radProxySocks = new FRadioButton("SOCKS Proxy");
|
private final FRadioButton radProxySocks = new FRadioButton("SOCKS Proxy");
|
||||||
private final JRadioButton radProxyHTTP = new FRadioButton("HTTP Proxy");
|
private final FRadioButton radProxyHTTP = new FRadioButton("HTTP Proxy");
|
||||||
|
|
||||||
// Proxy info
|
private final GuiDownloadService service;
|
||||||
private int type;
|
|
||||||
|
|
||||||
// Progress variables
|
public GuiDownloader(GuiDownloadService service0) {
|
||||||
private Map<String, String> cards; // local path -> url
|
service = service0;
|
||||||
private boolean cancel;
|
|
||||||
private final long[] times = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
||||||
private int tptr = 0;
|
|
||||||
private int skipped = 0;
|
|
||||||
private long lTime = System.currentTimeMillis();
|
|
||||||
|
|
||||||
protected GuiDownloader() {
|
|
||||||
String radConstraints = "w 100%!, h 30px!, gap 2% 0 0 10px";
|
String radConstraints = "w 100%!, h 30px!, gap 2% 0 0 10px";
|
||||||
JXButtonPanel grpPanel = new JXButtonPanel();
|
JXButtonPanel grpPanel = new JXButtonPanel();
|
||||||
grpPanel.add(radProxyNone, radConstraints);
|
grpPanel.add(radProxyNone, radConstraints);
|
||||||
@@ -121,8 +83,8 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
|
|||||||
|
|
||||||
// Layout
|
// Layout
|
||||||
pnlDialog.add(grpPanel, "w 50%!");
|
pnlDialog.add(grpPanel, "w 50%!");
|
||||||
pnlDialog.add(txfAddr, "w 95%!, h 30px!, gap 2% 0 0 10px");
|
pnlDialog.add(txtAddress, "w 95%!, h 30px!, gap 2% 0 0 10px");
|
||||||
pnlDialog.add(txfPort, "w 95%!, h 30px!, gap 2% 0 0 10px");
|
pnlDialog.add(txtPort, "w 95%!, h 30px!, gap 2% 0 0 10px");
|
||||||
pnlDialog.add(barProgress, "w 95%!, h 40px!, gap 2% 0 20px 0");
|
pnlDialog.add(barProgress, "w 95%!, h 40px!, gap 2% 0 20px 0");
|
||||||
pnlDialog.add(btnStart, "w 200px!, h 40px!, gap 0 0 20px 0, ax center");
|
pnlDialog.add(btnStart, "w 200px!, h 40px!, gap 0 0 20px 0, ax center");
|
||||||
pnlDialog.add(btnClose, "w 20px!, h 20px!, pos 370px 10px");
|
pnlDialog.add(btnClose, "w 20px!, h 20px!, pos 370px 10px");
|
||||||
@@ -133,218 +95,15 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
|
|||||||
pnl.add(pnlDialog, "w 400px!, h 350px!, ax center, ay center");
|
pnl.add(pnlDialog, "w 400px!, h 350px!, ax center, ay center");
|
||||||
SOverlayUtils.showOverlay();
|
SOverlayUtils.showOverlay();
|
||||||
|
|
||||||
// Free up the EDT by assembling card list in the background
|
service.initialize(txtAddress, txtPort, barProgress, btnStart, cmdClose, new Runnable() {
|
||||||
SwingWorker<Void, Void> thrGetImages = new SwingWorker<Void, Void>() {
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground() throws Exception {
|
|
||||||
try {
|
|
||||||
GuiDownloader.this.cards = GuiDownloader.this.getNeededImages();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void done() {
|
|
||||||
GuiDownloader.this.readyToStart();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
thrGetImages.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readyToStart() {
|
|
||||||
if (this.cards.isEmpty()) {
|
|
||||||
barProgress.setString("All items have been downloaded.");
|
|
||||||
btnStart.setText("OK");
|
|
||||||
btnStart.addActionListener(actOK);
|
|
||||||
} else {
|
|
||||||
barProgress.setMaximum(this.cards.size());
|
|
||||||
barProgress.setString(this.cards.size() == 1 ? "1 item found." : this.cards.size() + " items found.");
|
|
||||||
//for(Entry<String, String> kv : cards.entrySet()) System.out.printf("Will get %s from %s%n", kv.getKey(), kv.getValue());
|
|
||||||
btnStart.addActionListener(actStartDownload);
|
|
||||||
}
|
|
||||||
btnStart.setVisible(true);
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
btnStart.requestFocusInWindow();
|
fireStateChanged();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCancel(final boolean cancel) {
|
private class ProxyHandler implements ChangeListener {
|
||||||
this.cancel = cancel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void close() {
|
|
||||||
setCancel(true);
|
|
||||||
|
|
||||||
// Kill overlay
|
|
||||||
SOverlayUtils.hideOverlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final int getAverageTimePerObject() {
|
|
||||||
int numNonzero = 10;
|
|
||||||
|
|
||||||
if (this.tptr > 9) {
|
|
||||||
this.tptr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.times[this.tptr] = System.currentTimeMillis() - this.lTime;
|
|
||||||
this.lTime = System.currentTimeMillis();
|
|
||||||
|
|
||||||
int tTime = 0;
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
tTime += this.times[i];
|
|
||||||
if (this.times[i] == 0) {
|
|
||||||
numNonzero--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tptr++;
|
|
||||||
return tTime / Math.max(1, numNonzero);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void update(final int card, final File dest) {
|
|
||||||
EventQueue.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
GuiDownloader.this.fireStateChanged();
|
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
final int a = GuiDownloader.this.getAverageTimePerObject();
|
|
||||||
|
|
||||||
if (card != GuiDownloader.this.cards.size()) {
|
|
||||||
sb.append(card + "/" + GuiDownloader.this.cards.size() + " - ");
|
|
||||||
|
|
||||||
long t2Go = (GuiDownloader.this.cards.size() - card) * a;
|
|
||||||
|
|
||||||
if (t2Go > 3600000) {
|
|
||||||
sb.append(String.format("%02d:", t2Go / 3600000));
|
|
||||||
t2Go = t2Go % 3600000;
|
|
||||||
}
|
|
||||||
if (t2Go > 60000) {
|
|
||||||
sb.append(String.format("%02d:", t2Go / 60000));
|
|
||||||
t2Go = t2Go % 60000;
|
|
||||||
} else {
|
|
||||||
sb.append("00:");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append(String.format("%02d remaining.", t2Go / 1000));
|
|
||||||
} else {
|
|
||||||
sb.append(String.format("%d of %d items finished! Skipped " + skipped + " items. Please close!",
|
|
||||||
card, GuiDownloader.this.cards.size()));
|
|
||||||
btnStart.setText("OK");
|
|
||||||
btnStart.addActionListener(actOK);
|
|
||||||
btnStart.setEnabled(true);
|
|
||||||
btnStart.requestFocusInWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
GuiDownloader.this.barProgress.setString(sb.toString());
|
|
||||||
System.out.println(card + "/" + GuiDownloader.this.cards.size() + " - " + dest);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void run() {
|
|
||||||
final Random r = MyRandom.getRandom();
|
|
||||||
|
|
||||||
Proxy p = null;
|
|
||||||
if (this.type == 0) {
|
|
||||||
p = Proxy.NO_PROXY;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
p = new Proxy(GuiDownloader.TYPES[this.type], new InetSocketAddress(this.txfAddr.getText(),
|
|
||||||
Integer.parseInt(this.txfPort.getText())));
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
BugReporter.reportException(ex,
|
|
||||||
"Proxy connection could not be established!\nProxy address: %s\nProxy port: %s",
|
|
||||||
this.txfAddr.getText(), this.txfPort.getText());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int iCard = 0;
|
|
||||||
for(Entry<String, String> kv : cards.entrySet()) {
|
|
||||||
if( cancel )
|
|
||||||
break;
|
|
||||||
|
|
||||||
String url = kv.getValue();
|
|
||||||
final File fileDest = new File(kv.getKey());
|
|
||||||
final File base = fileDest.getParentFile();
|
|
||||||
|
|
||||||
ReadableByteChannel rbc = null;
|
|
||||||
FileOutputStream fos = null;
|
|
||||||
try {
|
|
||||||
// test for folder existence
|
|
||||||
if (!base.exists() && !base.mkdir()) { // create folder if not found
|
|
||||||
System.out.println("Can't create folder" + base.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
URL imageUrl = new URL(url);
|
|
||||||
HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection(p);
|
|
||||||
// don't allow redirections here -- they indicate 'file not found' on the server
|
|
||||||
conn.setInstanceFollowRedirects(false);
|
|
||||||
conn.connect();
|
|
||||||
|
|
||||||
if (conn.getResponseCode() != 200) {
|
|
||||||
conn.disconnect();
|
|
||||||
System.out.println("Skipped Download for: " + fileDest.getPath());
|
|
||||||
update(++iCard, fileDest);
|
|
||||||
skipped++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
rbc = Channels.newChannel(conn.getInputStream());
|
|
||||||
fos = new FileOutputStream(fileDest);
|
|
||||||
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
|
|
||||||
} catch (final ConnectException ce) {
|
|
||||||
System.out.println("Connection refused for url: " + url);
|
|
||||||
} catch (final MalformedURLException mURLe) {
|
|
||||||
System.out.println("Error - possibly missing URL for: " + fileDest.getName());
|
|
||||||
} catch (final FileNotFoundException fnfe) {
|
|
||||||
String formatStr = "Error - the LQ picture %s could not be found on the server. [%s] - %s";
|
|
||||||
System.out.println(String.format(formatStr, fileDest.getName(), url, fnfe.getMessage()));
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
Log.error("LQ Pictures", "Error downloading pictures", ex);
|
|
||||||
} finally {
|
|
||||||
if (null != rbc) {
|
|
||||||
try { rbc.close(); } catch (IOException e) { System.out.println("error closing input stream"); }
|
|
||||||
}
|
|
||||||
if (null != fos) {
|
|
||||||
try { fos.close(); } catch (IOException e) { System.out.println("error closing output stream"); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update(++iCard, fileDest);
|
|
||||||
|
|
||||||
// throttle to reduce load on the server
|
|
||||||
try {
|
|
||||||
Thread.sleep(r.nextInt(50) + 50);
|
|
||||||
} catch (final InterruptedException e) {
|
|
||||||
Log.error("GuiDownloader", "Sleep Error", e);
|
|
||||||
}
|
|
||||||
} // for
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Map<String, String> getNeededImages();
|
|
||||||
|
|
||||||
protected static void addMissingItems(Map<String, String> list, String nameUrlFile, String dir) {
|
|
||||||
for (Pair<String, String> nameUrlPair : FileUtil.readNameUrlFile(nameUrlFile)) {
|
|
||||||
File f = new File(dir, nameUrlPair.getLeft());
|
|
||||||
//System.out.println(f.getAbsolutePath());
|
|
||||||
if (!f.exists()) {
|
|
||||||
list.put(f.getAbsolutePath(), nameUrlPair.getRight());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected class ProxyHandler implements ChangeListener {
|
|
||||||
private final int type;
|
private final int type;
|
||||||
|
|
||||||
public ProxyHandler(final int type) {
|
public ProxyHandler(final int type) {
|
||||||
@@ -354,9 +113,9 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
|
|||||||
@Override
|
@Override
|
||||||
public final void stateChanged(final ChangeEvent e) {
|
public final void stateChanged(final ChangeEvent e) {
|
||||||
if (((AbstractButton) e.getSource()).isSelected()) {
|
if (((AbstractButton) e.getSource()).isSelected()) {
|
||||||
GuiDownloader.this.type = this.type;
|
service.setType(this.type);
|
||||||
GuiDownloader.this.txfAddr.setEnabled(this.type != 0);
|
txtAddress.setEnabled(this.type != 0);
|
||||||
GuiDownloader.this.txfPort.setEnabled(this.type != 0);
|
txtPort.setEnabled(this.type != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import forge.download.GuiDownloadPicturesLQ;
|
|||||||
import forge.download.GuiDownloadPrices;
|
import forge.download.GuiDownloadPrices;
|
||||||
import forge.download.GuiDownloadQuestImages;
|
import forge.download.GuiDownloadQuestImages;
|
||||||
import forge.download.GuiDownloadSetPicturesLQ;
|
import forge.download.GuiDownloadSetPicturesLQ;
|
||||||
|
import forge.download.GuiDownloader;
|
||||||
import forge.error.BugReporter;
|
import forge.error.BugReporter;
|
||||||
import forge.gui.ImportDialog;
|
import forge.gui.ImportDialog;
|
||||||
import forge.gui.framework.ICDoc;
|
import forge.gui.framework.ICDoc;
|
||||||
@@ -24,13 +25,13 @@ public enum CSubmenuDownloaders implements ICDoc {
|
|||||||
private final UiCommand cmdLicensing = new UiCommand() { @Override
|
private final UiCommand cmdLicensing = new UiCommand() { @Override
|
||||||
public void run() { VSubmenuDownloaders.SINGLETON_INSTANCE.showLicensing(); } };
|
public void run() { VSubmenuDownloaders.SINGLETON_INSTANCE.showLicensing(); } };
|
||||||
private final UiCommand cmdPicDownload = new UiCommand() { @Override
|
private final UiCommand cmdPicDownload = new UiCommand() { @Override
|
||||||
public void run() { new GuiDownloadPicturesLQ(); } };
|
public void run() { new GuiDownloader(new GuiDownloadPicturesLQ()); } };
|
||||||
private final UiCommand cmdSetDownload = new UiCommand() { @Override
|
private final UiCommand cmdSetDownload = new UiCommand() { @Override
|
||||||
public void run() { new GuiDownloadSetPicturesLQ(); } };
|
public void run() { new GuiDownloader(new GuiDownloadSetPicturesLQ()); } };
|
||||||
private final UiCommand cmdQuestImages = new UiCommand() { @Override
|
private final UiCommand cmdQuestImages = new UiCommand() { @Override
|
||||||
public void run() { new GuiDownloadQuestImages(); } };
|
public void run() { new GuiDownloader(new GuiDownloadQuestImages()); } };
|
||||||
private final UiCommand cmdDownloadPrices = new UiCommand() { @Override
|
private final UiCommand cmdDownloadPrices = new UiCommand() { @Override
|
||||||
public void run() { new GuiDownloadPrices(); } };
|
public void run() { new GuiDownloader(new GuiDownloadPrices()); } };
|
||||||
private final UiCommand cmdHowToPlay = new UiCommand() { @Override
|
private final UiCommand cmdHowToPlay = new UiCommand() { @Override
|
||||||
public void run() { VSubmenuDownloaders.SINGLETON_INSTANCE.showHowToPlay(); } };
|
public void run() { VSubmenuDownloaders.SINGLETON_INSTANCE.showHowToPlay(); } };
|
||||||
private final UiCommand cmdImportPictures = new UiCommand() { @Override
|
private final UiCommand cmdImportPictures = new UiCommand() { @Override
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package forge.toolbox;
|
package forge.toolbox;
|
||||||
|
|
||||||
|
import forge.UiCommand;
|
||||||
import forge.assets.FSkinProp;
|
import forge.assets.FSkinProp;
|
||||||
import forge.gui.framework.ILocalRepaint;
|
import forge.gui.framework.ILocalRepaint;
|
||||||
import forge.interfaces.IButton;
|
import forge.interfaces.IButton;
|
||||||
@@ -237,4 +238,14 @@ public class FButton extends SkinnedButton implements ILocalRepaint, IButton {
|
|||||||
|
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCommand(final UiCommand command) {
|
||||||
|
addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
command.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -627,4 +627,9 @@ public class FLabel extends SkinnedLabel implements ILocalRepaint, IButton {
|
|||||||
super.setIcon(new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH)));
|
super.setIcon(new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCommand(UiCommand command0) {
|
||||||
|
cmdClick = command0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package forge.toolbox;
|
package forge.toolbox;
|
||||||
|
|
||||||
import forge.gui.MouseUtil;
|
import forge.gui.MouseUtil;
|
||||||
|
import forge.interfaces.ITextField;
|
||||||
import forge.toolbox.FSkin.SkinnedTextField;
|
import forge.toolbox.FSkin.SkinnedTextField;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@@ -19,7 +20,7 @@ import java.awt.event.FocusEvent;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class FTextField extends SkinnedTextField {
|
public class FTextField extends SkinnedTextField implements ITextField {
|
||||||
/**
|
/**
|
||||||
* Uses the Builder pattern to facilitate/encourage inline styling.
|
* Uses the Builder pattern to facilitate/encourage inline styling.
|
||||||
* Credit to Effective Java 2 (Joshua Bloch).
|
* Credit to Effective Java 2 (Joshua Bloch).
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package forge;
|
package forge;
|
||||||
|
|
||||||
import forge.download.GuiDownloadPicturesLQ;
|
import forge.download.GuiDownloadPicturesLQ;
|
||||||
|
import forge.download.GuiDownloader;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
@@ -15,6 +16,6 @@ public class GuiDownloadPicturesLQTest {
|
|||||||
*/
|
*/
|
||||||
@Test(enabled = false, timeOut = 1000)
|
@Test(enabled = false, timeOut = 1000)
|
||||||
public void guiDownloadPicturesTest1() {
|
public void guiDownloadPicturesTest1() {
|
||||||
new GuiDownloadPicturesLQ();
|
new GuiDownloader(new GuiDownloadPicturesLQ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package forge;
|
package forge;
|
||||||
|
|
||||||
import forge.download.GuiDownloadSetPicturesLQ;
|
import forge.download.GuiDownloadSetPicturesLQ;
|
||||||
|
import forge.download.GuiDownloader;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
@@ -15,6 +16,6 @@ public class GuiDownloadSetPicturesLQTest {
|
|||||||
*/
|
*/
|
||||||
@Test(enabled = false, timeOut = 1000)
|
@Test(enabled = false, timeOut = 1000)
|
||||||
public void g() {
|
public void g() {
|
||||||
new GuiDownloadSetPicturesLQ();
|
new GuiDownloader(new GuiDownloadSetPicturesLQ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ import forge.toolbox.FOverlay;
|
|||||||
import forge.util.Utils;
|
import forge.util.Utils;
|
||||||
|
|
||||||
public class Forge implements ApplicationListener {
|
public class Forge implements ApplicationListener {
|
||||||
|
public static final String CURRENT_VERSION = "1.5.19.001";
|
||||||
|
|
||||||
private static Clipboard clipboard;
|
private static Clipboard clipboard;
|
||||||
private static int screenWidth;
|
private static int screenWidth;
|
||||||
private static int screenHeight;
|
private static int screenHeight;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import forge.assets.FSkin;
|
|||||||
import forge.assets.FSkinProp;
|
import forge.assets.FSkinProp;
|
||||||
import forge.assets.FTextureImage;
|
import forge.assets.FTextureImage;
|
||||||
import forge.assets.ISkinImage;
|
import forge.assets.ISkinImage;
|
||||||
|
import forge.assets.ImageCache;
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.FDeckViewer;
|
import forge.deck.FDeckViewer;
|
||||||
import forge.error.BugReportDialog;
|
import forge.error.BugReportDialog;
|
||||||
@@ -373,4 +374,9 @@ public class GuiMobile implements IGuiBase {
|
|||||||
public void startAltSoundSystem(String filename, boolean isSynchronized) {
|
public void startAltSoundSystem(String filename, boolean isSynchronized) {
|
||||||
//TODO: Support alt sound system
|
//TODO: Support alt sound system
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearImageCache() {
|
||||||
|
ImageCache.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.badlogic.gdx.Input.Keys;
|
|||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
|
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
|
import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
|
||||||
|
|
||||||
|
import forge.UiCommand;
|
||||||
import forge.Forge.Graphics;
|
import forge.Forge.Graphics;
|
||||||
import forge.assets.FSkinColor;
|
import forge.assets.FSkinColor;
|
||||||
import forge.assets.FSkinColor.Colors;
|
import forge.assets.FSkinColor.Colors;
|
||||||
@@ -228,4 +229,20 @@ public class FButton extends FDisplayObject implements IButton {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//use FEventHandler one except when references as IButton
|
||||||
|
@Override
|
||||||
|
public void setCommand(final UiCommand command0) {
|
||||||
|
setCommand(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
command0.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requestFocusInWindow() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
|
|||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
|
||||||
import forge.Forge.Graphics;
|
import forge.Forge.Graphics;
|
||||||
|
import forge.UiCommand;
|
||||||
import forge.assets.FImage;
|
import forge.assets.FImage;
|
||||||
import forge.assets.FSkinColor;
|
import forge.assets.FSkinColor;
|
||||||
import forge.assets.FSkinColor.Colors;
|
import forge.assets.FSkinColor.Colors;
|
||||||
@@ -311,4 +312,20 @@ public class FLabel extends FDisplayObject implements IButton {
|
|||||||
g.endClip();
|
g.endClip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//use FEventHandler one except when references as IButton
|
||||||
|
@Override
|
||||||
|
public void setCommand(final UiCommand command0) {
|
||||||
|
setCommand(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
command0.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requestFocusInWindow() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ import forge.Forge.KeyInputAdapter;
|
|||||||
import forge.assets.FSkinColor;
|
import forge.assets.FSkinColor;
|
||||||
import forge.assets.FSkinFont;
|
import forge.assets.FSkinFont;
|
||||||
import forge.assets.FSkinColor.Colors;
|
import forge.assets.FSkinColor.Colors;
|
||||||
|
import forge.interfaces.ITextField;
|
||||||
import forge.toolbox.FEvent.FEventHandler;
|
import forge.toolbox.FEvent.FEventHandler;
|
||||||
import forge.toolbox.FEvent.FEventType;
|
import forge.toolbox.FEvent.FEventType;
|
||||||
import forge.util.Utils;
|
import forge.util.Utils;
|
||||||
|
|
||||||
public class FTextField extends FDisplayObject {
|
public class FTextField extends FDisplayObject implements ITextField {
|
||||||
private static final FSkinFont DEFAULT_FONT = FSkinFont.get(14);
|
private static final FSkinFont DEFAULT_FONT = FSkinFont.get(14);
|
||||||
private static final float BORDER_THICKNESS = Utils.scaleX(1);
|
private static final float BORDER_THICKNESS = Utils.scaleX(1);
|
||||||
protected static final float PADDING = Utils.scaleX(5);
|
protected static final float PADDING = Utils.scaleX(5);
|
||||||
@@ -330,4 +331,9 @@ public class FTextField extends FDisplayObject {
|
|||||||
protected float getRightPadding() {
|
protected float getRightPadding() {
|
||||||
return PADDING;
|
return PADDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requestFocusInWindow() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,14 +29,9 @@ import java.io.File;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
public class GuiDownloadPicturesLQ extends GuiDownloadService {
|
||||||
public class GuiDownloadPicturesLQ extends GuiDownloader {
|
|
||||||
public GuiDownloadPicturesLQ() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final Map<String, String> getNeededImages() {
|
protected final Map<String, String> getNeededFiles() {
|
||||||
Map<String, String> downloads = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
Map<String, String> downloads = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
|
||||||
for (PaperCard c : FModel.getMagicDb().getCommonCards().getAllCards()) {
|
for (PaperCard c : FModel.getMagicDb().getCommonCards().getAllCards()) {
|
||||||
@@ -22,14 +22,9 @@ import forge.properties.ForgeConstants;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
public class GuiDownloadPrices extends GuiDownloadService {
|
||||||
public class GuiDownloadPrices extends GuiDownloader {
|
|
||||||
public GuiDownloadPrices() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, String> getNeededImages() {
|
protected Map<String, String> getNeededFiles() {
|
||||||
Map<String, String> result = new HashMap<String, String>();
|
Map<String, String> result = new HashMap<String, String>();
|
||||||
result.put(ForgeConstants.QUEST_CARD_PRICE_FILE, ForgeConstants.URL_PRICE_DOWNLOAD);
|
result.put(ForgeConstants.QUEST_CARD_PRICE_FILE, ForgeConstants.URL_PRICE_DOWNLOAD);
|
||||||
return result;
|
return result;
|
||||||
@@ -22,27 +22,9 @@ import forge.properties.ForgeConstants;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
/** */
|
public class GuiDownloadQuestImages extends GuiDownloadService {
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public class GuiDownloadQuestImages extends GuiDownloader {
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Constructor for GuiDownloadQuestImages.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public GuiDownloadQuestImages() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getNeededCards.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return an array of {@link forge.download.GuiDownloadSetPicturesLQ} objects.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected final Map<String, String> getNeededImages() {
|
protected final Map<String, String> getNeededFiles() {
|
||||||
// read all card names and urls
|
// read all card names and urls
|
||||||
final Map<String, String> urls = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
final Map<String, String> urls = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
|
||||||
303
forge-gui/src/main/java/forge/download/GuiDownloadService.java
Normal file
303
forge-gui/src/main/java/forge/download/GuiDownloadService.java
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Forge Team
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.download;
|
||||||
|
|
||||||
|
import com.esotericsoftware.minlog.Log;
|
||||||
|
|
||||||
|
import forge.FThreads;
|
||||||
|
import forge.GuiBase;
|
||||||
|
import forge.UiCommand;
|
||||||
|
import forge.error.BugReporter;
|
||||||
|
import forge.interfaces.IButton;
|
||||||
|
import forge.interfaces.IProgressBar;
|
||||||
|
import forge.interfaces.ITextField;
|
||||||
|
import forge.util.FileUtil;
|
||||||
|
import forge.util.MyRandom;
|
||||||
|
import forge.util.ThreadUtil;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.*;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public abstract class GuiDownloadService implements Runnable {
|
||||||
|
public static final Proxy.Type[] TYPES = Proxy.Type.values();
|
||||||
|
|
||||||
|
//Components passed from GUI component displaying download
|
||||||
|
private ITextField txtAddress;
|
||||||
|
private ITextField txtPort;
|
||||||
|
private IProgressBar barProgress;
|
||||||
|
private IButton btnStart;
|
||||||
|
private UiCommand cmdClose;
|
||||||
|
private Runnable onUpdate;
|
||||||
|
|
||||||
|
private final UiCommand cmdStartDownload = new UiCommand() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//invalidate image cache so newly downloaded images will be loaded
|
||||||
|
GuiBase.getInterface().clearImageCache();
|
||||||
|
ThreadUtil.invokeInGameThread(this);
|
||||||
|
btnStart.setEnabled(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Proxy info
|
||||||
|
private int type;
|
||||||
|
|
||||||
|
// Progress variables
|
||||||
|
private Map<String, String> cards; // local path -> url
|
||||||
|
private boolean cancel;
|
||||||
|
private final long[] times = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
private int tptr = 0;
|
||||||
|
private int skipped = 0;
|
||||||
|
private long lTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
protected GuiDownloadService() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(ITextField txtAddress0, ITextField txtPort0, IProgressBar barProgress0, IButton btnStart0, UiCommand cmdClose0, Runnable onUpdate0) {
|
||||||
|
txtAddress = txtAddress0;
|
||||||
|
txtPort = txtPort0;
|
||||||
|
barProgress = barProgress0;
|
||||||
|
btnStart = btnStart0;
|
||||||
|
cmdClose = cmdClose0;
|
||||||
|
onUpdate = onUpdate0;
|
||||||
|
|
||||||
|
// Free up the EDT by assembling card list on the game thread
|
||||||
|
ThreadUtil.invokeInGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
cards = getNeededFiles();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
FThreads.invokeInEdtLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
readyToStart();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readyToStart() {
|
||||||
|
if (cards.isEmpty()) {
|
||||||
|
barProgress.setDescription("All items have been downloaded.");
|
||||||
|
btnStart.setText("OK");
|
||||||
|
btnStart.setCommand(cmdClose);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
barProgress.setMaximum(cards.size());
|
||||||
|
barProgress.setDescription(cards.size() == 1 ? "1 item found." : cards.size() + " items found.");
|
||||||
|
//for(Entry<String, String> kv : cards.entrySet()) System.out.printf("Will get %s from %s%n", kv.getKey(), kv.getValue());
|
||||||
|
btnStart.setCommand(cmdStartDownload);
|
||||||
|
}
|
||||||
|
btnStart.setVisible(true);
|
||||||
|
|
||||||
|
FThreads.invokeInEdtLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
btnStart.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(int type0) {
|
||||||
|
type = type0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCancel(boolean cancel0) {
|
||||||
|
cancel = cancel0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final int getAverageTimePerObject() {
|
||||||
|
int numNonzero = 10;
|
||||||
|
|
||||||
|
if (tptr > 9) {
|
||||||
|
tptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
times[tptr] = System.currentTimeMillis() - lTime;
|
||||||
|
lTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
int tTime = 0;
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
tTime += times[i];
|
||||||
|
if (times[i] == 0) {
|
||||||
|
numNonzero--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tptr++;
|
||||||
|
return tTime / Math.max(1, numNonzero);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update(final int card, final File dest) {
|
||||||
|
FThreads.invokeInEdtLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
onUpdate.run();
|
||||||
|
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
final int a = getAverageTimePerObject();
|
||||||
|
|
||||||
|
if (card != cards.size()) {
|
||||||
|
sb.append(card + "/" + cards.size() + " - ");
|
||||||
|
|
||||||
|
long t2Go = (cards.size() - card) * a;
|
||||||
|
|
||||||
|
if (t2Go > 3600000) {
|
||||||
|
sb.append(String.format("%02d:", t2Go / 3600000));
|
||||||
|
t2Go = t2Go % 3600000;
|
||||||
|
}
|
||||||
|
if (t2Go > 60000) {
|
||||||
|
sb.append(String.format("%02d:", t2Go / 60000));
|
||||||
|
t2Go = t2Go % 60000;
|
||||||
|
} else {
|
||||||
|
sb.append("00:");
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(String.format("%02d remaining.", t2Go / 1000));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sb.append(String.format("%d of %d items finished! Skipped " + skipped + " items. Please close!",
|
||||||
|
card, cards.size()));
|
||||||
|
btnStart.setText("OK");
|
||||||
|
btnStart.setCommand(cmdClose);
|
||||||
|
btnStart.setEnabled(true);
|
||||||
|
btnStart.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
barProgress.setDescription(sb.toString());
|
||||||
|
System.out.println(card + "/" + cards.size() + " - " + dest);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void run() {
|
||||||
|
final Random r = MyRandom.getRandom();
|
||||||
|
|
||||||
|
Proxy p = null;
|
||||||
|
if (type == 0) {
|
||||||
|
p = Proxy.NO_PROXY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
p = new Proxy(TYPES[type], new InetSocketAddress(txtAddress.getText(), Integer.parseInt(txtPort.getText())));
|
||||||
|
}
|
||||||
|
catch (final Exception ex) {
|
||||||
|
BugReporter.reportException(ex,
|
||||||
|
"Proxy connection could not be established!\nProxy address: %s\nProxy port: %s",
|
||||||
|
txtAddress.getText(), txtPort.getText());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int iCard = 0;
|
||||||
|
for (Entry<String, String> kv : cards.entrySet()) {
|
||||||
|
if (cancel) { break; }
|
||||||
|
|
||||||
|
String url = kv.getValue();
|
||||||
|
final File fileDest = new File(kv.getKey());
|
||||||
|
final File base = fileDest.getParentFile();
|
||||||
|
|
||||||
|
ReadableByteChannel rbc = null;
|
||||||
|
FileOutputStream fos = null;
|
||||||
|
try {
|
||||||
|
// test for folder existence
|
||||||
|
if (!base.exists() && !base.mkdir()) { // create folder if not found
|
||||||
|
System.out.println("Can't create folder" + base.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
URL imageUrl = new URL(url);
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection(p);
|
||||||
|
// don't allow redirections here -- they indicate 'file not found' on the server
|
||||||
|
conn.setInstanceFollowRedirects(false);
|
||||||
|
conn.connect();
|
||||||
|
|
||||||
|
if (conn.getResponseCode() != 200) {
|
||||||
|
conn.disconnect();
|
||||||
|
System.out.println("Skipped Download for: " + fileDest.getPath());
|
||||||
|
update(++iCard, fileDest);
|
||||||
|
skipped++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rbc = Channels.newChannel(conn.getInputStream());
|
||||||
|
fos = new FileOutputStream(fileDest);
|
||||||
|
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
|
||||||
|
}
|
||||||
|
catch (final ConnectException ce) {
|
||||||
|
System.out.println("Connection refused for url: " + url);
|
||||||
|
}
|
||||||
|
catch (final MalformedURLException mURLe) {
|
||||||
|
System.out.println("Error - possibly missing URL for: " + fileDest.getName());
|
||||||
|
}
|
||||||
|
catch (final FileNotFoundException fnfe) {
|
||||||
|
String formatStr = "Error - the LQ picture %s could not be found on the server. [%s] - %s";
|
||||||
|
System.out.println(String.format(formatStr, fileDest.getName(), url, fnfe.getMessage()));
|
||||||
|
}
|
||||||
|
catch (final Exception ex) {
|
||||||
|
Log.error("LQ Pictures", "Error downloading pictures", ex);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (null != rbc) {
|
||||||
|
try { rbc.close(); } catch (IOException e) { System.out.println("error closing input stream"); }
|
||||||
|
}
|
||||||
|
if (null != fos) {
|
||||||
|
try { fos.close(); } catch (IOException e) { System.out.println("error closing output stream"); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update(++iCard, fileDest);
|
||||||
|
|
||||||
|
// throttle to reduce load on the server
|
||||||
|
try {
|
||||||
|
Thread.sleep(r.nextInt(50) + 50);
|
||||||
|
} catch (final InterruptedException e) {
|
||||||
|
Log.error("GuiDownloader", "Sleep Error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Map<String, String> getNeededFiles();
|
||||||
|
|
||||||
|
protected static void addMissingItems(Map<String, String> list, String nameUrlFile, String dir) {
|
||||||
|
for (Pair<String, String> nameUrlPair : FileUtil.readNameUrlFile(nameUrlFile)) {
|
||||||
|
File f = new File(dir, nameUrlPair.getLeft());
|
||||||
|
//System.out.println(f.getAbsolutePath());
|
||||||
|
if (!f.exists()) {
|
||||||
|
list.put(f.getAbsolutePath(), nameUrlPair.getRight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,14 +31,9 @@ import java.io.File;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
public class GuiDownloadSetPicturesLQ extends GuiDownloadService {
|
||||||
public class GuiDownloadSetPicturesLQ extends GuiDownloader {
|
|
||||||
public GuiDownloadSetPicturesLQ() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final Map<String, String> getNeededImages() {
|
protected final Map<String, String> getNeededFiles() {
|
||||||
Map<String, String> downloads = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
Map<String, String> downloads = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
|
||||||
for (final PaperCard c : Iterables.concat(FModel.getMagicDb().getCommonCards().getAllCards(), FModel.getMagicDb().getVariantCards().getAllCards())) {
|
for (final PaperCard c : Iterables.concat(FModel.getMagicDb().getCommonCards().getAllCards(), FModel.getMagicDb().getVariantCards().getAllCards())) {
|
||||||
@@ -1,10 +1,16 @@
|
|||||||
package forge.interfaces;
|
package forge.interfaces;
|
||||||
|
|
||||||
|
import forge.UiCommand;
|
||||||
|
|
||||||
public interface IButton {
|
public interface IButton {
|
||||||
boolean isEnabled();
|
boolean isEnabled();
|
||||||
void setEnabled(boolean b0);
|
void setEnabled(boolean b0);
|
||||||
|
boolean isVisible();
|
||||||
|
void setVisible(boolean b0);
|
||||||
String getText();
|
String getText();
|
||||||
void setText(String text0);
|
void setText(String text0);
|
||||||
boolean isSelected();
|
boolean isSelected();
|
||||||
void setSelected(boolean b0);
|
void setSelected(boolean b0);
|
||||||
|
boolean requestFocusInWindow();
|
||||||
|
void setCommand(UiCommand command0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,4 +87,5 @@ public interface IGuiBase {
|
|||||||
ForgeProfileProperties getProfileProps();
|
ForgeProfileProperties getProfileProps();
|
||||||
IAudioClip createAudioClip(String filename);
|
IAudioClip createAudioClip(String filename);
|
||||||
void startAltSoundSystem(String filename, boolean isSynchronized);
|
void startAltSoundSystem(String filename, boolean isSynchronized);
|
||||||
|
void clearImageCache();
|
||||||
}
|
}
|
||||||
11
forge-gui/src/main/java/forge/interfaces/ITextField.java
Normal file
11
forge-gui/src/main/java/forge/interfaces/ITextField.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package forge.interfaces;
|
||||||
|
|
||||||
|
public interface ITextField {
|
||||||
|
boolean isEnabled();
|
||||||
|
void setEnabled(boolean b0);
|
||||||
|
boolean isVisible();
|
||||||
|
void setVisible(boolean b0);
|
||||||
|
String getText();
|
||||||
|
void setText(String text0);
|
||||||
|
boolean requestFocusInWindow();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user