Можно ли создать Java-апплет во время выполнения другого Java-приложения - PullRequest
4 голосов
/ 18 апреля 2011

Я занимаюсь разработкой Java-приложения, которое выполняет длинный ряд запросов и вычислений и представляет его результаты в виде серии HTML-страниц. Для визуализации графиков я какое-то время играл с библиотекой JUNG, и, похоже, реальная сила библиотеки - поддержка взаимодействия с пользователем, которая, конечно, недоступна, когда график сохраняется как статическое изображение (PNG в моем дело).

Мне было интересно, будет ли это:

а) возможно

б) выполнимо

в) разумный

... для создания апплета во время выполнения основного приложения, который затем может быть вставлен в отчеты HTML и может использоваться в интерактивном режиме после того, как приложение завершило выполнение и пользователь просматривает страницы отчета.

Если это невозможно по техническим причинам; У вас есть альтернативные рекомендации / предложения относительно того, как я могу достичь чего-то подобного?

Спасибо

РЕДАКТИРОВАТЬ: Просто чтобы прояснить концепцию, «основное» приложение является звеном в цепочке событий, и, следовательно, имеет такой отдельный GUI. Идея использования апплета заключается не в том, чтобы имитировать или переносить весь материал из основного приложения на HTML-страницу, а в том, чтобы сделать возможным использование интерактивных инструментов, поставляемых с библиотекой JUNG, когда пользователь просматривает графические результаты ПОСЛЕ выполнения основное программное обеспечение завершено.

Дайте мне знать, если концепция все еще довольно неясна, и я дам вторую попытку объяснить вещи более подробно.

ОБНОВЛЕНИЕ: Следуя полученным советам, благодаря @boffinBrain & @AndrewThompson я написал свой апплет и поместил его в пакет в своем проекте вместе с другими классами, связанными с визуализацией. Иерархия выглядит следующим образом:

my.domain.project
my.domain.project.tests
my.domain.project.visualization

Теперь отчеты HTML создаются в произвольном месте на локальном диске, это особенность, поскольку пользователь предоставляет выходную папку перед запуском «основного» приложения. В моем ReportGenerator классе (который генерирует эти HTML-файлы) у меня есть следующий фрагмент кода:

File bin = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toString());
String codebase = bin.getParent();
System.out.println(codebase);
String archive = "lib/collections-generic-4.01/collections-generic-4.01.jar";
String applet_name = "bin/my.domain.project.visualization.HierarchyGraphApplet.class";

codebase Распечатка показывает: file:/home/username/workspace/project, что является правильным, что я ожидал. Под папкой проекта есть bin / и lib /, а внутри bin - правильная иерархия папок вплоть до моего класса апплета, который также существует.

Теперь, почему я все это записал; хорошо, потому что, когда я пытаюсь запустить свой апплет на отчетах, я получаю:

java.lang.NoClassDefFoundError: bin/my/domain/project/visualization/HierarchyGraphApplet (wrong name: my/domain/project/visualization/HierarchyGraphApplet)

Я читал похожие вопросы, такие как: это или это , но кажется, что проблема в другом. Я дважды проверил орфографию и т.д ... Есть что-то простое, чего мне не хватает, или есть более сложная проблема под рукой?

Ответы [ 2 ]

3 голосов
/ 18 апреля 2011

Может быть, этот пример даст вам некоторые идеи для продолжения. Он создает файлы данных, используемые в качестве «отчетов» для использования апплетами.

Поскольку апплет получает данные через входной файл, заголовок которого указан в апплете param. Содержимое файла данных ограничено только требованиями отчета, вашим умением его создавать и анализировать, ... и доступным дисковым пространством. ;)

Скомпилируйте и запустите main(String[]), чтобы (надеюсь) увидеть 2 веб-страницы, открытые во вкладках вашего браузера.

import java.awt.Desktop;
import javax.swing.*;
import java.net.*;
import java.io.*;

/** Simplistic example, not intended to show good I/O practices
or Exception handling for the sake of brevity. */
public class Reporter extends JApplet {

    public void init() {
        String input = getParameter("input");

        JEditorPane report = new JEditorPane();
        report.setText("Problem loading input file");
        add(report);

        URL url;
        try {
            url = new URL(getDocumentBase(), input);
            report.setPage(url);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    /** The main represents our report generator.  It is part
    of the applet class only in order to create an SSCCE. Good
    design would imply that it might be in a class ReportGenerator,
    while the applet is in class ReportViewer. */
    public static void main(String[] args) throws Exception {
        File f;
        String title = "1";
        String data = "apples";

        createInput(title, data);
        f = createHTML(title);
        Desktop.getDesktop().browse(f.toURI());

        title = "2";
        data = "oranges";

        createInput(title, data);
        f = createHTML(title);
        Desktop.getDesktop().browse(f.toURI());

        System.out.println( "End of report generation.." );
    }

    public static void createInput(String title, String data) throws Exception {
        File f = new File("data" + title + ".txt");
        PrintWriter pw = new PrintWriter(f);
        pw.println(data);

        pw.flush();
        pw.close();
    }

    public static File createHTML(String title) throws Exception {
        File f = new File("Data" + title + ".html");
        PrintWriter pw = new PrintWriter(f);

        pw.println("<html>");
        pw.println("<title>");
        pw.println("Data " + title);
        pw.println("<title>");
        pw.println("<body>");
        pw.println("<h1>");
        pw.println("Data " + title);
        pw.println("</h1>");
        pw.println("<applet ");
        pw.println("code='Reporter'");
        pw.println("width='400'");
        pw.println("height='400'");
        pw.println(">");
        pw.println("<param name='input' value='data" + title + ".txt'>");
        pw.println("</applet>");
        pw.println("</body>");
        pw.println("</html>");

        pw.flush();
        pw.close();

        return f;
    }
}

По дальнейшим вопросам:

.. предполагает ли данный код, что HTML-отчеты и апплет находятся в одной папке?

Не обязательно. Параметр input может указывать ../other/data3.txt для каталога other на том же уровне, что и каталог HTML, или /reports/data3.txt для каталога reports в корне сайта.

.. Как вы также заметили, в реальном примере код для апплета, скорее всего, был бы в своем собственном классе, что создавало бы какие-либо сложности с тем, как он будет включен в HTML-файлы (которые генерируется в отдельном классе с именем ReportGenerator)?

Потребуются лишь незначительные изменения, чтобы указать на applet.jar в отличие от application.jar. Используйте codebase для отделения HTML от каталога applet.jar (хотя к архивам также можно обращаться через относительные или абсолютные URL).

2 голосов
/ 18 апреля 2011

Определенно возможно создать апплет для отображения данных, но вы не хотите динамически генерировать новый каждый раз. Вы хотите создать отдельный автономный апплет, который может генерировать ваши графики / отчеты из набора входных данных в текстовом формате, а затем при создании страницы HTML предоставлять данные отчета с помощью параметра апплета (с использованием тега PARAM). ).

...