PDF PrinterJob get Job status - java

I have an issue to print a PDF using java. I know that Java doesn't support print PDF natively cause java doesn't have a PDF renderer. So to solve this problem I'm using a PDFRenderer library and here is an example for printing with it:
File f = new File("myfile.pdf");
FileInputStream fis = new FileInputStream(f);
FileChannel fc = fis.getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0,
fc.size());
PDFFile pdfFile = new PDFFile(bb);
PDFPrintPage pages = new PDFPrintPage(pdfFile);
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
pjob.setJobName(f.getName());
pjob.setPrintService(mPrintService);
Book book = new Book();
book.append(pages, pf, pdfFile.getNumPages());
pjob.setPageable(book);
pjob.print();
It works fine, but I need some way to get status of my printer job. I need to know when my printer job was finished that I can start another. Java API has a good solution with DocPrintJob and PrintJobListener but I need to use PrinterJob for my PDF printing. So how I can listen the job status from my PrinterJob like it does in DocPrintJob?

javafx.print
Enum PrinterJob.JobStatus
java.lang.Object
java.lang.Enum<PrinterJob.JobStatus>
javafx.print.PrinterJob.JobStatus
public static PrinterJob.JobStatus[] values()
Returns an array containing the constants of this enum type, in the order they are declared. This method may be used to iterate over the constants as follows:
for (PrinterJob.JobStatus c : PrinterJob.JobStatus.values())
System.out.println(c);

For anyone dealing with this problem here in 2020, I found a pretty slick way of printing PDF files while being able to monitor the print job, without using JavaFX - as people don't seem to be too hip on using JavaFX for printing PDF files, and I'm not to keen on object node printing, as it is really diffiult to get the print out to look like a normal document in my opinion ... JavaFX seems to like the idea of - basically - screen shotting a portion of your form, then rendering that snap shot as a graphic, then you have to scale it for the printer and it just ends up looking kinda weird ... whereas taking something like nicely formatted HTML, and printing it through a PDF library is really clean, and really fast. So here is what I found:
First, I used this library, which is free, to render my HTML String into a PDF file. Here is the Maven source for the library:
<dependency>
<groupId>org.icepdf.os</groupId>
<artifactId>icepdf-core</artifactId>
<version>6.2.2</version>
</dependency>
And here is my code for rendering the PDF:
String docPath = "/Users/michael/Documents/JavaFile.pdf";
String html = "<html>Any HTML Code you want, including embedded CSS for a really clean look</html>
OutputStream outputStream = new FileOutputStream(docPath);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(outputStream);
outputStream.close();
And here is my class for printing the PDF ... its a little lengthy, but VERY simple, and it uses native Java API which is nice (i'm using 1.8):
import javafx.application.Platform;
import javafx.scene.control.Label;
import java.io.*;
import javax.print.*;
import javax.print.event.PrintJobAdapter;
import javax.print.event.PrintJobEvent;
public class PrintHandler {
private void delay(int msec) {
try {
Thread.sleep(msec);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public PrintHandler (FileInputStream fis, Label statusLabel) {
this.statusLabel = statusLabel;
this.fis = fis;
}
private FileInputStream fis;
private Label statusLabel;
private String state;
public void startPrintJob () {
try {
Platform.runLater(()->statusLabel.setText("PRINTING"));
delay(5000);
InputStream is = new BufferedInputStream(this.fis);
DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob printJob = service.createPrintJob();
JobMonitor monitor = new JobMonitor();
printJob.addPrintJobListener(monitor);
Doc doc = new SimpleDoc(is, flavor, null);
printJob.print(doc, null);
monitor.waitForJobCompletion();
is.close();
} catch (PrintException | IOException e) {
e.printStackTrace();
}
}
private class JobMonitor extends PrintJobAdapter {
private boolean notify = false;
final int DATA_TRANSFERRED = 10;
final int JOB_COMPLETE = 11;
final int JOB_FAILED = 12;
final int JOB_CANCELED = 13;
final int JOB_NO_MORE_EVENTS = 14;
final int JOB_NEEDS_ATTENTION = 15;
private int status;
#Override
public void printDataTransferCompleted(PrintJobEvent pje) {
status = DATA_TRANSFERRED;
markAction();
}
#Override
public void printJobCompleted(PrintJobEvent pje) {
status = JOB_COMPLETE;
markAction();
}
#Override
public void printJobFailed(PrintJobEvent pje) {
status = JOB_FAILED;
markAction();
}
#Override
public void printJobCanceled(PrintJobEvent pje) {
status = JOB_CANCELED;
markAction();
}
#Override
public void printJobNoMoreEvents(PrintJobEvent pje) {
status = JOB_NO_MORE_EVENTS;
markAction();
}
#Override
public void printJobRequiresAttention(PrintJobEvent pje) {
status = JOB_NEEDS_ATTENTION;
markAction();
}
private void markAction() {
synchronized (JobMonitor.this) {
notify = true;
JobMonitor.this.notify();
}
}
public synchronized void waitForJobCompletion() {
Runnable runner = ()->{
boolean keepRunning = true;
while (keepRunning) {
try {
while (!notify) {
wait();
}
switch(this.status){
case DATA_TRANSFERRED:
state = "DATA_TRANSFERRED";
break;
case JOB_COMPLETE:
state = "JOB_FINISHED";
keepRunning = false;
break;
case JOB_FAILED:
state = "JOB_FAILED";
keepRunning = false;
break;
case JOB_CANCELED:
state = "JOB_CANCELED";
keepRunning = false;
break;
case JOB_NO_MORE_EVENTS:
state = "JOB_COMPLETE";
keepRunning = false;
break;
case JOB_NEEDS_ATTENTION:
state = "JOB_NEEDS_ATTENTION";
break;
}
Platform.runLater(()->statusLabel.setText(state));
delay(5000);
notify = false;
}
catch (InterruptedException e) {}
}
delay(5000);
Platform.runLater(()->statusLabel.setText(""));
};
Thread monitor = new Thread(runner);
monitor.start();
}
}
}
And here is how I invoke the class to print and monitor the job:
FileInputStream fis = new FileInputStream(docPath);
Label jobStatus = new Label(); //Already in my AnchorPane but included here for clarity
new PrintHandler(fis,jobStatus).startPrintJob();

Related

Not able to read individual page using PDFTextStripper with multiple threads

I am able to create 10 threads. But the problem is when I try to access individual page using those threads in parallel style. I have tried putting the private static PDFTextStripper instance into synchronized block as well. Still I get below exception:
COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?
trying to print first word from each page for first 10 pages, but its not working. This is my first experiment with Multithreading and PDF reading. Any help would be much appreciated.
public class ReadPDFFile extends Thread implements FileInstance {
private static String fileLocation;
private static String fileNameIV;
private static String userInput;
private static int userConfidence;
private static int totalPages;
private static ConcurrentHashMap<Integer, List<String>> map = null;
private Iterator<PDDocument> iteratorForThisDoc;
private PDFTextStripperByArea text;
private static PDFTextStripper pdfStrip = null;
private static PDFParser pdParser = null;
private Splitter splitter;
private static int counter=0;
private StringWriter writer;
private static ReentrantLock counterLock = new ReentrantLock(true);
private static PDDocument doc;
private static PDDocument doc2;
private static boolean flag = false;
List<PDDocument> listOfPages;
ReadPDFFile(String filePath, String fileName, String userSearch, int confidence) throws FileNotFoundException{
fileLocation= filePath;
fileNameIV = fileName;
userInput= userSearch;
userConfidence = confidence;
System.out.println("object created");
}
#Override
public void createFileInstance(String filePath, String fileName) {
List<String> list = new ArrayList<String>();
map = new ConcurrentHashMap<Integer, List<String>>();
try(PDDocument document = PDDocument.load(new File(filePath))){
doc = document;
pdfStrip = new PDFTextStripper();
this.splitter = new Splitter();
text = new PDFTextStripperByArea();
document.getClass();
if(!document.isEncrypted()) {
totalPages = document.getNumberOfPages();
System.out.println("Number of pages in this book "+totalPages);
listOfPages = splitter.split(document);
iteratorForThisDoc = listOfPages.iterator();
}
this.createThreads();
/*
* for(int i=0;i<1759;i++) { readThisPage(i, pdfStrip); } flag= true;
*/
}
catch(IOException ie) {
ie.printStackTrace();
}
}
public void createThreads() {
counter=1;
for(int i=0;i<=9;i++) {
ReadPDFFile pdf = new ReadPDFFile();
pdf.setName("Reader"+i);
pdf.start();
}
}
public void run() {
try {
while(counter < 10){
int pgNum= pageCounterReentrant();
readThisPage(pgNum, pdfStrip);
}
doc.close();
}catch(Exception e) {
}
flag= true;
}
public static int getCounter() {
counter= counter+1;
return counter;
}
public static int pageCounterReentrant() {
counterLock.lock();
try {
counter = getCounter();
} finally {
counterLock.unlock();
}
return counter;
}
public static void readThisPage(int pageNum, PDFTextStripper ts) {
counter++;
System.out.println(Thread.currentThread().getName()+" reading page: "+pageNum+", counter: "+counter);
synchronized(ts){
String currentpageContent= new String();
try {
ts.setStartPage(pageNum);
ts.setEndPage(pageNum);
System.out.println("-->"+ts.getPageEnd());
currentpageContent = ts.getText(doc);
currentpageContent = currentpageContent.substring(0, 10);
System.out.println("\n\n "+currentpageContent);
}
/*
* further operations on currentpageContent here
*/
catch(IOException io) {
io.printStackTrace();
}finally {
}
}
}
public static void printFinalResult(ConcurrentHashMap<Integer, List<String>> map) {
/*
* simply display content of ConcurrentHashMap
*/
}
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(System.in);
System.out.println("Search Word");
userInput = sc.nextLine();
System.out.println("Confidence");
userConfidence = sc.nextInt();
ReadPDFFile pef = new ReadPDFFile("file path", "file name",userInput, userConfidence);
pef.createFileInstance("file path ","file name");
if(flag==true)
printFinalResult(map);
}
}
If I read each page in a for loop sequentially using one thread then it is able to print the content, but not with multithreads. You can see that code commented in void createFileInstance(), after this.createThreads(); I wish to get string content of each pdf page individually, using threads, and then perform operation on it. I have the logic to collect each word token into List but before moving ahead, I need to solve this problem.
Your code looks like this:
try(PDDocument document = PDDocument.load(new File(filePath))){
doc = document;
....
this.createThreads();
} // document gets closed here
...
//threads that do text extraction still running here (and using a closed object)
These threads use doc to extract the text (ts.getText(doc)). However at this time, the PDDocument object is already closed due to the usage of try-with-resources, and its streams also closed. Thus the error message "Perhaps its enclosing PDDocument has been closed?".
You should create the thread before closing the document, and waiting for all threads to finish before closing it.
I'd advise against using multithreading on one PDDocument, see PDFBOX-4559. You could create several PDDocuments and then extract on these, or not do it at all. Text extraction works pretty fast in PDFBox (compared to rendering).

Printing plain text files to PDF printer using javax.print results in an empty file

I need to create a pdf file from plain text files. I supposed that the simplest method would be read these files and print them to a PDF printer.
My problem is that if I print to a pdf printer, the result will be an empty pdf file. If I print to Microsoft XPS Document Writer, the file is created in plain text format, not in oxps format.
I would be satisfied with a two or three step solution. (Eg. converting to xps first then to pdf using ghostscript, or something similar).
I have tried a couple of pdf printers such as: CutePDF, Microsoft PDF writer, Bullzip PDF. The result is the same for each one.
The environment is Java 1.7/1.8 Win10
private void print() {
try {
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
PrintRequestAttributeSet patts = new HashPrintRequestAttributeSet();
PrintService[] ps = PrintServiceLookup.lookupPrintServices(flavor, patts);
if (ps.length == 0) {
throw new IllegalStateException("No Printer found");
}
System.out.println("Available printers: " + Arrays.asList(ps));
PrintService myService = null;
for (PrintService printService : ps) {
if (printService.getName().equals("Microsoft XPS Document Writer")) { //
myService = printService;
break;
}
}
if (myService == null) {
throw new IllegalStateException("Printer not found");
}
myService.getSupportedDocFlavors();
DocPrintJob job = myService.createPrintJob();
FileInputStream fis1 = new FileInputStream("o:\\k\\t1.txt");
Doc pdfDoc = new SimpleDoc(fis1, DocFlavor.INPUT_STREAM.AUTOSENSE, null);
HashPrintRequestAttributeSet pr = new HashPrintRequestAttributeSet();
pr.add(OrientationRequested.PORTRAIT);
pr.add(new Copies(1));
pr.add(MediaSizeName.ISO_A4);
PrintJobWatcher pjw = new PrintJobWatcher(job);
job.print(pdfDoc, pr);
pjw.waitForDone();
fis1.close();
} catch (PrintException ex) {
Logger.getLogger(Docparser.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {
Logger.getLogger(Docparser.class.getName()).log(Level.SEVERE, null, ex);
}
}
class PrintJobWatcher {
boolean done = false;
PrintJobWatcher(DocPrintJob job) {
job.addPrintJobListener(new PrintJobAdapter() {
public void printJobCanceled(PrintJobEvent pje) {
allDone();
}
public void printJobCompleted(PrintJobEvent pje) {
allDone();
}
public void printJobFailed(PrintJobEvent pje) {
allDone();
}
public void printJobNoMoreEvents(PrintJobEvent pje) {
allDone();
}
void allDone() {
synchronized (PrintJobWatcher.this) {
done = true;
System.out.println("Printing done ...");
PrintJobWatcher.this.notify();
}
}
});
}
public synchronized void waitForDone() {
try {
while (!done) {
wait();
}
} catch (InterruptedException e) {
}
}
}
If you can install LibreOffice, it is possible to use the Java UNO API to do this.
There is a similar example here which will load and save a file: Java Convert Word to PDF with UNO. This could be used to convert your text file to PDF.
Alternatively, you could take the text file and send it directly to the printer using the same API.
The following JARs give access to the UNO API. Ensure these are in your class path:
[Libre Office Dir]/URE/java/juh.jar
[Libre Office Dir]/URE/java/jurt.jar
[Libre Office Dir]/URE/java/ridl.jar
[Libre Office Dir]/program/classes/unoil.jar
[Libre Office Dir]/program
The following code will then take your sourceFile and print to the printer named "Local Printer 1".
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.sun.star.beans.PropertyValue;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.view.XPrintable;
public class DirectPrintTest
{
public static void main(String args[])
{
// set to the correct name of your printers
String printer = "Local Printer 1";// "Microsoft Print to PDF";
File sourceFile = new File("c:/projects/WelcomeTemplate.doc");
if (!sourceFile.canRead()) {
throw new RuntimeException("Can't read:" + sourceFile.getPath());
}
com.sun.star.uno.XComponentContext xContext = null;
try {
// get the remote office component context
xContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
System.out.println("Connected to a running office ...");
// get the remote office service manager
com.sun.star.lang.XMultiComponentFactory xMCF = xContext
.getServiceManager();
Object oDesktop = xMCF.createInstanceWithContext(
"com.sun.star.frame.Desktop", xContext);
com.sun.star.frame.XComponentLoader xCompLoader = (XComponentLoader) UnoRuntime
.queryInterface(com.sun.star.frame.XComponentLoader.class,
oDesktop);
StringBuffer sUrl = new StringBuffer("file:///");
sUrl.append(sourceFile.getCanonicalPath().replace('\\', '/'));
List<PropertyValue> loadPropsList = new ArrayList<PropertyValue>();
PropertyValue pv = new PropertyValue();
pv.Name = "Hidden";
pv.Value = Boolean.TRUE;
loadPropsList.add(pv);
PropertyValue[] loadProps = new PropertyValue[loadPropsList.size()];
loadPropsList.toArray(loadProps);
// Load a Writer document, which will be automatically displayed
com.sun.star.lang.XComponent xComp = xCompLoader
.loadComponentFromURL(sUrl.toString(), "_blank", 0,
loadProps);
// Querying for the interface XPrintable on the loaded document
com.sun.star.view.XPrintable xPrintable = (XPrintable) UnoRuntime
.queryInterface(com.sun.star.view.XPrintable.class, xComp);
// Setting the property "Name" for the favoured printer (name of
// IP address)
com.sun.star.beans.PropertyValue propertyValue[] = new com.sun.star.beans.PropertyValue[2];
propertyValue[0] = new com.sun.star.beans.PropertyValue();
propertyValue[0].Name = "Name";
propertyValue[0].Value = printer;
// Setting the name of the printer
xPrintable.setPrinter(propertyValue);
propertyValue[0] = new com.sun.star.beans.PropertyValue();
propertyValue[0].Name = "Wait";
propertyValue[0].Value = Boolean.TRUE;
// Printing the loaded document
System.out.println("sending print");
xPrintable.print(propertyValue);
System.out.println("closing doc");
((com.sun.star.util.XCloseable) UnoRuntime.queryInterface(
com.sun.star.util.XCloseable.class, xPrintable))
.close(true);
System.out.println("closed");
System.exit(0);
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(1);
}
}
}
Thank you for all. After two days struggling with various type of printers (I gave a chance to CUPS PDF printer too but I could not make it to print in landscape mode) I ended up using the Apache PDFbox.
It's only a POC solution but works and fits to my needs. I hope it will be useful for somebody.
( cleanTextContent() method removes some ESC control characters from the line to be printed. )
public void txt2pdf() {
float POINTS_PER_INCH = 72;
float POINTS_PER_MM = 1 / (10 * 2.54f) * POINTS_PER_INCH;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:m.ss");
PDDocument doc = null;
try {
doc = new PDDocument();
PDPage page = new PDPage(new PDRectangle(297 * POINTS_PER_MM, 210 * POINTS_PER_MM));
doc.addPage(page);
PDPageContentStream content = new PDPageContentStream(doc, page);
//PDFont pdfFont = PDType1Font.HELVETICA;
PDFont pdfFont = PDTrueTypeFont.loadTTF(doc, new File("c:\\Windows\\Fonts\\lucon.ttf"));
float fontSize = 10;
float leading = 1.1f * fontSize;
PDRectangle mediabox = page.getMediaBox();
float margin = 20;
float startX = mediabox.getLowerLeftX() + margin;
float startY = mediabox.getUpperRightY() - margin;
content.setFont(pdfFont, fontSize);
content.beginText();
content.setLeading(leading);
content.newLineAtOffset(startX, startY);
BufferedReader fis1 = new BufferedReader(new InputStreamReader(new FileInputStream("o:\\k\\t1.txt"), "cp852"));
String inString;
//content.setRenderingMode(RenderingMode.FILL_STROKE);
float currentY = startY + 60;
float hitOsszesenOffset = 0;
int pageNumber = 1;
while ((inString = fis1.readLine()) != null) {
currentY -= leading;
if (currentY <= margin) {
content.newLineAtOffset(0, (mediabox.getLowerLeftX()-35));
content.showText("Date Generated: " + dateFormat.format(new Date()));
content.newLineAtOffset((mediabox.getUpperRightX() / 2), (mediabox.getLowerLeftX()));
content.showText(String.valueOf(pageNumber++)+" lap");
content.endText();
float yCordinate = currentY+30;
float sX = mediabox.getLowerLeftY()+ 35;
float endX = mediabox.getUpperRightX() - 35;
content.moveTo(sX, yCordinate);
content.lineTo(endX, yCordinate);
content.stroke();
content.close();
PDPage new_Page = new PDPage(new PDRectangle(297 * POINTS_PER_MM, 210 * POINTS_PER_MM));
doc.addPage(new_Page);
content = new PDPageContentStream(doc, new_Page);
content.beginText();
content.setFont(pdfFont, fontSize);
content.newLineAtOffset(startX, startY);
currentY = startY;
}
String ss = new String(inString.getBytes(), "UTF8");
ss = cleanTextContent(ss);
if (!ss.isEmpty()) {
if (ss.contains("JAN") || ss.contains("SUMMARY")) {
content.setRenderingMode(RenderingMode.FILL_STROKE);
}
content.newLineAtOffset(0, -leading);
content.showText(ss);
}
content.setRenderingMode(RenderingMode.FILL);
}
content.newLineAtOffset((mediabox.getUpperRightX() / 2), (mediabox.getLowerLeftY()));
content.showText(String.valueOf(pageNumber++));
content.endText();
fis1.close();
content.close();
doc.save("o:\\k\\t1.pdf");
} catch (IOException ex) {
Logger.getLogger(Document_Creation.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (doc != null) {
try {
doc.close();
} catch (IOException ex) {
Logger.getLogger(Document_Creation.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}

Why isn't this multithreaded code faster?

This is my java code. Before, it calls BatchGenerateResult sequentially which is a lengthy process, but I want to try some multithreading and have each one of them run at the same time. However when I test it, the new time is the same as the old time. I expected the new time to be faster. Does anyone know whats wrong?
public class PlutoMake {
public static String classDir;
public static void main(String[] args) throws JSONException, IOException,
InterruptedException {
// determine path to the class file, I will use it as current directory
String classDirFile = PlutoMake.class.getResource("PlutoMake.class")
.getPath();
classDir = classDirFile.substring(0, classDirFile.lastIndexOf("/") + 1);
// get the input arguments
final String logoPath;
final String filename;
if (args.length < 2) {
logoPath = classDir + "tests/android.png";
filename = "result.png";
} else {
logoPath = args[0];
filename = args[1];
}
// make sure the logo image exists
File logofile = new File(logoPath);
if (!logofile.exists() || logofile.isDirectory()) {
System.exit(1);
}
// get the master.js file
String text = readFile(classDir + "master.js");
JSONArray files = new JSONArray(text);
ExecutorService es = Executors.newCachedThreadPool();
// loop through all active templates
int len = files.length();
for (int i = 0; i < len; i += 1) {
final JSONObject template = files.getJSONObject(i);
if (template.getBoolean("active")) {
es.execute(new Runnable() {
#Override
public void run() {
try {
BatchGenerateResult(logoPath, template.getString("template"),
template.getString("mapping"),
template.getString("metadata"), template.getString("result")
+ filename, template.getString("filter"),
template.getString("mask"), template.getInt("x"),
template.getInt("y"), template.getInt("w"),
template.getInt("h"));
} catch (IOException | JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
es.shutdown();
boolean finshed = es.awaitTermination(2, TimeUnit.MINUTES);
}
private static void BatchGenerateResult(String logoPath, String templatePath,
String mappingPath, String metadataPath, String resultPath,
String filter, String maskPath, int x, int y, int w, int h)
throws IOException, JSONException {
ColorFilter filterobj = null;
if (filter.equals("none")) {
filterobj = new NoFilter();
} else if (filter.equals("darken")) {
filterobj = new Darken();
} else if (filter.equals("vividlight")) {
filterobj = new VividLight();
} else {
System.exit(1);
}
String text = readFile(classDir + metadataPath);
JSONObject metadata = new JSONObject(text);
Map<Point, Point> mapping = MyJSON.ReadMapping(classDir + mappingPath);
BufferedImage warpedimage = Exporter.GenerateWarpedLogo(logoPath, maskPath,
mapping, metadata.getInt("width"), metadata.getInt("height"));
// ImageIO.write(warpedimage, "png", new FileOutputStream(classDir +
// "warpedlogo.png"));
Exporter.StampLogo(templatePath, resultPath, x, y, w, h, warpedimage,
filterobj);
warpedimage.flush();
}
private static String readFile(String path) throws IOException {
File file = new File(path);
FileInputStream fis = new FileInputStream(file);
byte[] data = new byte[(int) file.length()];
fis.read(data);
fis.close();
String text = new String(data, "UTF-8");
return text;
}
}
It looks like, for all practical purposes the following code should be the only one which can improve performance by using multithreading.
BufferedImage warpedimage = Exporter.GenerateWarpedLogo(logoPath, maskPath,
mapping, metadata.getInt("width"), metadata.getInt("height"));
// ImageIO.write(warpedimage, "png", new FileOutputStream(classDir +
// "warpedlogo.png"));
Exporter.StampLogo(templatePath, resultPath, x, y, w, h, warpedimage,
filterobj);
The rest of it major IO - I doubt how much performance improvement you can achieve there.
Do a profile and check how long each one of the methods is executing. Depending on that you should be able to understand.
Hi sorry not able add to comment part as just joined..
would suggest to first go for dummy method any check whether it works at your end then add your business logic...
if the sample works then you might need to check your "template" class
here's the sample.. check the timestamp
package example;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorStaticExample {
public static void main(String[] args){
ExecutorService ex = Executors.newCachedThreadPool();
for (int i=0;i<10;i++){
ex.execute(new Runnable(){
#Override
public void run() {
helloStatic();
System.out.println(System.currentTimeMillis());
}
});
}
}
static void helloStatic(){
System.out.println("hello form static");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Let the user enter the filename

I created an interface that allows to add instances in an rdf file. I put the filepath in the readRDFfile parameter and the same filepath in Filewriter (in order to update the file when user add instances). But i'd like to allow user enter the name file he want to create when I execute the code. And FileWriter must take this file in parameter when user add instances.
My problem is that I don't know how to put the file that user has chosen and that was read in readRDFfile, in Filewriter parameter in order to be updated when he adds instances.
import java.util.*;
import java.util.List;
import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.ontology.impl.*;
import com.hp.hpl.jena.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.XSD;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
public class FamilyModel extends Frame
{
TextField[]tabTF=new TextField[4];
Button bAjout, bModifier, bSupprimer, bPrecedent, bSuivant, bValiderModif; //buttons Add, Remove, Previous, Next
OntModel model;
Onto onto;
int indice=0;
int p=0;
Resource p1;
Button creerBouton(String S, int x, int y)
{
Button b=new Button(S);
add(b);
b.setBounds(x,y,120,30);
return b;
}
void creerLabel(String etiquette, int x, int y)
{
Label la=new Label(etiquette);
la.setBounds(x,y,100,25);
add(la);
}
public FamilyModel ()
{
setLayout (null);
setBackground (Color.pink);
setBounds (100,200,900,450);
creerLabel("Prenom : ",10,50);
creerLabel("Nom : ",10,100);
creerLabel("Date de Naissance: ",10,145);
creerLabel("Genre (H ou F): ",10,190);
//TextFields
for(int i=0;i<4;i++)
{
tabTF[i]=new TextField("");
tabTF[i].setBackground(Color.white);
add(tabTF[i]);
}
tabTF[0].setBounds(120,45,150,25);
tabTF[1].setBounds(120,100,150,25);
tabTF[2].setBounds(120,145, 100,25);
tabTF[3].setBounds(120,190, 45,25);
bAjout=creerBouton("Ajouter",20,250);
setVisible(true);
bModifier=creerBouton("Modifier",138,250);
setVisible(true);
//bSupprimer=creerBouton("Supprimer",250,250);
//setVisible(true);
bPrecedent=creerBouton("Precedent",360,250);
bSuivant=creerBouton("Suivant",450,250);
bSupprimer=creerBouton("Supprimer",600,250);
setVisible(true);
onto = new Onto();
readRDFfile();
traitement(this);
}
void traitement(Frame fenetre)
{
bAjout.addActionListener(new ActionAjoutPersonne());
//bModifier.addActionListener(new ActionModifier());
//bValiderModif.addActionListener(new ActionModif());
bSuivant.addActionListener(new ActionSuivant());
bPrecedent.addActionListener(new ActionPrecedent());
bSupprimer.addActionListener(new ActionSupprimer());
}
//Button Add
public class ActionAjoutPersonne implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
p1=onto.model.createResource(onto.uriBase+"#"+tabTF[0].getText());
p1.addProperty(onto.aPourPrenom, tabTF[0].getText());
p1.addProperty(onto.aPourNom, tabTF[1].getText());
p1.addProperty(onto.aDateNaiss, tabTF[2].getText());
if (tabTF[3].getText().equals("F"))
{
p1.addProperty(onto.aGenre, tabTF[3].getText());
p1.addProperty(RDF.type, onto.femme);
}
else if (tabTF[3].getText().equals("H"))
{
p1.addProperty(onto.aGenre, tabTF[3].getText());
p1.addProperty(RDF.type, onto.homme);
}
StringWriter sw = new StringWriter();
onto.model.write(sw, "RDF/XML-ABBREV");
String owlCode = sw.toString();
File file = new File("d:/Onto.rdf");
try{
FileWriter fw = new FileWriter(file);
fw.write(owlCode);
fw.close();
} catch(FileNotFoundException fnfe){
fnfe.printStackTrace();}
catch(IOException ioe){
ioe.printStackTrace();
}
}
}
//Button Remove
public class ActionSupprimer implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
List<Statement> statementsToRemove = new ArrayList<Statement>();
StmtIterator iter = onto.model.listStatements();
while (iter.hasNext())
{
Statement stmt = iter.nextStatement();
Resource subject = stmt.getSubject();
Property predicate = stmt.getPredicate();
RDFNode object = stmt.getObject();
if(subject.toString().equals (onto.uriBase+"#"+tabTF[0].getText()))
{
statementsToRemove.add(stmt);
}
}
for( Statement stmt : statementsToRemove)
{
onto.model.remove(stmt);
}
StringWriter sw = new StringWriter();
onto.model.write(sw, "RDF/XML-ABBREV");
String owlCode = sw.toString();
File file = new File("d:/Onto.rdf");
try{
FileWriter fw = new FileWriter(file);
fw.write(owlCode);
fw.close();
} catch(FileNotFoundException fnfe){
fnfe.printStackTrace();}
catch(IOException ioe){
ioe.printStackTrace();
}
}
}
//Read Onto.rdf
public void readRDFfile()
{
String inputFile="D:/Onto.rdf";
try
{
InputStream in =new FileInputStream(inputFile);
if (in == null) {
System.out.println("File not found");
}
onto.model.read(in, null);
}catch(Exception e) {
System.out.println("model.read catched error: " + e);
}
}
//Button Next
class ActionSuivant implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
++indice;
ExtendedIterator instances = onto.personne.listInstances();
Individual instance = null;
Individual firstInstance = null;
for (p = 0; p < indice && instances.hasNext(); p++) {
instance = (Individual) instances.next();
if (firstInstance == null) {
firstInstance = instance;
}
}
if (p < indice) {
indice = 1;
instance = firstInstance;
}
tabTF[0].setText(instance.getPropertyValue(onto.aPourPrenom).toString());
tabTF[1].setText(instance.getPropertyValue(onto.aPourNom).toString());
tabTF[2].setText(instance.getPropertyValue(onto.aDateNaiss).toString());
tabTF[3].setText(instance.getPropertyValue(onto.aGenre).toString());
}
}
class ActionPrecedent implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
--indice;
//Instances de la Classe Personne
ExtendedIterator instances=onto.personne.listInstances();
Individual instance = null;
for(p = 0; p < indice && instances.hasNext(); p++)
{
instance = (Individual) instances.next();
}
tabTF[0].setText(instance.getPropertyValue(onto.aPourPrenom).toString());
tabTF[1].setText(instance.getPropertyValue(onto.aPourNom).toString());
tabTF[2].setText(instance.getPropertyValue(onto.aDateNaiss).toString());
tabTF[3].setText(instance.getPropertyValue(onto.aGenre).toString());
}
}
//Ontology
public class Onto
{
OntClass personne, genre, homme, femme, feminin, masculin, evenement, deces, mariage, divorce;
OntModel model;
String uriBase;
ObjectProperty aPourFils, aPourFille, aGenre;
DatatypeProperty aPourNom, aPourPrenom, aDateNaiss;
public Onto (){
model = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM_MICRO_RULE_INF );
uriBase = "http://www.something.com/FAM";
model.createOntology(uriBase);
//Classes
personne = model.createClass(uriBase+"personne");
femme = model.createClass(uriBase+"femme");
homme = model.createClass(uriBase+"homme");
genre = model.createClass(uriBase+"genre");
feminin = model.createClass(uriBase+"feminin");
masculin = model.createClass(uriBase+"masculin");
evenement = model.createClass(uriBase+"evenement");
deces = model.createClass(uriBase+"deces");
mariage = model.createClass(uriBase+"mariage");
divorce = model.createClass(uriBase+"divorce");
//Sub-classes
genre.addSubClass(feminin);
genre.addSubClass(masculin);
personne.addSubClass(homme);
personne.addSubClass(femme);
evenement.addSubClass(deces);
evenement.addSubClass(mariage);
evenement.addSubClass(divorce);
aPourFils = model.createObjectProperty(uriBase+"aPourFils");
aPourFils.setDomain(personne);
aPourFils.setRange(homme);
aPourFille = model.createObjectProperty(uriBase+"aPourFille");
aPourFille.setDomain(personne);
aPourFille.setRange(femme);
aGenre = model.createObjectProperty(uriBase+"aGenre");
aGenre.setDomain(personne);
aGenre.setRange(genre);
aPourNom = model.createDatatypeProperty(uriBase+"aPourNom");
aPourNom.setDomain(personne);
aPourNom.setRange(XSD.xstring);
aPourPrenom = model.createDatatypeProperty(uriBase+"aPourPrenom");
aPourPrenom.setDomain(personne);
aPourPrenom.setRange(XSD.xstring);
aDateNaiss = model.createDatatypeProperty(uriBase+"aDateNaiss");
aDateNaiss.setDomain(personne);
aDateNaiss.setRange(XSD.xstring);
}
}
public static void main(String args[])
{
new FamilyModel();
}
}
If your app has a GUI, the standard way to select an input file would be to use a file chooser, for example JFileChooser if your app is Swing based, or FileDialog if you want to stick to AWT components.
Here is an exmaple for JFileChooser:
int returnVal = fc.showOpenDialog(FileChooserDemo.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
String filename = file.getName();
}
JFileChooser Tutorial:
http://download.oracle.com/javase/tutorial/uiswing/components/filechooser.html
If your app is command line based (which I gather it not the case from your code for handling button clicks), you could make the input be one of the command line arguments when you run the app, and you could read it out of args[] array passed into main().
There are many options and schools of thought regarding how to get data from the user. Most of this depends on who the user will be and how they are going to be interacting with this program. A couple I've listed.
Command Line Interface This is my favorite because I'm in the terminal a lot and write a lot of bash scripts. Very simple and low development overhead, while still being extensible. You'll need to add code in your main method to retrieve options and values. I like using Apache Commons CLI even though it's not under active development, there is a good tutorial.
Graphical User Interface Use Java Swing or a web application to create a UI around your app. This will inevitably take much longer than any other option but will be the most accessible for non-technical users.
Standard In If you just want the program to pause and prompt the user on the console with no bells or whistles use this in main (if you using
Console con = System.console();
String file = con.readLine("File Name: ");

How can I display a PPT file in a Java Applet?

I want to open and display an existing Microsoft PowerPoint presentation in a Java Applet. How can I do that?
Tonic Systems was selling a Java PPT renderer until they were bought by Google. I know of no other solution.
You could implement this yourself, of course, but that's going to be a lot of work. There is rudimentary support for reading and writing PPT files in the Apache POI project, but you will have to do all the rendering yourself.
Visualization can be done by visualizing each slide as a jpg image.
You can use the Jacob java library for the conversion. This library expoits COM bridge and gets Microsoft Office Power Point to do the conversion (through save-as command). I've got PP2007:
package jacobSample;
import com.jacob.activeX.*;
import com.jacob.com.*;
public class Ppt {
ActiveXComponent pptapp = null; //PowerPoint.Application ActiveXControl Object
Object ppto = null; //PowerPoint.Application COM Automation Object
Object ppts = null; //Presentations Set
// Office.MsoTriState
public static final int msoTrue = -1;
public static final int msoFalse = 0;
// PpSaveAsFileType
public static final int ppSaveAsJPG = 17 ;
//other formats..
public static final int ppSaveAsHTML = 12;
public static final int ppSaveAsHTMLv3 =13;
public static final int ppSaveAsHTMLDual= 14;
public static final int ppSaveAsMetaFile =15;
public static final int ppSaveAsGIF =16;
public static final int ppSaveAsPNG =18;
public static final int ppSaveAsBMP =19;
public static final int ppSaveAsWebArchive =20;
public static final int ppSaveAsTIF= 21;
public static final int ppSaveAsPresForReview= 22;
public static final int ppSaveAsEMF= 23;
public Ppt(){
try{
pptapp = new ActiveXComponent("PowerPoint.Application");
ppto = pptapp.getObject();
ppts = Dispatch.get((Dispatch)ppto, "Presentations").toDispatch();
}catch(Exception e){
e.printStackTrace();
}
}
public Dispatch getPresentation(String fileName){
Dispatch pres = null; //Presentation Object
try{
pres = Dispatch.call((Dispatch)ppts, "Open", fileName,
new Variant(Ppt.msoTrue), new Variant(Ppt.msoTrue),
new Variant(Ppt.msoFalse)).toDispatch();
}catch(Exception e){
e.printStackTrace();
}
return pres;
}
public void saveAs(Dispatch presentation, String saveTo, int ppSaveAsFileType){
try{
Object slides = Dispatch.get(presentation, "Slides").toDispatch();
Dispatch.call(presentation, "SaveAs", saveTo, new Variant(ppSaveAsFileType));
}catch (Exception e) {
e.printStackTrace();
}
}
public void closePresentation(Dispatch presentation){
if(presentation != null){
Dispatch.call(presentation, "Close");
}
}
public void quit(){
if(pptapp != null){
ComThread.Release();
//pptapp.release();
try{
pptapp.invoke("Quit", new Variant[]{});
}catch(Exception e){
System.out.println("error");
}
}
}
public static void main(String[] args){
//System.loadLibrary("jacob-1.15-M4-x86.dll");
//System.loadLibrary("jacob-1.15-M4-x64.dll");
Ppt a = new Ppt();
System.out.println("start");
Dispatch pres = a.getPresentation("C:\\j.pptx");// pptx file path
a.saveAs(pres, "C:\\im", Ppt.ppSaveAsJPG); // jpg destination folder
a.closePresentation(pres);
a.quit();
System.out.println("end");
}
}
I am not sure whether my idea of simulating PPT rendering works or not:
Let the server side read the PPT file and generate JPG files for display.
The browser side will use ajax to request for any specific page from the PPT.

Categories

Resources