-2

I am trying to download a TableView in JavaFx as an pdf document. I am using iText 7.2.5 . When I am clicking the button to download the TableView, it is asking me to select the folder then it is asking to write the name for the pdf document then after it; when I press ok to download the document, it downloads the pdf file that is unable to show any content even a blank page. When I open the pdf file with chrome it shows this, and I also tried to open with Adobe Acrobat, but situation is the same with pdf file.

Error Failed to load PDF document.

First, it was giving an exception for slf4j; then I added these jar files in classpath: slf4j-simple-2.0.6.jar , slf4j-api-2.0.6-javadoc.jar , slf4j-api-2.0.6.jar . It was giving warning for provider not found or something like that; that was solved after adding slf4j-simple-2.0.6.jar.

I saw a similar question here java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory problem.

Answer of this question is: It turns out that it missed the following 3 jars : slf4j.api, slf4j-log4j12, and log4j

It works now after adding the above 3 jars.

These are all the files at org/slf4j integration/ - -
jcl-over-slf4j/ - -
jcl104-over-slf4j/ - -
jul-to-slf4j/ - -
log4j-over-slf4j/ - -
nlog4j/ - -
osgi-over-slf4j/ - -
slf4j-android/ - -
slf4j-api/ - -
slf4j-archetype/ - -
slf4j-converter/ - -
slf4j-ext/ - -
slf4j-jcl/ - -
slf4j-jdk-platform-logging/ - -
slf4j-jdk14/ - -
slf4j-log4j12/ - -
slf4j-log4j13/ - -
slf4j-migrator/ - -
slf4j-nop/ - -
slf4j-parent/ - -
slf4j-reload4j/ - -
slf4j-simple/ - -
slf4j-site/ - -
slf4j-skin/ - -
taglib/ - -

log4j-over-slf4j/ ---> is it the file log4j that is mentioned in reference answer to the question.

I am unable to get slf4j-log4j12.

because org/slf4j/slf4j-log4j12/2.0.6 contains no jar file but this

slf4j-log4j12-2.0.6.pom 2022-12-12 19:14 873
slf4j-log4j12-2.0.6.pom.asc 2022-12-12 19:14 317
slf4j-log4j12-2.0.6.pom.md5 2022-12-12 19:14 32
slf4j-log4j12-2.0.6.pom.sha1

Here is the code on download button:

@FXML
public void ButtonDownload(ActionEvent event) {
     
    DirectoryChooser directoryChooser = new DirectoryChooser();
    File selectedDirectory =                directoryChooser.showDialog(TableName.getScene().getWindow());
    if (selectedDirectory == null) {
        return;
    }
    
    
    TextInputDialog dialog = new TextInputDialog("table");
    dialog.setTitle("Enter File Name");
    dialog.setHeaderText("Enter the name for the PDF file:");
    dialog.setContentText("File name:");
    Optional<String> result = dialog.showAndWait();
    
    if (result.isPresent()) {
        try {
            String fileName = result.get();
            if (!fileName.endsWith(".pdf")) {
                fileName = fileName + ".pdf";
            }
            String filePath = selectedDirectory.getAbsolutePath() + "/" + fileName;
            OutputStream file = new FileOutputStream(filePath);
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(filePath));
            Document document = new Document(pdfDoc);
            Table pdfTable = new Table(TableName.getColumns().size());
            
            
            for (TableColumn<?, ?> column : TableName.getColumns()) {
                pdfTable.addCell(column.getText());
            }
            
            for (Object item : TableName.getItems()) {
                
                for (TableColumn<?, ?> column : TableName.getColumns()) {
                /*this line is line:254*/
                    pdfTable.addCell(column.getCellData((int) item).toString());
                    
                }
            }
            document.add(pdfTable);
            document.close();
        } catch (Exception e) {
            System.out.println("Exception while downloading pdf tableView: "+e);
            e.printStackTrace();
        }
    }
}

This is the StackTrace:

Exception while downloading pdf tableView: java.lang.ClassCastException: class application.(className --> that is the controller of the fxml file where the download button is placed) cannot be cast to class java.lang.Integer (application.className(Controller) is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')
java.lang.ClassCastException: class application.className(Controller) cannot be cast to class java.lang.Integer (application.className(Controller) is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')
    at application.className(Controller).DownloadMethod(className(Controller).java:254)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:77)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at javafx.base@19.0.2.1/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml@19.0.2.1/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:84)
    at javafx.fxml@19.0.2.1/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1852)
    at javafx.fxml@19.0.2.1/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1724)
    at javafx.base@19.0.2.1/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@19.0.2.1/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base@19.0.2.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19.0.2.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19.0.2.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base@19.0.2.1/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics@19.0.2.1/javafx.scene.Node.fireEvent(Node.java:8923)
    at javafx.controls@19.0.2.1/javafx.scene.control.Button.fire(Button.java:203)
    at javafx.controls@19.0.2.1/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:207)
    at javafx.controls@19.0.2.1/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base@19.0.2.1/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base@19.0.2.1/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@19.0.2.1/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base@19.0.2.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19.0.2.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19.0.2.1/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@19.0.2.1/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base@19.0.2.1/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics@19.0.2.1/javafx.scene.Scene$MouseHandler.process(Scene.java:3894)
    at javafx.graphics@19.0.2.1/javafx.scene.Scene.processMouseEvent(Scene.java:1887)
    at javafx.graphics@19.0.2.1/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2620)
    at javafx.graphics@19.0.2.1/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
    at javafx.graphics@19.0.2.1/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics@19.0.2.1/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
    at javafx.graphics@19.0.2.1/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics@19.0.2.1/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
    at javafx.graphics@19.0.2.1/com.sun.glass.ui.View.handleMouseEvent(View.java:551)
    at javafx.graphics@19.0.2.1/com.sun.glass.ui.View.notifyMouse(View.java:937)
    at javafx.graphics@19.0.2.1/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics@19.0.2.1/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:833)

EDIT: 254 original code

 pdfTable.addCell(column.getCellData(item).toString());

but then It asked to cast argument item to int like this

 pdfTable.addCell(column.getCellData((int) item).toString());

Kindly help out to solve this.

devwebcl
  • 2,866
  • 3
  • 27
  • 46
  • If the slf4j stuff works then why is it in the question? Please keep the question focused—it’s unclear what the actual problem is. Is there an exception? Is the pdf file invalid? Both? How is slf4j involved? – Dave Newton Feb 09 '23 at 13:42
  • @DaveNewton Now the problem is ClassCastException as the title suggests and I mentioned all these details to make clear how it all went, and what I am trying to do. – Sarmad Ali Feb 09 '23 at 13:49
  • @DaveNewton And yes pdf file is still invalid not showing any content. – Sarmad Ali Feb 09 '23 at 13:52
  • If you find that you are missing some jar files, then add them to your project (pom/gradle/manually). – devwebcl Feb 09 '23 at 13:54
  • 1
    same comments as to your previous questions: [mcve] required, stick to java naming conventions .. – kleopatra Feb 09 '23 at 14:00
  • Obviously, `item`, which you get from iterating through `tableName.getItems()` is not an `int`. It's not clear what you want anyone to tell you that the stack trace is not already telling you. – James_D Feb 09 '23 at 14:15
  • @James_D I want to print the TableView as a pdf document containing all the data in the table – Sarmad Ali Feb 09 '23 at 14:20
  • Yes, we know that. But no-one can help you do that from the information you've provided. As previously suggested, create (probably from scratch) a [mre] and [edit] your question to include it. The question actually has nothing to do with creating a PDF; the error arises from trying to iterate through the table cells incorrectly. So your mre should have no code related to the PDF, just try to iterate through the cells in the table, and display the content in the console, for example. – James_D Feb 09 '23 at 14:23
  • If you use proper types for your `TableView`, instead of wildcards, and properly type `item`, instead of using `Object`, then you should be able to call [`column.getCellData(item)`](https://openjfx.io/javadoc/19/javafx.controls/javafx/scene/control/TableColumnBase.html#getCellData(S)) directly. – James_D Feb 09 '23 at 14:39
  • “How it went” isn’t related, and it’s very distracting. Questions should include only **relevant** information. – Dave Newton Feb 09 '23 at 14:40
  • @DaveNewton Accept my apologies dear. – Sarmad Ali Feb 09 '23 at 14:44
  • @James_D Will you please elaborate on it a little? – Sarmad Ali Feb 09 '23 at 14:47
  • What is there to elaborate on? Use the correct type for the table view, not a wildcard. Then you can use the same type for `item`, and consequently call the method I linked. That's all there is to it. – James_D Feb 09 '23 at 15:15
  • @James_D problem is here: for (int i = 0; i < TableName.getItems().size(); i++) { for (TableColumn column : TableName.getColumns()) { pdfTable.addCell(column.getCellData(i).toString()); }} this is the code that is causing a null exception – Sarmad Ali Feb 09 '23 at 15:44
  • And as I've already indicated, there is not enough information in the question to tell you why that is. As I said already, the problem is that you're not able to iterate through the cells in the table. Solve that problem in isolation, without any of the distraction of the PDF etc, and then incorporate it into your actual project. Create a new project from scratch which does nothing except create a table with some dummy data, iterates through the cells, and print their content to the console. If you get stuck with that, then post *that* project in the question. – James_D Feb 09 '23 at 15:55

2 Answers2

2
Exception while downloading pdf tableView: java.lang.ClassCastException: class application.(className --> that is the controller of the fxml file where the download button is placed) cannot be cast to class java.lang.Integer (application.className(Controller) is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')
java.lang.ClassCastException: class application.className(Controller) cannot be cast to class java.lang.Integer (application.className(Controller) is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')
    at application.className(Controller).DownloadMethod(className(Controller).java:254)

As this stack trace suggests, the error occurs because you are trying to cast the table item, which apparently is not an integer, to an integer at line number 254. Note that the method TableView#getItems returns an iterable object of type ObservableList<S>.

You need to fix the following line at the minimum: pdfTable.addCell(column.getCellData((int) item).toString());

It looks like you intend to add the index of the item in the table view rather than the item itself to your pdf table. Try this instead:

pdfTable.addCell(column.getCellData(TableName.getItems().indexOf(item)).toString());

VHS
  • 9,534
  • 3
  • 19
  • 43
  • pdfTable.addCell(column.getCellData(TableName.getItems().indexOf(item)).toString()); It didn't help. And I am trying to print all the items in Table not index, But Code Editor suggested me to cast item to int. – Sarmad Ali Feb 09 '23 at 14:10
  • when placing this code 'pdfTable.addCell(column.getCellData(TableName.getItems().indexOf(item)).toString());' it is giving NullPointerException 'java.lang.NullPointerException: Cannot invoke "Object.toString()" because the return value of "javafx.scene.control.TableColumn.getCellData(int)" is null at application.ClassName(controller).DownloadMethod(ClassName(controller).java:254)' – Sarmad Ali Feb 09 '23 at 14:17
  • 2
    @SarmadAli So why do you say "It didn't help"? It clearly did help, because the error you were originally getting went away. The fact that you got a different error means something else is also wrong in your code. – James_D Feb 09 '23 at 14:25
  • @James_D well, yes it helped indeed :) – Sarmad Ali Feb 09 '23 at 14:30
-1

Thanks to all! Special Thanks to @James_D

This is the code that is printing the pdf correctly.

@FXML
 public void DownloadButtonMethod(ActionEvent event) {
     
        DirectoryChooser directoryChooser = new DirectoryChooser();
        File selectedDirectory = directoryChooser.showDialog(TableName.getScene().getWindow());
        if (selectedDirectory == null) {
            return;
        }
        
        
        TextInputDialog dialog = new TextInputDialog("table");
        dialog.setTitle("Enter File Name");
        dialog.setHeaderText("Enter the name for the PDF file:");
        dialog.setContentText("File name:");
        Optional<String> result = dialog.showAndWait();
        
        if (result.isPresent()) {
            try {
                String fileName = result.get();
                if (!fileName.endsWith(".pdf")) {
                    fileName = fileName + ".pdf";
                }
                String filePath = selectedDirectory.getAbsolutePath() + "/" + fileName;
                OutputStream file = new FileOutputStream(filePath);
                PdfDocument pdfDoc = new PdfDocument(new PdfWriter(filePath));
                Document document = new Document(pdfDoc);
                Table pdfTable = new Table(TableName.getColumns().size());
                
                try {
                    
                for (TableColumn<ClassName(holds records), ?> column : TableName.getColumns()) {
                    pdfTable.addCell(column.getText());
                }
                
                }catch(Exception e) {
                    System.out.println("E1: "+e);
                    e.printStackTrace();
                }
                
                
                try {
                    
                    for (int i = 0; i < TableName.getItems().size(); i++) {
                        for (TableColumn<ClassName(holds records), ?> column : TableName.getColumns()) {
                            try {
                                pdfTable.addCell(column.getCellData(i).toString());
                            } catch (NullPointerException e) {
                                pdfTable.addCell("");
                            }
                        }
                    }
                    
                } catch(Exception e) {
                    System.out.println("E2: "+e);
                    e.printStackTrace();
                }
    
                document.add(pdfTable);
                document.close();
            } catch (Exception e) {
                System.out.println("Exception while downloading pdf tableView: "+e);
                e.printStackTrace();
            }
        }
    }

We have handled the NullPointerException by checking if the object is null, if yes then we have added the empty string to it so it couldn't throw a NullPointerException. And the ClassCastException was caused because when I was trying to cast an object to a type that it is not compatible with. Then I placed className(contains records: i.e variables, constructor, and getters and setters) as a type instead of using wildcards in TabelColumn as suggested by @James_D.

Thanks Again :)