I created a pdf reader using boxPdf.
My project contain 4 java files and ui.fxml
The main file (main.java)
the controller (controller.java)
display pdf file class (pdfDisplay.java)
and the pdf model (pdfModel.java).
the load button is implemented on the controller.java, when i click on it i will load a pdf file with a close button.
My question is:
How can i disable the load button, when a pdf is displayed, until when i click on the close button?
Because as you can see, in the second picture, the load button is always enabled, and user can load another file even if the first one is displayed, what i don't want.
Another answer:
When i close the pdf displayed, and load another one i get:
Children: duplicate children added: parent = AnchorPane[id=anchor, styleClass=root] in the debugger
This is my code project
main.java
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*@author toru
*/
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
final Parent parent = FXMLLoader.load(getClass().getResource("ui.fxml"));
parent.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setTitle("Vet0b00k5");
primaryStage.setScene(new Scene(parent,600, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
controller.java
package application;
import java.io.File;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.stage.FileChooser;
import java.nio.file.Path;
public class controller{
@FXML
private AnchorPane anchor = new AnchorPane();
Button loadButton=new Button ("Load");
pdfDisplay pdfFileOpened= new pdfDisplay();
HBox menuLoadB = new HBox (1);
Path Path;
PdfModel model= new PdfModel();
public void initialize(){
/*this part doesn't work*/
if(Path==null){
loadButton.setDisable(false);
}
else{
loadButton.setDisable(true);
}
/*this part doesn't work*/
menuLoadB.getChildren().add(loadButton);
anchor.getChildren().addAll(menuLoadB);
loadButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
loadFile();
}
});
}
void loadFile() {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Upload File Path");
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("PDF", "*.pdf"));
File file = fileChooser.showOpenDialog(anchor.getScene().getWindow());
if (file != null && file.toPath()!=null) {
String f=file.getPath();
pdfFileOpened.setModel(f);
anchor.getChildren().addAll(pdfFileOpened.affichePDF());
} else {
System.out.println("error"); // or something else
}
}
}
pdfDisplayClass.java
package application;
import java.nio.file.Path;
import java.nio.file.Paths;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Pagination;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
public class pdfDisplay{
Button xButton=new Button ("X");
HBox menu = new HBox (1);
Pagination pagination;
Path Path;
PdfModel model= new PdfModel();
ScrollPane scrollPane = new ScrollPane();
VBox vboxRoot= new VBox();
ImageView imageView = new ImageView();
public VBox createPage(int pageIndex) {
VBox box = new VBox();
imageView = new ImageView(model.getImage(pageIndex));
imageView.setFitWidth(model.afficheLargeur()*1.25);
imageView.setFitHeight(model.afficheHauteur()*1.25);
VBox.setMargin(scrollPane, new Insets(10, 50, 10, 50));
scrollPane.prefHeightProperty().bind(vboxRoot.heightProperty());
scrollPane.setPannable(true);
scrollPane.setContent(imageView);
scrollPane.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
scrollPane.setHbarPolicy(ScrollBarPolicy.AS_NEEDED);
scrollPane.setStyle("-fx-border-color:red;");
pagination.setStyle("-fx-border-color:black;");
box.getChildren().add(scrollPane);
return box;
}
void setModel(String f) {
model= new PdfModel(Paths.get(f));
}
Path getModel() {
return model.getPath();
}
VBox affichePDF() {
pagination = new Pagination();
pagination.setPageCount(model.nombreDePages());
pagination.setPageFactory((Integer pageIndex) -> { return createPage(pageIndex);});
xButtonAction();
VBox.setMargin(pagination, new Insets(10, 10, 10, 10));
VBox.setMargin(menu, new Insets(10, 10, 10, 10));
menu.getChildren().addAll(xButton);
menu.setStyle("-fx-border-color:yellow;");
vboxRoot.setStyle("-fx-border-color:yellow;");
vboxRoot.getChildren().addAll(menu,pagination);
AnchorPane.setTopAnchor(vboxRoot, 50.0);
AnchorPane.setRightAnchor(vboxRoot, 10.0);
AnchorPane.setBottomAnchor(vboxRoot, 40.0);
AnchorPane.setLeftAnchor(vboxRoot, 40.0);
return vboxRoot;
}
void xButtonAction() {
xButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
fermerFichier();
}
});
}
void fermerFichier() {
pagination.setPageFactory( (Integer pageIndex) -> { return null;} );
menu.getChildren().removeAll(xButton);
vboxRoot.getChildren().removeAll(menu,pagination);
model.setPath(null);
model.fermer();
}
}
pdfmodel.java
package application;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
//import java.util.logging.Logger;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.rendering.PDFRenderer;
/**
* @author toru
*/
class PdfModel {
//private static final Logger logger = Logger.getLogger(PdfModel.class.getName());
private PDDocument document;
private PDFRenderer renderer;
Path chemin;
PdfModel() {
}
PdfModel(Path path) {
try {
chemin=path;
document = PDDocument.load(path.toFile());
renderer = new PDFRenderer(document);
} catch (IOException ex) {
throw new UncheckedIOException("PDDocument thorws IOException file=" + path, ex);
}
}
int nombreDePages() {
return document.getPages().getCount();
}
void fermer() {
try {
document.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
void setPath(Path pPays)
{
chemin = pPays;
}
Path getPath()
{
return chemin;
}
double afficheHauteur() {
PDPage page = document.getPage(document.getNumberOfPages() - 1);
PDRectangle pageSize = page.getMediaBox();
return pageSize.getHeight();
}
double afficheLargeur() {
PDPage page = document.getPage(document.getNumberOfPages() - 1);
PDRectangle pageSize = page.getMediaBox();
return pageSize.getWidth();
}
Image getImage(int pageNumber) {
BufferedImage pageImage;
try {
pageImage = renderer.renderImage(pageNumber,3);
} catch (IOException ex) {
throw new UncheckedIOException("PDFRenderer throws IOException", ex);
}
return SwingFXUtils.toFXImage(pageImage, null);
}
}
ui.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<AnchorPane fx:id="anchor" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller">
<children>
<HBox prefHeight="50.0" prefWidth="400.0" />
</children>
</AnchorPane>
You can download my eclipse project and the pdf box
thanks for taking the time to read all of this
best regards
this is the solution.
The loadButton must be static.
To access controller loadButton from another class and set it to ennable, this is the correct command
application.controller.loadButton.setDisable(false);
regards