1

I have a JavaFX application whose main job is to display different tables containing data loaded from CSV files. I can read CSV files into TableViews with no problems, and export them to CSVs as well. My problem is displaying the different TableViews.

When I load from a CSV into a TableView, I want to save that TableView for future processing. I also want to display a table showing the newly loaded data. My strategy is to have a global TableView, call it table, that is added to the main VBox, and update its contents to contain (and hence display) the elements of whichever TableView I just created by reading a file.

Is this a bad idea? It seems like a simple concept to me, but I can't find a way to easily "clone" the chosen TableView - i.e. transfer its contents to my displayed TableView called table.

My simple attempt at cloning TableViews is shown here. I also tried writing an extensive equateTable() method, which went nowhere.

//WHY DOESN'T THIS WORK?
table.setItems(reqTable.getItems());

Here's the rest of the code. Thanks to anyone who answers!

package FLOOR;

import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Callback;

// --- Main Class
public class Main extends Application {

// --- All Tables
TableView<ObservableList<StringProperty>> reqTable = new TableView<>();
TableView<ObservableList<StringProperty>> tempTable = new TableView<>();
TableView<ObservableList<StringProperty>> ontTable = new TableView<>();

// --- Display Table
TableView<ObservableList<StringProperty>> table = new TableView<>();

// --- Main
public static void main(String[] args) {
    launch(args);
}

// --- Start
@Override
public void start(Stage stage) {
    // --- Stage & Scene
    stage.setTitle("FLOOR");
    Scene scene = new Scene(new VBox(), 900, 500);
    MenuBar menuBar = new MenuBar();

    // --- VBox
    final VBox vbox = new VBox();
    vbox.setAlignment(Pos.CENTER);
    vbox.setSpacing(10);
    vbox.setPadding(new Insets(0, 10, 0, 10));
    vbox.getChildren().addAll(table);
    table.setVisible(false);

    // --- Menus 
    // --- File Menu
    // --- Import Submenu
    Menu menuFile = new Menu("File");
    Menu importMenu = new Menu("Import");
    MenuItem reqOption = new MenuItem("Requirements");
    MenuItem tempOption = new MenuItem("Templates");
    MenuItem ontOption = new MenuItem("Ontologies");
    importMenu.getItems().addAll(reqOption, tempOption, ontOption);

    //Import Requirements
    reqOption.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent e) {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("Select Requirements CSV");
            File file = fileChooser.showOpenDialog(stage);
            if (file != null) {
                populateTable(reqTable, file.getAbsolutePath());
            }
            getRequirementsPage();
        }
    });

    //Import Templates
    tempOption.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent e) {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("Select Templates CSV");
            File file = fileChooser.showOpenDialog(stage);
            if (file != null) {
                populateTable(tempTable, file.getAbsolutePath());
            }
            getTemplatesPage();
        }
    });

    //Import Ontologies
    ontOption.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent e) {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("Select Ontology CSV");
            File file = fileChooser.showOpenDialog(stage);
            if (file != null) {
                populateTable(ontTable, file.getAbsolutePath());
            }
            getOntologiesPage();
        }
    });

    //Export
    MenuItem export = new MenuItem("Export");
    export.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent t) {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("Save Requirements CSV");
            File file = fileChooser.showSaveDialog(stage);
            if (file != null) {
                exportTable(reqTable, file.getAbsolutePath());
            }
        }
    });

    //Exit
    MenuItem exit = new MenuItem("Exit");
    exit.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent t) {
            System.exit(0);
        }
    });
    menuFile.getItems().addAll(importMenu, export, new SeparatorMenuItem(), exit);

    // --- Menu Bar
    menuBar.getMenus().addAll(menuFile);

    // --- Show FLOOR
    ((VBox) scene.getRoot()).getChildren().addAll(menuBar, vbox);
    stage.setScene(scene);
    stage.show();
}

// --- Methods
// Table Getters
private void getRequirementsPage() {
    table.getItems().clear();
    //WHY DOESN'T THIS WORK?
    table.setItems(reqTable.getItems());
    table.setVisible(true);
}
private void getTemplatesPage() {
    table.getItems().clear();
    table.setItems(tempTable.getItems());
    table.setVisible(true);
}
private void getOntologiesPage() {
    table.getItems().clear();
    table.setItems(ontTable.getItems());
    table.setVisible(true);
}

//populateTable
private void populateTable(
        final TableView<ObservableList<StringProperty>> table,
        final String filename) {
    table.getItems().clear();
    table.getColumns().clear();
    table.setPlaceholder(new Label("Loading..."));
    Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            CSVReader reader = new CSVReader(new FileReader(filename));
            String [] nextLine;
            int count = 1;
            while ((nextLine = reader.readNext()) != null) {
                if (count == 1) {
                    final String[] headers = nextLine;
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            for (int column = 0; column < headers.length; column++) {
                                table.getColumns().add(
                                        createColumn(column, headers[column]));
                            }
                        }
                    });
                } else {
                    final String[] dataValues = nextLine;
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            // Add additional columns if necessary:
                            for (int columnIndex = table.getColumns().size(); columnIndex < dataValues.length; columnIndex++) {
                                table.getColumns().add(createColumn(columnIndex, ""));
                            }
                            // Add data to table:
                            ObservableList<StringProperty> data = FXCollections
                                    .observableArrayList();
                            for (String value : dataValues) {
                                data.add(new SimpleStringProperty(value));
                            }
                            table.getItems().add(data);
                        }
                    });
                }
                count++;
            }
            reader.close();
            return null;
        }
    };
    Thread thread = new Thread(task);
    thread.setDaemon(true);
    thread.start();
}

//exportTable
private void exportTable(
        final TableView<ObservableList<StringProperty>> table,
        final String filename) {
    Task<Void> task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            CSVWriter writer = null;
            try {
                writer = new CSVWriter(new FileWriter(filename), ',');
            } catch (IOException e) {
                e.printStackTrace();
            }
            int numRows = table.getItems().size();
            int numCols = table.getColumns().size();
            String[] dataWrite = new String[numCols];
            for (int i = 0; i < numRows; i++) {
                for (int j = 0; j < numCols; j++) {
                    dataWrite[j] = table.getItems().get(i).get(j).getValue();
                }
                writer.writeNext(dataWrite);
            }
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    };
    Thread thread = new Thread(task);
    thread.setDaemon(true);
    thread.start();
}

//createColumn
private TableColumn<ObservableList<StringProperty>, String> createColumn(
        final int columnIndex, String columnTitle) {
    TableColumn<ObservableList<StringProperty>, String> column = new TableColumn<>();
    String title;
    if (columnTitle == null || columnTitle.trim().length() == 0) {
        title = "Column " + (columnIndex + 1);
    } else {
        title = columnTitle;
    }
    column.setText(title);
    column
    .setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<StringProperty>, String>, ObservableValue<String>>() {
        @Override
        public ObservableValue<String> call(
                CellDataFeatures<ObservableList<StringProperty>, String> cellDataFeatures) {
            ObservableList<StringProperty> values = cellDataFeatures.getValue();
            if (columnIndex >= values.size()) {
                return new SimpleStringProperty("");
            } else {
                return cellDataFeatures.getValue().get(columnIndex);
            }
        }
    });
    return column;
}

}

Ted
  • 45
  • 4

0 Answers0