Error displaying some PDFs with OpenViewerFX - java

I am using OpenViewerFX (JPedal) to display PDF files in a JavaFX application. Some files are displayed well, others only show not printable characters (in documents created by myself and also documents from other people).
See for example this one:
This is my code:
private final PdfDecoderFX pdf = new PdfDecoderFX();
private Group group;
#Override
public void start(Stage stage) {
BorderPane bp = new BorderPane();
Scene scene = new Scene(bp, 400, 400);
stage.setScene(scene);
stage.show();
group = new Group();
group.getChildren().add(pdf);
bp.setCenter(group);
Platform.runLater(() -> {
try {
pdf.openPdfFile("D:\\Dokument1.pdf");
decodePage();
} catch (PdfException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
});
}
private void decodePage() {
try {
pdf.setPageParameters(2.0f, 0);
pdf.decodePage(1);
pdf.waitForDecodingToFinish();
} catch (final Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
The PDF file was created from a Word document with Adobe PDF printer. I used the standard font and only standard characters. I tested several settings when creating the file, including
Compatibility "PDF 1.3" to "PDF 1.7"
Enable/Disable web optimization
Include all fonts
Include Open-Type fonts
but always the same result.
What could I be doing wrong?

Seems like a font issue to me. The debugging output helped me in the past - at least I saw some error message in there. I'm not quite sure what the correct option was but try the following:
Did you try to enable jpedal logging?
//debug code
LogWriter.log_name="/yourpath/log.txt";
LogWriter.setupLogFile(true,0,"1.0","v",false);
What does the org.jpedal.PdfDecoder.getPageDecodeStatus(int type)state where type is any value Defined in org.jpedal.parser.DecodeStatus
We use a patched version of the ViewerFX - can you try that one?
Are you sure you specified the correct path to the fonts?
To add a whole directory of fonts via JVM flag set the JVM flag -Dorg.jpedal.fontdirs=dirList where dirList is a comma-separated list of possible directories.
What is your OS? Windows or Linx?
Did you also try the -Dorg.jpedal.inclusiveLogFilter= "memory,error"JVM option?
Try to set -Dverbose=true
Call GUI.debugFX=true; see here.

Related

JavaFX-SceneBuilder - Can't access fx:id when opening new window

I have this code (part of a quite big application):
The following function is located in the controller class of the project.
public void callSearch(){
Stage supplyStage = new Stage();
Parent root = null;
try {
root = FXMLLoader.load(getClass().getResource("supplyResult.fxml"));
supplyStage.setTitle("Supply Result Set");
supplyStage.setScene(new Scene(root, 1400, 900));
supplyStage.show();
} catch (IOException e) {
e.printStackTrace();
}
try {
typeColumn.setCellValueFactory(new PropertyValueFactory<Supply, String>("type"));
nameColumn.setCellValueFactory(new PropertyValueFactory<Supply, String>("name"));
dateColumn.setCellValueFactory(new PropertyValueFactory<Supply, String>("order_date"));
pricePerUnitColumn.setCellValueFactory(new PropertyValueFactory<>("pricePerUnit"));
quantityColumn.setCellValueFactory(new PropertyValueFactory<>("quantity"));
}
catch (NullPointerException npe){
System.out.println("Null...");
}
searchSupplyStartDate = java.sql.Date.valueOf(startDateDatePicker.getValue());
searchSupplyEndDate = java.sql.Date.valueOf(endDateDatePicker.getValue());
tableOutput.setItems(myMain.getSupplies(searchSupplyStartDate,searchSupplyEndDate,null,null));
}
My problem is that I get a NullPointerException in the line typeColumn.setCellValueFactory(new PropertyValueFactory<Supply, String>("type"));
In previous version of the application I had the columns in the same window as the rest of the scene. Now I try to add a second window when displaying the same stuff, to make the first scene a bit more beautiful. (the code was working when I had one scene).
In fact, to make things clear, i want with the press of a button, the function callSearch() to be called. Then a window appears, with a table of 5 columns attached: typeColumn, nameColumn, dateColumn, pricePerUnitColumn, quantityColumn. Those 5 columns are declared in the (only) controller of the project, so i thought that they are visible in any fxml file in the project, but that's not the case.
Does anybody know what am I missing? the typeColumn is visible from the SupplyResult.fxml in scene builder, but does not seem to execute the code it has to...

How to open a generated PDF in vaadin?

In my vaadin application I have a Table with an additional column containing a print Button. The Button calls the following util method to create a pdf and open it in a new window (ui parameter is the button):
public static void printPDF(Offer offer, AbstractComponent ui) throws IOException, DocumentException, TemplateException {
// ... create PDF
FileResource resource = new FileResource(pdfFile);
BrowserWindowOpener opener = new BrowserWindowOpener(resource);
opener.setFeatures("");
opener.extend(ui);
}
Now clicking the button the first time does not work. Clicking it the second time works. Clicking it the third time, opens two windows. This increases on every further click.
I also want to open the pdf using the context menu e.g.
table.addActionHandler(new Handler()...
There I don't even have a button to extend. I would prefer to, not use the .extend() part and just open a new window. How can I do that?
EDIT: This blocks the button from opening mulitple instances, still not a nice solution and the first click does not work.
Collection<Extension> extensions = ui.getExtensions();
for (Extension e : extensions) {
if (e instanceof BrowserWindowOpener) {
((BrowserWindowOpener) e).setResource(resource);
return;
}
}
I guess I would need to create a BrowserWindowOpener for every print Button in my Table.
Not a very clean solution, the table may contain lots of rows which would create a lot of BrowserWindowOpener instances which will never be used. The context menu problem would not be solved as well.
EDIT2: This is the other solution I tried:
ResourceReference rr = ResourceReference.create(resource, ui, "print");
Page.getCurrent().open(rr.getURL(), "blank_");
Here I get the following error:
Button (175) did not handle connector request for
print/2016_9090_R_1634500091131558445.pdf
You can use the FileDownloader to achieve what you want.
FileResource resource = new FileResource(pdfFile);
FileDownloader downloader = new FileDownloader(resource);
Button pdf= new Button("Download PDF");
downloader.extend(pdf);
Use this code
Window window = new Window();
((VerticalLayout) window.getContent()).setSizeFull();
window.setResizable(true);
window.setCaption("Exemplo PDF");
window.setWidth("800");
window.setHeight("600");
window.center();
StreamSource s = new StreamResource.StreamSource() {
#Override
public InputStream getStream() {
try {
File f = new File("C:/themes/repy.pdf");
FileInputStream fis = new FileInputStream(f);
return fis;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
};
StreamResource r = new StreamResource(s, "repy.pdf", mainLayout.getApplication());
Embedded e = new Embedded();
e.setSizeFull();
e.setType(Embedded.TYPE_BROWSER);
r.setMIMEType("application/pdf");
e.setSource(r);
window.addComponent(e);
getMainWindow().addWindow(window);

dynamically adding hyperlinks to rtf file in JEditorPane

I am currently building a word processor for use in a multi-window media annotation tool, written in Java. It is for film students to write essays and embed them with links to multimedia clips.
I want the user to be able to highlight text in an rtf document and create a link to a media file in the project. When clicked the link will display the media in its associated window.
I would like to know if it is possible to dynamically create hyperlinks in rtf documents in Java? As is possible in Word, for example.
At the moment I am using a JEditorPane with the Advanced RTF Editor Kit (http://java-sl.com/advanced_rtf_editor_kit.html). I am struggling to find any sort of a solution.
Any help or pointers greatly appreciated.
Thanks
Edit:
code, with parts 1 & 3 from # Eric's answer added
`item3.addActionListener(new ActionListener() {
#Override
public void actionPerformed(java.awt.event.ActionEvent e) {
//use FX thread to open FileChooser
Platform.runLater(new Runnable() {
#Override
public void run() {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("create link");
String startDirectory = System.getProperty("user.home") + File.separator + "Pictures";
fileChooser.setInitialDirectory(new File(startDirectory));
FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("JPEG files (*.jpg)", "*.jpg");
FileChooser.ExtensionFilter extFilter2 = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.png");
FileChooser.ExtensionFilter extFilter3 = new FileChooser.ExtensionFilter("JPG files (*.jpeg)", "*.jpeg");
fileChooser.getExtensionFilters().addAll(extFilter,extFilter2, extFilter3);
File imageFile = fileChooser.showOpenDialog(stage);
if(imageFile != null){
Image image = ImageViewerController.getImage();
try {
image = new Image(imageFile.toURI().toURL().toExternalForm().toString());
int start = textArea.getSelectionStart();
int end = textArea.getSelectionEnd();
textArea.getDocument().remove(start, end);
String newString = "{\field{\*\fldinst HYPERLINK 'http://www.google.com/'}{\fldrslt http://www.google.com}}";
textArea.getDocument().insertString(start, newString , null);
textArea.addHyperlinkListener(new HyperlinkListener() {
#Override
public void hyperlinkUpdate(HyperlinkEvent hle) {
if (HyperlinkEvent.EventType.ACTIVATED.equals(hle.getEventType())) {
System.out.println(hle.getURL());
Desktop desktop = Desktop.getDesktop();
try {
desktop.browse(hle.getURL().toURI());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
});`
I think there are various parts in your question:
1. Replace selected text in a Document:
Get the selected range with:
int start = editorpane.getSelectionStart();
int end = editorpane.getSelectionEnd();
Replace the text with:
editorpane.getDocument().remove(start,end);
editorpane.getDocument().insertString(start, newString, null);
Note: replace null with actual attribute set if needed.
2. Create a RTF-formatted hyperlink. I think this post has everything.
3. React to hyperlink clicks: As explained in the docs, you must add a HyperlinkListener to the editor pane to open the corresponding media. However a condition for this to work is that the editor kit generates HyperlinkEvents when hyperlinks are clicked. This is definitely the case for HTML documents, but since you are using a 3rd party library, I cannot confirm it will work the same way...

Load FXML in initialize()

I'm creating my first JavaFX application, and I'm doing OK so far. I'm just encountering one problem.
For displaying and loading FXML files I'm using a VistaNavigator class found on StackOverflow:
public static void loadVista(String fxml) {
try {
mainController.setVista(
FXMLLoader.load(
VistaNavigator.class.getResource(
fxml
)
)
);
} catch (IOException e) {
e.printStackTrace();
}
}
I have a ScanController, which receives input from the keyboard and checks a ticket ID based on this input. When the ticket is OK, it loads "scan-success.fxml", otherwise it loads "scan-failure.xml", each of these FXML-files have an own controller. I'm loading the success FXML like this:
VistaNavigator.loadVista(VistaNavigator.VISTA_SCAN_SUCCESS);
This is working great. The Success-FXML page is showing and the ScanSuccessController is loading. In the initialize() method of ScanSuccessController.java I have the following code snippet:
try {
Thread.sleep(2000); //1000 milliseconds is one second.
VistaNavigator.loadVista(VistaNavigator.VISTA_SCAN_HOME);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
So I would like to show the success-page for about 2 seconds, and then head back to the home screen (scan-home.fxml with controller ScanHomeController.java) to scan some more tickets. However, when executing this code, just 'nothing' happens, no exception and no change of FXML-file.
When I try to load a new vista after clicking a button (in an EventHandler) it works great.
I can imagine that JavaFX is not able to load a new FXML-file before the controller has been fully initialised, but cannot figure out where to put this line of code..
I hope someone can help me out with this.
What about this:
#Override
public void initialize(URL url, ResourceBundle rb) {
Timeline timeline=new Timeline();
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(2),
e->VistaNavigator.loadVista(VistaNavigator.VISTA_SCAN_HOME)));
timeline.play();
}
Note that by using a Timeline everything runs in the JavaFX thread.

How to view a PDF document using PDFBox's PDFPagePanel

I cannot seem to figure out how to view a PDF Page using PDFBox and its PDFPagePanel component.
So it seems that using PDFBox my options are to either create a List of PDPage objects or PDDocument objects, I've gone with the PDPage list (as opposed to using Splitter() for PDDocument objects)
The following code creates a PDPage object named testPage
File PDF_Path = new File("C:\\PDF.PDF");
PDDocument inputPDF = PDDocument.load(PDF_Path);
List<PDPage> allPages = inputPDF.getDocumentCatalog().getAllPages();
inputPDF.close();
PDPage testPage = (PDPage)allPages.get(0);
From here I would like to create a PDFPagePanel and use its setPage() method to place the PDPage into the component. From here I want to add the component to a JFrame. When I do this I just see whitespace.
JFrame testFrame = new JFrame();
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
PDFPagePanel pdfPanel = new PDFPagePanel();
pdfPanel.setPage(testPage);
testFrame.add(pdfPanel);
testFrame.setBounds(40, 40, pdfPanel.getWidth(), pdfPanel.getHeight());
testFrame.setVisible(true);
I found one 'solution' which suggest converting the PDF to an image and displaying it as a buffered image, and while this works it doesn't seem like the correct way to do this. Am I incorrect in trying to use PDFBox's PDFPagePanel as a means to displaying a PDF?
When I comment out the inputPDF.close call, it works okay. What if you move the close to after you are finished displaying the pdf? Something like this...
testFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
testFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
try {
inputPDF.close();
testFrame.setVisible(false);
} catch (IOException e1) {
// TODO: implement error handling
e1.printStackTrace();
}
}
});
For the record, I also implemented a PDFBox viewer as a BufferedImage wrapped in a Component wrapped in a JPanel. Then, I was able to customize the panel with additional buttons to change pages, change documents, "zoom" or resize the image, etc.

Categories

Resources