summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2015-08-07 17:42:25 +0200
committerSimon Rettberg2015-08-07 17:42:25 +0200
commit76aa5675c7b1a5488593bd2ca51b8db910605518 (patch)
treee40b50892784114aa2b733551b16b57201c52b64
parent[client] make image details editable also if user has admin rights or if he d... (diff)
downloadtutor-module-76aa5675c7b1a5488593bd2ca51b8db910605518.tar.gz
tutor-module-76aa5675c7b1a5488593bd2ca51b8db910605518.tar.xz
tutor-module-76aa5675c7b1a5488593bd2ca51b8db910605518.zip
[client] Implement progress bar for uploads in main window
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/TransferEvent.java5
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java21
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/ActivityPanel.java14
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UploadPanel.java119
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/MainMenuWindow.java6
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java86
6 files changed, 146 insertions, 105 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/TransferEvent.java b/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/TransferEvent.java
index 4206da81..af63b0c6 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/TransferEvent.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/TransferEvent.java
@@ -14,7 +14,8 @@ public class TransferEvent {
*/
public final String speed;
/**
- * Estimated remaining time, human readable. <code>null</code> == not updated
+ * Estimated remaining time, human readable. <code>null</code> == not
+ * updated
*/
public final String remaining;
/**
@@ -44,7 +45,7 @@ public class TransferEvent {
if (remainingRaw == 0) {
this.remaining = null;
} else {
- this.remaining = FormatHelper.formatMilliseconds(remainingRaw, false);
+ this.remaining = FormatHelper.formatMilliseconds(remainingRaw + 30000, false);
}
this.errorMessage = errorMessage;
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
index d5b4d4e3..295cf413 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
@@ -10,7 +10,6 @@ import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
-import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -22,11 +21,10 @@ import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
+import javax.swing.JSeparator;
import org.apache.log4j.Logger;
import org.apache.thrift.TException;
-import org.openslx.bwlp.thrift.iface.TAuthorizationException;
-import org.openslx.bwlp.thrift.iface.TInternalServerError;
import org.openslx.dozmod.App;
import org.openslx.dozmod.Config;
import org.openslx.dozmod.Config.SavedSession;
@@ -202,6 +200,8 @@ public abstract class MainWindow {
mainWindow.getContentPane().add(win, BorderLayout.PAGE_START);
}
activityPanel.setLayout(new BoxLayout(activityPanel, BoxLayout.PAGE_AXIS));
+ activityPanel.setVisible(false);
+ activityPanel.add(new JSeparator());
mainWindow.getContentPane().add(activityPanel, BorderLayout.PAGE_END);
// center the window on the primary monitor
@@ -271,8 +271,19 @@ public abstract class MainWindow {
}
public static void addUpload(UploadWizardState state) {
- activities.add(new UploadPanel(activityPanel, state));
- activityPanel.validate();
+ UploadPanel panel = new UploadPanel(state);
+ activities.add(panel);
+ activityPanel.add(panel);
+ activityPanel.setVisible(true);
+ mainWindow.validate();
+ }
+
+ public static void removeActivity(ActivityPanel panel) {
+ activities.remove(panel);
+ activityPanel.remove(panel);
+ if (activities.isEmpty())
+ activityPanel.setVisible(false);
+ mainWindow.validate();
}
private static void createMenu() {
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/ActivityPanel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/ActivityPanel.java
index eb651fef..768ee82d 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/ActivityPanel.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/ActivityPanel.java
@@ -2,14 +2,10 @@ package org.openslx.dozmod.gui.activity;
import javax.swing.JPanel;
-public abstract class ActivityPanel extends JPanel {
-
- private final JPanel container;
+import org.openslx.dozmod.gui.MainWindow;
- public ActivityPanel(JPanel container) {
- this.container = container;
- container.add(this);
- }
+@SuppressWarnings("serial")
+public abstract class ActivityPanel extends JPanel {
/**
* If this activity wants to prevent the user from closing the application,
@@ -20,4 +16,8 @@ public abstract class ActivityPanel extends JPanel {
*/
public abstract boolean wantConfirmQuit();
+ protected final void close() {
+ MainWindow.removeActivity(this);
+ }
+
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UploadPanel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UploadPanel.java
index 430f6ae6..46ffb51c 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UploadPanel.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/activity/UploadPanel.java
@@ -1,5 +1,6 @@
package org.openslx.dozmod.gui.activity;
+import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
@@ -13,20 +14,43 @@ import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
+import org.apache.log4j.Logger;
+import org.openslx.dozmod.filetransfer.TransferEvent;
+import org.openslx.dozmod.filetransfer.TransferEventListener;
+import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.control.BlockProgressBar;
+import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.state.UploadWizardState;
+import org.openslx.thrifthelper.ThriftManager;
+import org.openslx.util.QuickTimer;
+import org.openslx.util.QuickTimer.Task;
@SuppressWarnings("serial")
-public class UploadPanel extends ActivityPanel {
+public class UploadPanel extends ActivityPanel implements TransferEventListener {
+
+ private static final Logger LOGGER = Logger.getLogger(UploadPanel.class);
private final JLabel lblStatus;
+ private final JLabel lblError;
+
+ private final JLabel lblSpeed;
+
+ private final JLabel lblRemaining;
+
private final BlockProgressBar progress;
private final UploadWizardState state;
- public UploadPanel(JPanel container, UploadWizardState state) {
- super(container);
+ private final UploadPanel panel = this;
+
+ private final Color defaultLabelColor;
+
+ private int errorCountdown = 0;
+
+ private final JButton btnClose;
+
+ public UploadPanel(UploadWizardState state) {
this.state = state;
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
@@ -42,9 +66,9 @@ public class UploadPanel extends ActivityPanel {
header.add(Box.createHorizontalGlue());
header.add(new JLabel(state.diskFile.getName()));
header.add(Box.createHorizontalStrut(10));
- JButton button = new JButton("Knopf");
- button.addActionListener(new ButtonAction());
- header.add(button);
+ btnClose = new JButton("Abbrechen");
+ btnClose.addActionListener(new ButtonAction());
+ header.add(btnClose);
add(header);
// ProgressBar
JPanel progressWrapper = new JPanel();
@@ -54,17 +78,98 @@ public class UploadPanel extends ActivityPanel {
progress = new BlockProgressBar(null);
progressWrapper.add(progress);
add(progressWrapper);
+ // Speed & error
+ JPanel footer = new JPanel();
+ footer.setLayout(new BoxLayout(footer, BoxLayout.LINE_AXIS));
+ lblError = new JLabel();
+ lblSpeed = new JLabel("-");
+ lblRemaining = new JLabel("-");
+ lblSpeed.setMinimumSize(new Dimension(50, 0));
+ lblRemaining.setMinimumSize(new Dimension(60, 0));
+ footer.add(lblError);
+ footer.add(Box.createGlue());
+ footer.add(lblSpeed);
+ footer.add(Box.createRigidArea(new Dimension(6, 6)));
+ footer.add(lblRemaining);
+ add(footer);
+ defaultLabelColor = lblError.getForeground();
+ state.uploadTask.addListener(this);
}
@Override
public boolean wantConfirmQuit() {
- return false;
+ return state != null && state.uploadTask != null && !state.uploadTask.isCanceled();
}
private class ButtonAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
+ if (!state.uploadTask.isCanceled()) {
+ if (!Gui.showMessageBox(panel, "Wollen Sie diesen Transfer wirklich abbrechen?",
+ MessageType.QUESTION_YESNO, null, null))
+ return;
+ state.uploadTask.cancel();
+ QuickTimer.scheduleOnce(new Task() {
+ @Override
+ public void fire() {
+ try {
+ ThriftManager.getSatClient().cancelUpload(state.transferInformation.getToken());
+ } catch (Exception ex) {
+ LOGGER.debug("Remote error while canceling upload for " + state.uuid, ex);
+ }
+ }
+ });
+ }
+ state.uploadTask.removeListener(panel);
+ close();
}
}
+ @Override
+ public void update(final TransferEvent event) {
+ Gui.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ // Any error message?
+ if (event.errorMessage != null && !event.errorMessage.isEmpty()) {
+ lblError.setText(event.errorMessage);
+ lblError.setForeground(Color.RED);
+ errorCountdown = 20;
+ } else if (errorCountdown > 0) {
+ errorCountdown--;
+ if (errorCountdown == 10) {
+ lblError.setForeground(defaultLabelColor);
+ } else if (errorCountdown == 0) {
+ lblError.setText("");
+ }
+ }
+ // Status?
+ if (event.state != null) {
+ switch (event.state) {
+ case ERROR:
+ errorCountdown = 20;
+ break;
+ case FINISHED:
+ btnClose.setText("Schließen");
+ lblRemaining.setText("-");
+ state.uploadTask.removeListener(panel);
+ break;
+ }
+ lblStatus.setText(event.state.toString());
+ }
+ // Remaining + Speed
+ if (event.remainingRaw != 0) {
+ lblRemaining.setText(event.remaining);
+ }
+ if (event.speedRaw != 0) {
+ lblSpeed.setText(event.speed);
+ }
+ // Progress bar
+ if (event.progress != null) {
+ progress.setStatus(event.progress);
+ }
+ panel.validate();
+ }
+ });
+ }
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/MainMenuWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/MainMenuWindow.java
index a4a73510..066ef54c 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/MainMenuWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/MainMenuWindow.java
@@ -19,6 +19,7 @@ import org.openslx.util.QuickTimer.Task;
import com.google.gson.Gson;
+@SuppressWarnings("serial")
public class MainMenuWindow extends MainMenuWindowLayout {
public MainMenuWindow() {
@@ -60,7 +61,7 @@ public class MainMenuWindow extends MainMenuWindowLayout {
private class GResult {
private String tbUrl;
}
-
+
private int loadImageToControl(int start, GResult[] results, final JButton control) {
if (start >= results.length)
start = results.length - 1;
@@ -101,7 +102,8 @@ public class MainMenuWindow extends MainMenuWindowLayout {
String term = terms[(int) Math.floor(Math.random() * terms.length)] + "+"
+ terms[(int) Math.floor(Math.random() * terms.length)];
try {
- URL oracle = new URL("http://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=8&q=" + term);
+ URL oracle = new URL(
+ "http://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=8&q=" + term);
Reader reader = new InputStreamReader(oracle.openStream());
Gson gson = new Gson();
GMain data = gson.fromJson(reader, GMain.class);
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java
index afb0fed8..e7f9700f 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/wizard/page/ImageUploadPage.java
@@ -20,10 +20,9 @@ import javax.swing.filechooser.FileNameExtensionFilter;
import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.TImageDataException;
import org.openslx.dozmod.Config;
-import org.openslx.dozmod.filetransfer.TransferEvent;
-import org.openslx.dozmod.filetransfer.TransferEventListener;
import org.openslx.dozmod.filetransfer.UploadTask;
import org.openslx.dozmod.gui.Gui;
+import org.openslx.dozmod.gui.MainWindow;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.wizard.Wizard;
import org.openslx.dozmod.gui.wizard.layout.ImageUploadPageLayout;
@@ -31,8 +30,6 @@ import org.openslx.dozmod.state.UploadWizardState;
import org.openslx.dozmod.thrift.MetaDataCache;
import org.openslx.dozmod.thrift.Session;
import org.openslx.thrifthelper.ThriftManager;
-import org.openslx.util.QuickTimer;
-import org.openslx.util.QuickTimer.Task;
import org.openslx.util.Util;
import org.openslx.util.vm.VmMetaData.HardDisk;
import org.openslx.util.vm.VmwareMetaData;
@@ -241,20 +238,6 @@ public class ImageUploadPage extends ImageUploadPageLayout {
+ state.diskFile.getAbsolutePath(), MessageType.ERROR, LOGGER, e);
return false;
}
- // -- add listener for upload status/progress --
- state.uploadTask.addListener(new TransferEventListener() {
- @Override
- public void update(final TransferEvent event) {
- final TransferEventListener listener = this;
- Gui.asyncExec(new Runnable() {
- @Override
- public void run() {
- // always callback to gui
- processTransferStatus(listener, event);
- }
- });
- }
- });
new Thread(state.uploadTask).start();
do {
Util.sleep(5);
@@ -265,74 +248,13 @@ public class ImageUploadPage extends ImageUploadPageLayout {
if (state.uploadTask.getTransferCount() == 0) {
Gui.showMessageBox(this, "Aufbau der Verbindung zum Hochladen fehlgeschlagen", MessageType.ERROR,
LOGGER, null);
+ state.uploadTask.cancel();
+ state.uploadTask = null;
return false;
}
+ MainWindow.addUpload(state);
// -- check image creation --
blockProgressBar.setVisible(true);
return true;
}
-
- /**
- * Evaluates the transfer's state and show feedback to the user based on the
- * state.
- *
- * @param listener
- */
- private void processTransferStatus(TransferEventListener listener, TransferEvent event) {
- if (!getTopLevelAncestor().isVisible()) {
- if (state.uploadTask != null) {
- state.uploadTask.removeListener(listener);
- }
- return;
- }
- if (!isVisible())
- return;
- // always update progress bar
- if (event.progress != null) {
- // TODO: Maybe only display percentage in the wizard pages once we have the status bar in mainwindow
- blockProgressBar.setStatus(event.progress);
- }
- if (event.state == null)
- return;
- // TODO: Move user interaction to central listener when we have it
- switch (event.state) {
- case FINISHED:
- Gui.showMessageBox(this, "Upload abgeschlossen.", MessageType.INFO, LOGGER, null);
- break;
- case ERROR:
- if (state.uploadTask != null && state.uploadTask.isCanceled())
- return;
- Gui.showMessageBox(this, "Fehler beim Upload: " + event.errorMessage, MessageType.ERROR, LOGGER,
- null);
- // user wants to try again, just reset transferInformation ...
- state.uploadTask = null;
- break;
- case WORKING:
- case IDLE:
- break;
- default:
- LOGGER.warn("Unhandled transfer state: " + event.state);
- break;
- }
- }
-
- // TODO: In main control in main window....
- private void cancelUpload() {
- LOGGER.debug("Cancelling upload ...");
- // first tell the server about this
- QuickTimer.scheduleOnce(new Task() {
- @Override
- public void fire() {
- try {
- ThriftManager.getSatClient().cancelUpload(state.transferInformation.getToken());
- } catch (Exception e) {
- LOGGER.debug("Remote error while canceling upload for " + state.uuid, e);
- }
- // Then cancel the task
- state.uploadTask.cancel();
- }
- });
- setPageComplete(false);
- blockProgressBar.setVisible(false);
- }
}