0

I am trying to compare HIVE and Oracle table data using a desktop GUI application, so I used JavaFX and built the app, am able to get the user entered data from the forms and execute it in backend and get the resultset however I am not able to print the result set in the ResultSet tab of the application I have tried the methods used here and browsed few other stack questions but as am new to JFX am not able to get how to print a result set into the scene

enter image description here

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<TabPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1100.0" tabClosingPolicy="UNAVAILABLE" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.40"
fx:controller="application.Controller">
<tabs>
<Tab text="Query Tab">
  <content>
    <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
           <children>
              <TextArea layoutX="34.0" layoutY="143.0" prefHeight="506.0" prefWidth="360.0" promptText="Hive Query" fx:id="HiveQuery" />
              <TextArea layoutX="506.0" layoutY="141.0" prefHeight="508.0" prefWidth="384.0" promptText="Oracle Query" fx:id="OracleQuery" />
              <TextField layoutX="34.0" layoutY="27.0" promptText="Hive Server Name" fx:id="HiveServerName" />
              <TextField layoutX="34.0" layoutY="79.0" promptText="Hive Username" fx:id="HiveUserName" />
              <PasswordField layoutX="204.0" layoutY="79.0" promptText="Hive Password" fx:id="HivePassword" />
              <PasswordField layoutX="698.0" layoutY="79.0" promptText="Oracle Password" fx:id="OraclePassword" />
              <TextField layoutX="521.0" layoutY="79.0" promptText="Oracle Username" fx:id="OracleUserName" />
              <TextField layoutX="521.0" layoutY="27.0" promptText="Oracle HostName" fx:id="OracleHostName" />
              <Button layoutX="420.0" layoutY="666.0" mnemonicParsing="false" text="Compare" fx:id="CompareButton" onAction="#CompareDataSets" />
           </children></AnchorPane>
  </content>
</Tab>
<Tab text="Result Set">
  <content>
    <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
           <children>
              <TableView layoutX="8.0" layoutY="19.0" prefHeight="671.0" prefWidth="433.0">
                <columns>
                  <TableColumn prefWidth="75.0" text="C1" />
                  <TableColumn prefWidth="75.0" text="C2" />
                </columns>
              </TableView>
              <TableView layoutX="463.0" layoutY="19.0" prefHeight="671.0" prefWidth="448.0">
                <columns>
                  <TableColumn prefWidth="75.0" text="C1" />
                  <TableColumn prefWidth="75.0" text="C2" />
                </columns>
              </TableView>
           </children></AnchorPane>
  </content>
</Tab>

3
  • Can you show what you have tried to display your data? The code you posted is just the layout. Commented Jan 5, 2016 at 13:46
  • @James_D: Yes, following the link mentioned above I created a separate class and passed the login values to one more class which returns the resultset from oracle and hive... However a new stage/window opens instead of printing in this tab (the table can have any number of columns) Commented Jan 5, 2016 at 13:52
  • I guess I need to give a id to table view in fxml and use that in controller but since my table is not of fixed columns I am not exactly sure how to do it Commented Jan 5, 2016 at 13:58

1 Answer 1

1

Following the example you linked to above you can perform the same logic, with a few minor tweaks.... First name your tableView in the FXML, and second, remove the columns that are present so that you only have the tableView.

<Tab text="Result Set">
  <content>
    <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
           <children>
              <TableView fx:id="tableView" layoutX="8.0" layoutY="19.0" prefHeight="671.0" prefWidth="433.0">
                <columns>
                </columns>
              </TableView>
              ......
           </children></AnchorPane>
  </content>
</Tab>

Then update your controller:

//Name your table view in your FXML file and wire it like this.
@FXML
private TableView tableview;

//Then in your method where you process the data you can add columns dynamically....
        /**********************************
         * TABLE COLUMN ADDED DYNAMICALLY *
         **********************************/
        for(int i=0 ; i<rs.getMetaData().getColumnCount(); i++){
            //We are using non property style for making dynamic table
            final int j = i;                
            TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i+1));
            col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList,String>,ObservableValue<String>>(){                    
                public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {                                                                                              
                    return new SimpleStringProperty(param.getValue().get(j).toString());                        
                }                    
            });

            tableview.getColumns().addAll(col); 
            System.out.println("Column ["+i+"] ");
        }

//Etc....

This is how you can add your columns dynamically to the tableview laid out in the FXML.

Sign up to request clarification or add additional context in comments.

7 Comments

now I am able to see the table headers in the required place but there are two issues now: 1. All columns are not printed, tableview does not become scrollable instead if I increase the window size and run again more columns are visible. 2. After headers no rows are printed NPE is throw: Trying to compare data.... Column [0] ... Column [21] Row [1] added [100777073, null, null, Y, ...] Exception in thread "JavaFX Application Thread" java.lang.NullPointerException at application.Controller$1.call(Controller.java:86) at application.Controller$1.call(Controller.java:1)
return new SimpleStringProperty(param.getValue().get(j).toString()); is the 86th line in the controller
Check to make sure the value you are returning isn't null.. perhaps something like if (param.getValue().get(j).toString()) != null then return new SimpleStringProperty(param.getValue().get(j).toString()); else return SimpleStringProperty(""); Another trick I have learned is to force the table to repaint if things aren't displayed correctly. I have at times had to set a column invisible and then visible again. tableColumn.setVisible(false); tableColumn.setVisible(true); This can correct a visual display issue.
Sorry - the if statement would be this: if (param.getValue().get(j)) != null) -- we can't call toString() on a null reference.
Yaa... You are right... That row does have null... Can we substitute null as blank instead of ignoring it?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.