I have been developing a Java application which executes a long series of queries and calculations, and presents its results as a series of HTML pages. For visualizing graphs I have been playing around with JUNG library for a while, and it appears as the real strength of the library is the support for user interaction, which is of course unavailable when the graph is saved as a static image (PNG in my case).
I was wondering if it would be:
a) possible
b) feasible
c) sensible
... to create an applet, during execution of the main application, which then can be insert to the HTML reports and can be used interactively after the application has finished execution and the user goes through the report pages.
If this is not possible due to technical reasons; do you have any alternative recommendations/ suggestions as to how I can achieve something like this?
Thanks,
EDIT: Just to clarify the concept, the "main" application is a link in a chain of events, and thus has so separate GUI. The idea with the applet is NOT to mimic or transport all the stuff from the main app to a HTML page, but to make it possible to use interactive tools that come with JUNG library, when the user is reviewing the graphical results AFTER the execution of the main software has finished.
Let me know if the concept is still rather unclear and I'll give a second attempt to explain things in further detail.
UPDATE: Following the advices I got, thnx to @boffinBrain & @AndrewThompson, I wrote my applet, and placed in a package in my project along with other visualization related classes. The hierarchy is as follows:
my.domain.project
my.domain.project.tests
my.domain.project.visualization
Now the HTML reports are created at an arbitrary location on the local drive, this is a feature as the user gives an output folder prior to running the "main" application. In my ReportGenerator
class (which generates these HTML files) I have the following bit of code:
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
printout shows: file:/home/username/workspace/project
which is correct what I'd expected. Under the project folder there's bin/ and lib/, and inside bin there is the right hierarchy of folders all the way down to my applet class which also exists.
Now why did I write all this down; well because when I try to run my applet on the reports I get:
java.lang.NoClassDefFoundError: bin/my/domain/project/visualization/HierarchyGraphApplet (wrong name: my/domain/project/visualization/HierarchyGraphApplet)
I have read similar questions like: this or this but it seems like the problem is somewhere else. I double checked the spelling etc... Is there something simple I am missing, or is there a more complicated problem at hand?
Maybe this example will give you some ideas to pursue. It creates data files used as 'reports' for consumption by the applet(s).
Because the applet gains the data via an input file whose title is specified in an applet param
. The content of the data file is only limited by the requirements of the report, your skill to create it & parse it, ..and available disk space. ;)
Compile & run the main(String[])
to (hopefully) see 2 web pages open in tabs of your browser.
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;
}
}
In relation to further questions:
..does the given code assume that the html reports and the applet are located in the same folder?
Not necessarily. The input
parameter might specify ../other/data3.txt
for the other
directory at the same level as the one contained by the HTML
, or /reports/data3.txt
for a reports
directory at the root of the site.
..As you have also noted, in a real-life example the code for the applet would most likely be in its own class, would that pose any complications as to how it would be incorporated into the html files (which are generated in a separate class, named ReportGenerator)?
It would require only slight changes to point to the applet.jar
as opposed to the application.jar
. Use a codebase
to separate the HTML
from the directory of the applet.jar
(though archives can also be accessed via relative or absolute URLs).