при загрузке ресурса в приложении Java Webstart обычно отображается окно прогресса загрузки, в котором отображается ход загрузки.Если это окно является окном хода выполнения по умолчанию, оно имеет кнопку отмены.Я в основном пытаюсь реализовать эту кнопку отмены в пользовательском окне прогресса загрузки.
Поскольку нет способа, который вы могли бы вызвать, чтобы отменить загрузку, я попытался выяснить, как это было сделано в ходе выполнения по умолчанию.окно.Из-за реализации с ServiceManager немного сложно найти реальную реализацию.Но я наконец нашел это: [jdk-source на googlecode (DownloadServiceImpl)] .
Когда вы будете искать «отмена» или просто прокрутите вниз до метода выполнения, вы увидите, что это должно быть так же просто, как и генерирование RuntimeException.К сожалению, это на самом деле не работает.Это просто останавливает метод прогресса от вызова.Ресурс по-прежнему загружается в фоновом режиме, и метод loadPart никогда не возвращается.
Если вы хотите попробовать это сами, я подготовил небольшой пример.Вам понадобится какой-то веб-сервер (хотя локального веб-сервера вполне достаточно).Я пробовал это на Windows XP (32-разрядной) с Java 1.6.0_21 (и Apache Tomcat 6).
Простой файл jnlp будет выглядеть так (вы, вероятно, захотите изменить порт):
<?xml version="1.0" encoding="utf-8"?>
<jnlp
spec="1.0+"
codebase="http://127.0.0.1:8080/DownloadTest"
href="DownloadTest.jnlp"
version="1.0">
<information>
<title>DownloadTest</title>
<vendor>Download Tester</vendor>
</information>
<resources os="Windows">
<java version="1.6.0_18+" href="http://java.sun.com/products/autodl/j2se" />
<jar href="DownloadTest.jar" main="true"/>
<jar href="largeResource.jar" download="lazy" part="One"/>
</resources>
<application-desc main-class="downloadtest.Main">
</application-desc>
</jnlp>
Далее вам потребуется большой файл в качестве ресурса (содержимое не имеет значения ввсе).Например, на многих компьютерах с Windows вы найдете «driver.cab» в «Windows \ Driver Cache \ i386».Файл должен быть добавлен в архив jar (jar -cf largeResource.jar <input file>
).
Основная программа выглядит следующим образом (вам нужно включить jnlp.jar в качестве lib, который вы можете найти по адресу <jdk_home>\sample\jnlp\servlet
):
package downloadtest;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.jnlp.DownloadService;
import javax.jnlp.DownloadServiceListener;
import javax.jnlp.ServiceManager;
import javax.jnlp.UnavailableServiceException;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
public class Main {
private static DownloadService downloadService;
private static DownloadServiceListener customDownloadWindow;
static {
try {
downloadService = (DownloadService) ServiceManager.lookup("javax.jnlp.DownloadService");
} catch (UnavailableServiceException ex) {
System.err.println("DownloadService not available.");
}
customDownloadWindow = new CustomProgress();
}
public static void main(String[] args) {
JFrame frame = new JFrame("DownloadTest");
frame.setBounds(0, 0, 200, 100);
frame.setDefaultCloseOperation(JDialog.EXIT_ON_CLOSE);
frame.setLayout(null);
JButton startDownload = new JButton("download");
startDownload.setBounds(20, 20, 150, 40);
startDownload.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() {
try {
downloadService.loadPart("One", customDownloadWindow);
//downloadService.loadPart("One", downloadService.getDefaultProgressWindow());
} catch (IOException ex) {
ex.printStackTrace();
System.err.println("IOException loadPart.");
}
return null;
}
}.execute();
}
});
frame.add(startDownload);
frame.setVisible(true);
}
}
Вы можете попробовать каждое окно прогресса загрузкираскомментировав одну строку «downloadService.loadPart ...» и закомментировав другую.
И, наконец, собственно собственное окно прогресса:
package downloadtest;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.jnlp.DownloadServiceListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
public class CustomProgress implements DownloadServiceListener {
JFrame frame = null;
JProgressBar progressBar = null;
boolean uiCreated = false;
boolean canceled = false;
public CustomProgress() {
}
private void create() {
JPanel top = createComponents();
frame = new JFrame(); // top level custom progress indicator UI
frame.getContentPane().add(top, BorderLayout.CENTER);
frame.setBounds(300,300,400,300);
frame.pack();
updateProgressUI(0);
}
private JPanel createComponents() {
JPanel top = new JPanel();
top.setBackground(Color.WHITE);
top.setLayout(new BorderLayout(20, 20));
String lblText = "<html><font color=green size=+2>JDK Documentation</font>" +
"<br/> The one-stop shop for Java enlightenment! <br/></html>";
JLabel lbl = new JLabel(lblText);
top.add(lbl, BorderLayout.NORTH);
progressBar = new JProgressBar(0, 100);
progressBar.setValue(0);
progressBar.setStringPainted(true);
top.add(progressBar, BorderLayout.CENTER);
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
CustomProgress.this.canceled = true;
}
});
top.add(cancelButton, BorderLayout.SOUTH);
return top;
}
public void progress(URL url, String version, long readSoFar,
long total, int overallPercent) {
updateProgressUI(overallPercent);
}
public void upgradingArchive(java.net.URL url,
java.lang.String version,
int patchPercent,
int overallPercent) {
updateProgressUI(overallPercent);
}
public void validating(java.net.URL url,
java.lang.String version,
long entry,
long total,
int overallPercent) {
updateProgressUI(overallPercent);
}
public void downloadFailed(URL url, String string) {
System.err.println("Download failed");
}
private void updateProgressUI(int overallPercent) {
if (overallPercent > 0 && overallPercent < 99) {
if (!uiCreated) {
uiCreated = true;
// create custom progress indicator's UI only if
// there is more work to do, meaning overallPercent > 0 and < 100
// this prevents flashing when RIA is loaded from cache
create();
}
progressBar.setValue(overallPercent);
if (canceled) {
throw new RuntimeException("canceled by user");
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setVisible(true);
}
});
} else {
// hide frame when overallPercent is above 99
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (frame != null) {
frame.setVisible(false);
frame.dispose();
}
}
});
}
}
}
Это в основном взято из руководства Oracle(http://download.oracle.com/javase/tutorial/deployment/webstart/customProgressIndicatorForAppln.html). Я только что добавил кнопку отмены.
Когда вы создадите этот файл в виде jar-файла и поместите его вместе с largeResource.jar и DownloadTest.jnlp в общую папку вашего веб-сервера, вы сможетечтобы запустить приложение через веб-браузер. Затем нажмите кнопку загрузки и, прежде чем она будет завершена, нажмите кнопку отмены в окне загрузки. После того, как вы попробуете пользовательское окно прогресса, вам нужно будет удалить приложение (или только ресурс) из вашей Javaкеш (поскольку ресурс загружается в фоновом режиме независимо от нажатия кнопки отмены).
Итак, почему яэто работает с окном прогресса по умолчанию, но не с пользовательским окном прогресса?Есть ли простая возможность отменить загрузку с помощью специального окна загрузки?
Любая помощь или полезные советы приветствуются.
Drax