summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatti Tahvonen <matti.tahvonen@itmill.com>2009-08-05 07:48:43 +0000
committerMatti Tahvonen <matti.tahvonen@itmill.com>2009-08-05 07:48:43 +0000
commitb84bf1a1bd398d99de027f1468b8c5d07dd7dc50 (patch)
tree95e1b716788dee1412dee7f7d3f4a394aa4490c1
parent38e319600485d65b5b6298833e2dfa8f5ba51a12 (diff)
downloadvaadin-framework-b84bf1a1bd398d99de027f1468b8c5d07dd7dc50.tar.gz
vaadin-framework-b84bf1a1bd398d99de027f1468b8c5d07dd7dc50.zip
multiple upload related enhancements
- implemented interruption of upload #963 - added generics - changed deprecated gwt methods to 1.6 handlers - immediate mode now works (also styled as "one button upload") svn changeset:8442/svn branch:6.0
-rw-r--r--WebContent/VAADIN/themes/base/styles.css24
-rw-r--r--WebContent/VAADIN/themes/base/upload/upload.css22
-rw-r--r--WebContent/VAADIN/themes/reindeer/styles.css24
-rw-r--r--WebContent/VAADIN/themes/runo/styles.css24
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VUpload.java155
-rw-r--r--src/com/vaadin/tests/TestForStyledUpload.java288
-rw-r--r--src/com/vaadin/ui/Upload.java56
7 files changed, 546 insertions, 47 deletions
diff --git a/WebContent/VAADIN/themes/base/styles.css b/WebContent/VAADIN/themes/base/styles.css
index a75762c0f8..e98bef219c 100644
--- a/WebContent/VAADIN/themes/base/styles.css
+++ b/WebContent/VAADIN/themes/base/styles.css
@@ -1436,6 +1436,30 @@ div.v-tree-node-leaf {
clear: left;
}
+/* ./WebContent/VAADIN/themes/base/upload/upload.css */
+.v-upload-immediate {
+ position: relative;
+ width: 10em;
+ margin:0;
+}
+
+.v-upload-immediate input {
+ opacity: 0;
+ filter: alpha(opacity=0);
+ z-index:2;
+ position: absolute;
+ right:0;
+ height:21px;
+ text-align: right;
+}
+.v-upload-immediate button {
+ position:relative;
+ left:0;
+ top:0;
+ width:100%;
+}
+
+
/* ./WebContent/VAADIN/themes/base/window/window.css */
.v-window {
background: #fff;
diff --git a/WebContent/VAADIN/themes/base/upload/upload.css b/WebContent/VAADIN/themes/base/upload/upload.css
new file mode 100644
index 0000000000..ba96537ddb
--- /dev/null
+++ b/WebContent/VAADIN/themes/base/upload/upload.css
@@ -0,0 +1,22 @@
+.v-upload-immediate {
+ position: relative;
+ width: 10em;
+ margin:0;
+}
+
+.v-upload-immediate input {
+ opacity: 0;
+ filter: alpha(opacity=0);
+ z-index:2;
+ position: absolute;
+ right:0;
+ height:21px;
+ text-align: right;
+}
+.v-upload-immediate button {
+ position:relative;
+ left:0;
+ top:0;
+ width:100%;
+}
+ \ No newline at end of file
diff --git a/WebContent/VAADIN/themes/reindeer/styles.css b/WebContent/VAADIN/themes/reindeer/styles.css
index 4df54dd3ed..b5bf3402e5 100644
--- a/WebContent/VAADIN/themes/reindeer/styles.css
+++ b/WebContent/VAADIN/themes/reindeer/styles.css
@@ -1436,6 +1436,30 @@ div.v-tree-node-leaf {
clear: left;
}
+/* ./WebContent/VAADIN/themes/base/upload/upload.css */
+.v-upload-immediate {
+ position: relative;
+ width: 10em;
+ margin:0;
+}
+
+.v-upload-immediate input {
+ opacity: 0;
+ filter: alpha(opacity=0);
+ z-index:2;
+ position: absolute;
+ right:0;
+ height:21px;
+ text-align: right;
+}
+.v-upload-immediate button {
+ position:relative;
+ left:0;
+ top:0;
+ width:100%;
+}
+
+
/* ./WebContent/VAADIN/themes/base/window/window.css */
.v-window {
background: #fff;
diff --git a/WebContent/VAADIN/themes/runo/styles.css b/WebContent/VAADIN/themes/runo/styles.css
index a1633d5522..639e4cc992 100644
--- a/WebContent/VAADIN/themes/runo/styles.css
+++ b/WebContent/VAADIN/themes/runo/styles.css
@@ -1436,6 +1436,30 @@ div.v-tree-node-leaf {
clear: left;
}
+/* ./WebContent/VAADIN/themes/base/upload/upload.css */
+.v-upload-immediate {
+ position: relative;
+ width: 10em;
+ margin:0;
+}
+
+.v-upload-immediate input {
+ opacity: 0;
+ filter: alpha(opacity=0);
+ z-index:2;
+ position: absolute;
+ right:0;
+ height:21px;
+ text-align: right;
+}
+.v-upload-immediate button {
+ position:relative;
+ left:0;
+ top:0;
+ width:100%;
+}
+
+
/* ./WebContent/VAADIN/themes/base/window/window.css */
.v-window {
background: #fff;
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java
index 666652a15a..117d3ea267 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java
@@ -4,30 +4,53 @@
package com.vaadin.terminal.gwt.client.ui;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.FormHandler;
import com.google.gwt.user.client.ui.FormPanel;
-import com.google.gwt.user.client.ui.FormSubmitCompleteEvent;
-import com.google.gwt.user.client.ui.FormSubmitEvent;
+import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.Panel;
-import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler;
+import com.google.gwt.user.client.ui.FormPanel.SubmitHandler;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;
-public class VUpload extends FormPanel implements Paintable, ClickListener,
- FormHandler {
+public class VUpload extends FormPanel implements Paintable,
+ SubmitCompleteHandler, SubmitHandler {
+
+ private final class MyFileUpload extends FileUpload {
+ @Override
+ public void onBrowserEvent(Event event) {
+ super.onBrowserEvent(event);
+ if (event.getTypeInt() == Event.ONCHANGE) {
+ if (immediate && fu.getFilename() != null
+ && !"".equals(fu.getFilename())) {
+ submit();
+ }
+ } else if (event.getTypeInt() == Event.ONFOCUS) {
+ // IE and user has clicked on hidden textarea part of upload
+ // field. Manually open file selector, other browsers do it by
+ // default.
+ fireNativeClick(fu.getElement());
+ // also remove focus to enable hack if user presses cancel
+ // button
+ fireNativeBlur(fu.getElement());
+ }
+ }
+ }
public static final String CLASSNAME = "v-upload";
/**
* FileUpload component that opens native OS dialog to select file.
*/
- FileUpload fu = new FileUpload();
+ FileUpload fu = new MyFileUpload();
Panel panel = new FlowPanel();
@@ -56,18 +79,34 @@ public class VUpload extends FormPanel implements Paintable, ClickListener,
private boolean enabled = true;
+ private boolean immediate;
+
+ private Hidden maxfilesize = new Hidden();
+
public VUpload() {
super();
setEncoding(FormPanel.ENCODING_MULTIPART);
setMethod(FormPanel.METHOD_POST);
setWidget(panel);
+ panel.add(maxfilesize);
panel.add(fu);
submitButton = new Button();
- submitButton.addClickListener(this);
+ submitButton.setStyleName("v-button");
+ submitButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ if (immediate) {
+ // fire click on upload (eg. focused button and hit space)
+ fireNativeClick(fu.getElement());
+ } else {
+ submit();
+ }
+ }
+ });
panel.add(submitButton);
- addFormHandler(this);
+ addSubmitCompleteHandler(this);
+ addSubmitHandler(this);
setStyleName(CLASSNAME);
}
@@ -76,10 +115,12 @@ public class VUpload extends FormPanel implements Paintable, ClickListener,
if (client.updateComponent(this, uidl, true)) {
return;
}
+ setImmediate(uidl.getBooleanAttribute("immediate"));
this.client = client;
paintableId = uidl.getId();
setAction(client.getAppUri());
- submitButton.setText(uidl.getStringAttribute("buttoncaption"));
+ submitButton.setHTML("<span class=\"v-button-caption\">"
+ + uidl.getStringAttribute("buttoncaption") + "</span>");
fu.setName(paintableId + "_file");
if (uidl.hasAttribute("disabled") || uidl.hasAttribute("readonly")) {
@@ -87,16 +128,76 @@ public class VUpload extends FormPanel implements Paintable, ClickListener,
} else if (uidl.getBooleanAttribute("state")) {
enableUploaod();
}
+ }
+ private void setImmediate(boolean booleanAttribute) {
+ if (immediate != booleanAttribute) {
+ immediate = booleanAttribute;
+ if (immediate) {
+ fu.sinkEvents(Event.ONCHANGE);
+ fu.sinkEvents(Event.ONFOCUS);
+ }
+ }
+ setStyleName(getElement(), CLASSNAME + "-immediate", immediate);
}
- public void onClick(Widget sender) {
- submit();
+ private static native void fireNativeClick(Element element)
+ /*-{
+ element.click();
+ }-*/;
+
+ private static native void fireNativeBlur(Element element)
+ /*-{
+ element.blur();
+ }-*/;
+
+ protected void disableUpload() {
+ submitButton.setEnabled(false);
+ fu.setVisible(false);
+ enabled = false;
}
- public void onSubmit(FormSubmitEvent event) {
+ protected void enableUploaod() {
+ submitButton.setEnabled(true);
+ fu.setVisible(true);
+ enabled = true;
+ }
+
+ /**
+ * Re-creates file input field and populates panel. This is needed as we
+ * want to clear existing values from our current file input field.
+ */
+ private void rebuildPanel() {
+ panel.remove(submitButton);
+ panel.remove(fu);
+ fu = new MyFileUpload();
+ fu.setName(paintableId + "_file");
+ fu.setVisible(enabled);
+ panel.add(fu);
+ panel.add(submitButton);
+ if (immediate) {
+ fu.sinkEvents(Event.ONCHANGE);
+ }
+ }
+
+ public void onSubmitComplete(SubmitCompleteEvent event) {
+ if (client != null) {
+ if (t != null) {
+ t.cancel();
+ }
+ ApplicationConnection.getConsole().log("Submit complete");
+ client.sendPendingVariableChanges();
+ }
+
+ rebuildPanel();
+
+ submitted = false;
+ enableUploaod();
+ }
+
+ public void onSubmit(SubmitEvent event) {
if (fu.getFilename().length() == 0 || submitted || !enabled) {
- event.setCancelled(true);
+ event.cancel();
ApplicationConnection
.getConsole()
.log(
@@ -125,28 +226,4 @@ public class VUpload extends FormPanel implements Paintable, ClickListener,
t.schedule(800);
}
- protected void disableUpload() {
- submitButton.setEnabled(false);
- fu.setVisible(false);
- enabled = false;
- }
-
- protected void enableUploaod() {
- submitButton.setEnabled(true);
- fu.setVisible(true);
- enabled = true;
- }
-
- public void onSubmitComplete(FormSubmitCompleteEvent event) {
- if (client != null) {
- if (t != null) {
- t.cancel();
- }
- ApplicationConnection.getConsole().log("Submit complete");
- client.sendPendingVariableChanges();
- }
- submitted = false;
- enableUploaod();
- }
-
}
diff --git a/src/com/vaadin/tests/TestForStyledUpload.java b/src/com/vaadin/tests/TestForStyledUpload.java
new file mode 100644
index 0000000000..0e4933d2b9
--- /dev/null
+++ b/src/com/vaadin/tests/TestForStyledUpload.java
@@ -0,0 +1,288 @@
+/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.tests;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+
+import com.vaadin.Application;
+import com.vaadin.terminal.StreamResource;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Layout;
+import com.vaadin.ui.Link;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.ProgressIndicator;
+import com.vaadin.ui.Upload;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Upload.FailedEvent;
+import com.vaadin.ui.Upload.FailedListener;
+import com.vaadin.ui.Upload.FinishedEvent;
+import com.vaadin.ui.Upload.FinishedListener;
+import com.vaadin.ui.Upload.StartedEvent;
+import com.vaadin.ui.Upload.StartedListener;
+import com.vaadin.ui.Upload.SucceededEvent;
+import com.vaadin.ui.Upload.SucceededListener;
+
+public class TestForStyledUpload extends Application implements
+ Upload.FinishedListener, FailedListener, SucceededListener,
+ StartedListener {
+
+ Layout main = new VerticalLayout();
+
+ TmpFileBuffer buffer = new TmpFileBuffer();
+
+ Panel status = new Panel("Uploaded file:");
+
+ private final Upload up;
+
+ private final Label l;
+
+ private final Label transferred = new Label("");
+
+ private final ProgressIndicator pi = new ProgressIndicator();
+
+ private final Label memoryStatus;
+
+ public TestForStyledUpload() {
+ main
+ .addComponent(new Label(
+ "Clicking on button b updates information about upload components status or same with garbage collector."));
+
+ up = new Upload(null, buffer);
+ up.setButtonCaption("Select file");
+ up.setImmediate(true);
+ up.addListener((FinishedListener) this);
+ up.addListener((FailedListener) this);
+ up.addListener((SucceededListener) this);
+ up.addListener((StartedListener) this);
+
+ up.addListener(new Upload.ProgressListener() {
+
+ public void updateProgress(long readBytes, long contentLenght) {
+ pi.setValue(new Float(readBytes / (float) contentLenght));
+
+ refreshMemUsage();
+
+ transferred.setValue("Transferred " + readBytes + " of "
+ + contentLenght);
+ }
+
+ });
+
+ final Button b = new Button("Update status", this, "readState");
+
+ final Button c = new Button("Update status with gc", this, "gc");
+
+ main.addComponent(up);
+ l = new Label("Idle");
+ main.addComponent(l);
+
+ pi.setVisible(false);
+ pi.setPollingInterval(300);
+ main.addComponent(pi);
+ main.addComponent(transferred);
+
+ memoryStatus = new Label();
+ main.addComponent(memoryStatus);
+
+ status.setVisible(false);
+ main.addComponent(status);
+
+ Button cancel = new Button("Cancel current upload");
+ cancel.addListener(new Button.ClickListener() {
+ public void buttonClick(ClickEvent event) {
+ buffer.cancel();
+ }
+ });
+
+ main.addComponent(cancel);
+
+ final Button restart = new Button("Restart demo application");
+ restart.addListener(new Button.ClickListener() {
+
+ public void buttonClick(ClickEvent event) {
+ TestForStyledUpload.this.close();
+ }
+ });
+ main.addComponent(restart);
+ main.addComponent(b);
+ main.addComponent(c);
+
+ }
+
+ public void gc() {
+ Runtime.getRuntime().gc();
+ readState();
+ }
+
+ public void readState() {
+ final StringBuffer sb = new StringBuffer();
+
+ if (up.isUploading()) {
+ sb.append("Uploading...");
+ sb.append(up.getBytesRead());
+ sb.append("/");
+ sb.append(up.getUploadSize());
+ sb.append(" ");
+ sb.append(Math.round(100 * up.getBytesRead()
+ / (double) up.getUploadSize()));
+ sb.append("%");
+ } else {
+ sb.append("Idle");
+ }
+ l.setValue(sb.toString());
+ refreshMemUsage();
+ }
+
+ public void uploadFinished(FinishedEvent event) {
+ status.removeAllComponents();
+ final InputStream stream = buffer.getStream();
+ if (stream == null) {
+ status.addComponent(new Label(
+ "Upload finished, but output buffer is null!!"));
+ } else {
+ status
+ .addComponent(new Label("<b>Name:</b> "
+ + event.getFilename(), Label.CONTENT_XHTML));
+ status.addComponent(new Label("<b>Mimetype:</b> "
+ + event.getMIMEType(), Label.CONTENT_XHTML));
+ status.addComponent(new Label("<b>Size:</b> " + event.getLength()
+ + " bytes.", Label.CONTENT_XHTML));
+
+ status.addComponent(new Link("Download " + buffer.getFileName(),
+ new StreamResource(buffer, buffer.getFileName(), this)));
+
+ status.setVisible(true);
+ }
+ }
+
+ public interface Buffer extends StreamResource.StreamSource,
+ Upload.Receiver {
+
+ String getFileName();
+ }
+
+ public class TmpFileBuffer implements Buffer {
+ String mimeType;
+
+ String fileName;
+
+ private File file;
+
+ private FileInputStream stream;
+
+ public TmpFileBuffer() {
+ final String tempFileName = "upload_tmpfile_"
+ + System.currentTimeMillis();
+ try {
+ file = File.createTempFile(tempFileName, null);
+ } catch (final IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ public void cancel() {
+ up.interruptUpload();
+ }
+
+ public InputStream getStream() {
+ if (file == null) {
+ return null;
+ }
+ try {
+ stream = new FileInputStream(file);
+ return stream;
+ } catch (final FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * @see com.vaadin.ui.Upload.Receiver#receiveUpload(String, String)
+ */
+ public OutputStream receiveUpload(String filename, String MIMEType) {
+ fileName = filename;
+ mimeType = MIMEType;
+ try {
+ return new FileOutputStream(file);
+ } catch (final FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the fileName.
+ *
+ * @return String
+ */
+ public String getFileName() {
+ return fileName;
+ }
+
+ /**
+ * Returns the mimeType.
+ *
+ * @return String
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ }
+
+ public void uploadFailed(FailedEvent event) {
+ pi.setVisible(false);
+ l.setValue("Upload was interrupted");
+ }
+
+ public void uploadSucceeded(SucceededEvent event) {
+ pi.setVisible(false);
+ l.setValue("Finished upload, idle");
+ System.out.println(event);
+ }
+
+ private void refreshMemUsage() {
+ // memoryStatus.setValue("Not available in Java 1.4");
+ StringBuffer mem = new StringBuffer();
+ MemoryMXBean mmBean = ManagementFactory.getMemoryMXBean();
+ mem.append("Heap (M):");
+ mem.append(mmBean.getHeapMemoryUsage().getUsed() / 1048576);
+ mem.append(" | Non-Heap (M):");
+ mem.append(mmBean.getNonHeapMemoryUsage().getUsed() / 1048576);
+ memoryStatus.setValue(mem.toString());
+
+ }
+
+ public void uploadStarted(StartedEvent event) {
+ pi.setVisible(true);
+ l.setValue("Started uploading file " + event.getFilename());
+ }
+
+ @Override
+ public void init() {
+ Window w = new Window();
+ w.setTheme("runo");
+ w.addComponent(main);
+ setMainWindow(w);
+
+ }
+
+}
diff --git a/src/com/vaadin/ui/Upload.java b/src/com/vaadin/ui/Upload.java
index 70e16e1ded..cdea1e6ce3 100644
--- a/src/com/vaadin/ui/Upload.java
+++ b/src/com/vaadin/ui/Upload.java
@@ -4,6 +4,7 @@
package com.vaadin.ui;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
@@ -20,13 +21,16 @@ import com.vaadin.terminal.UploadStream;
/**
* Component for uploading files from client to server.
*
+ * <p>
* The visible component consists of a file name input box and a browse button
* and an upload submit button to start uploading.
*
+ * <p>
* The Upload component needs a java.io.OutputStream to write the uploaded data.
* You need to implement the Upload.Receiver interface and return the output
* stream in the receiveUpload() method.
*
+ * <p>
* You can get an event regarding starting (StartedEvent), progress
* (ProgressEvent), and finishing (FinishedEvent) of upload by implementing
* StartedListener, ProgressListener, and FinishedListener, respectively. The
@@ -34,10 +38,16 @@ import com.vaadin.terminal.UploadStream;
* to separate between these two cases, you can use SucceededListener
* (SucceededEvenet) and FailedListener (FailedEvent).
*
+ * <p>
* The upload component does not itself show upload progress, but you can use
* the ProgressIndicator for providing progress feedback by implementing
* ProgressListener and updating the indicator in updateProgress().
*
+ * <p>
+ * Setting upload component immediate initiates the upload as soon as a file is
+ * selected, instead of the common pattern of file selection field and upload
+ * button.
+ *
* @author IT Mill Ltd.
* @version
* @VERSION@
@@ -81,7 +91,9 @@ public class Upload extends AbstractComponent implements Component.Focusable {
* upload
*/
private ProgressListener progressListener;
- private LinkedHashSet progressListeners;
+ private LinkedHashSet<ProgressListener> progressListeners;
+
+ private boolean interrupted = false;
/* TODO: Add a default constructor, receive to temp file. */
@@ -169,6 +181,9 @@ public class Upload extends AbstractComponent implements Component.Focusable {
fireUpdateProgress(totalBytes, contentLength);
}
}
+ if (interrupted) {
+ throw new Exception("Upload interrupted by other thread");
+ }
}
// upload successful
@@ -182,8 +197,15 @@ public class Upload extends AbstractComponent implements Component.Focusable {
} catch (final Exception e) {
synchronized (application) {
// Download interrupted
+ try {
+ // still try to close output stream
+ out.close();
+ } catch (IOException e1) {
+ // NOP
+ }
fireUploadInterrupted(filename, type, totalBytes, e);
endUpload();
+ interrupted = false;
}
}
}
@@ -697,7 +719,7 @@ public class Upload extends AbstractComponent implements Component.Focusable {
*/
public void addListener(ProgressListener listener) {
if (progressListeners == null) {
- progressListeners = new LinkedHashSet();
+ progressListeners = new LinkedHashSet<ProgressListener>();
}
progressListeners.add(listener);
}
@@ -792,8 +814,9 @@ public class Upload extends AbstractComponent implements Component.Focusable {
// this is implemented differently than other listeners to maintain
// backwards compatibility
if (progressListeners != null) {
- for (Iterator it = progressListeners.iterator(); it.hasNext();) {
- ProgressListener l = (ProgressListener) it.next();
+ for (Iterator<ProgressListener> it = progressListeners.iterator(); it
+ .hasNext();) {
+ ProgressListener l = it.next();
l.updateProgress(totalBytes, contentLength);
}
}
@@ -881,12 +904,23 @@ public class Upload extends AbstractComponent implements Component.Focusable {
}
/**
+ * Interrupts the upload currently being received. The interruption will be
+ * done by the receiving tread so this method will return immediately and
+ * the actual interrupt will happen a bit later.
+ */
+ public void interruptUpload() {
+ if (isUploading) {
+ interrupted = true;
+ }
+ }
+
+ /**
* Go into state where new uploading can begin.
*
* Warning: this is an internal method used by the framework and should not
* be used by user of the Upload component.
*/
- public void endUpload() {
+ private void endUpload() {
isUploading = false;
contentLength = -1;
}
@@ -960,11 +994,17 @@ public class Upload extends AbstractComponent implements Component.Focusable {
}
/**
- * File uploads usually have button that starts actual upload progress. This
- * method is used to set text in that button.
+ * In addition to the actual file chooser, upload components have button
+ * that starts actual upload progress. This method is used to set text in
+ * that button.
+ *
+ * <p>
+ * <strong>Note</strong> the string given is set as is to the button. HTML
+ * formatting is not stripped. Be sure to properly validate your value
+ * according to your needs.
*
* @param buttonCaption
- * text for uploads button.
+ * text for upload components button.
*/
public void setButtonCaption(String buttonCaption) {
this.buttonCaption = buttonCaption;