ch.unibas.fittingwizard.presentation.MoleculeListPage.java Source code

Java tutorial

Introduction

Here is the source code for ch.unibas.fittingwizard.presentation.MoleculeListPage.java

Source

/*
 * Copyright (c) 2015, Florent Hedin, Markus Meuwly, and the University of Basel
 * All rights reserved.
 *
 * The 3-clause BSD license is applied to this software.
 * see LICENSE.txt
 *
 */
package ch.unibas.fittingwizard.presentation;

import ch.unibas.fittingwizard.application.Visualization;
import ch.unibas.fittingwizard.application.base.MoleculesDir;
import ch.unibas.fittingwizard.application.fitting.FitRepository;
import ch.unibas.fittingwizard.application.molecule.Molecule;
import ch.unibas.fittingwizard.application.molecule.MoleculeId;
import ch.unibas.fittingwizard.application.molecule.MoleculeRepository;
import ch.unibas.fittingwizard.application.xyz.XyzFile;
import ch.unibas.fittingwizard.application.xyz.XyzFileParser;
import ch.unibas.fittingwizard.presentation.addmolecule.AtomChargesDto;
import ch.unibas.fittingwizard.presentation.addmolecule.AtomTypeChargePage;
import ch.unibas.fittingwizard.presentation.addmolecule.SelectCoordinateFilePage;
import ch.unibas.fittingwizard.presentation.base.ButtonFactory;
import ch.unibas.fittingwizard.presentation.base.WizardPageWithVisualization;
import ch.unibas.fittingwizard.presentation.base.dialog.OverlayDialog;
import ch.unibas.fittingwizard.presentation.fitting.FitResultPage;
import ch.unibas.fittingwizard.presentation.fitting.FittingParameterPage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.DirectoryChooser;
import org.apache.commons.io.FileUtils;

public class MoleculeListPage extends WizardPageWithVisualization {

    private final MoleculeRepository moleculeRepository;
    private final FitRepository fitRepository;
    private final MoleculesDir moleculeDir;

    @FXML
    private TableView<Molecule> moleculesTable;
    @FXML
    private TableColumn<Molecule, String> nameColumn;

    @FXML
    private Button addButton;
    @FXML
    private Button displayButton;
    @FXML
    private Button editButton;
    @FXML
    private Button removeButton;
    @FXML
    private Button goToResultsButton;
    @FXML
    private Button loadExistingButton;

    private Molecule selectedMolecule;
    private Button fittingParameterButton;

    public MoleculeListPage(Visualization visualization, MoleculeRepository moleculeRepository,
            FitRepository fitRepository, MoleculesDir moleculesDir) {
        super(visualization, "Molecule list");
        this.moleculeRepository = moleculeRepository;
        this.fitRepository = fitRepository;
        this.moleculeDir = moleculesDir;
        setupMoleculesTable();
        setupButtons();
    }

    private void setupMoleculesTable() {
        moleculesTable.getItems().addListener(new ListChangeListener<Molecule>() {
            @Override
            public void onChanged(Change<? extends Molecule> change) {
                boolean hasMolecules = change.getList().size() > 0;
                fittingParameterButton.setDisable(!hasMolecules);
            }
        });
        moleculesTable.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Molecule>() {
            @Override
            public void changed(ObservableValue observableValue, Molecule o, Molecule o2) {
                selectedMolecule = o2;
                displayButton.setDisable(selectedMolecule == null);
                editButton.setDisable(selectedMolecule == null);
                removeButton.setDisable(selectedMolecule == null);
            }
        });
        nameColumn.setCellValueFactory(new PropertyValueFactory<Molecule, String>("description"));
    }

    private void setupButtons() {
        goToResultsButton.setDisable(fitRepository.getFitCount() == 0);
    }

    @Override
    public void initializeData() {
        fillMoleculeTable();
    }

    private void fillMoleculeTable() {
        selectedMolecule = null;
        ArrayList<Molecule> molecules = moleculeRepository.loadAll();
        moleculesTable.getItems().clear();
        moleculesTable.getItems().addAll(molecules);
    }

    protected void fillButtonBar() {
        fittingParameterButton = ButtonFactory.createButtonBarButton("Define fitting parameters",
                new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent actionEvent) {
                        logger.info("Defining fitting parameter.");

                        navigateTo(FittingParameterPage.class);
                    }
                });
        fittingParameterButton.setDisable(true);
        addButtonToButtonBar(fittingParameterButton);
    }

    public void handleAddAction(ActionEvent event) {
        logger.info("Adding new molecule.");
        navigateTo(SelectCoordinateFilePage.class);
    }

    public void handleRemoveAction(ActionEvent event) {
        if (selectedMolecule != null) {
            String message = String.format("Do you really want to remove molecule %s?",
                    selectedMolecule.getDescription());
            if (OverlayDialog.askYesOrNo(message)) {
                logger.info("Remove selected molecule.");
                moleculeRepository.remove(selectedMolecule);
                fillMoleculeTable();
            }
        }
    }

    public void handleEditAction(ActionEvent event) {
        logger.info("Edit selected molecule.");
        if (selectedMolecule != null) {
            navigateTo(AtomTypeChargePage.class, new AtomChargesDto(selectedMolecule));
        }
    }

    public void handleDisplayAction(ActionEvent event) {
        logger.info("Display selected molecule.");
        if (selectedMolecule != null) {
            visualization.show(selectedMolecule.getXyzFile().getSource());
        }
    }

    public void handleGoToResults(ActionEvent event) {
        logger.info("Going to fitting results.");
        navigateTo(FitResultPage.class);
    }

    public void handleLoadExisting(ActionEvent event) {
        logger.info("Loading existing molecule.");

        DirectoryChooser chooser = new DirectoryChooser();
        chooser.setInitialDirectory(moleculeDir.getDirectory());
        chooser.setTitle("Please select a molecule.");
        File selectedDir = chooser.showDialog(this.getScene().getWindow());
        if (selectedDir == null) {
            logger.info("User skipped.");
            return;
        }

        String moleculeName = selectedDir.getName();
        if (moleculeRepository.checkIfExists(new MoleculeId(moleculeName))) {
            logger.info("Molecule already loaded.");
            OverlayDialog.informUser("Molecule already loaded!",
                    "The selected molecule was already loaded. Please select another molecule.");
            return;
        }

        File xyzFile = new File(selectedDir.getParentFile(), moleculeName + ".xyz");
        if (!xyzFile.isFile()) {
            logger.error("XYZ file not found. Skipping.");
            String format = String.format("No xyz file (%s) found for selected molecule %s.",
                    xyzFile.getAbsolutePath(), moleculeName);
            OverlayDialog.showError("Could not load molecule", format);
            return;
        }

        xyzFile = copyFilesToMoleculesDir(selectedDir, xyzFile);

        XyzFile parse = null;
        try {
            parse = XyzFileParser.parse(xyzFile);
        } catch (Exception e) {
            OverlayDialog.showError("Could not load molecule",
                    "Error while parsing the xyz file " + xyzFile.getAbsolutePath());
        }

        navigateTo(AtomTypeChargePage.class, new AtomChargesDto(parse));
    }

    private File copyFilesToMoleculesDir(File selectedDir, File xyzFile) {
        boolean isAlreadyInMoleculeDir = moleculeDir.contains(selectedDir);
        if (!isAlreadyInMoleculeDir) {
            logger.info("Molecule files are not in molecules directory. Copying files to directory.");
            try {
                FileUtils.copyDirectoryToDirectory(selectedDir, moleculeDir.getDirectory());
                FileUtils.copyFileToDirectory(xyzFile, moleculeDir.getDirectory());
            } catch (IOException e) {
                throw new RuntimeException("Could not copy files to molecule directory.");
            }
        }
        return xyzFile;
    }
}