All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.cmu.tetradapp.editor.LoadDataDialog Maven / Gradle / Ivy

The newest version!
///////////////////////////////////////////////////////////////////////////////
// For information as to what this class does, see the Javadoc, below.       //
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,       //
// 2007, 2008, 2009, 2010, 2014, 2015, 2022 by Peter Spirtes, Richard        //
// Scheines, Joseph Ramsey, and Clark Glymour.                               //
//                                                                           //
// This program is free software; you can redistribute it and/or modify      //
// it under the terms of the GNU General Public License as published by      //
// the Free Software Foundation; either version 2 of the License, or         //
// (at your option) any later version.                                       //
//                                                                           //
// This program is distributed in the hope that it will be useful,           //
// but WITHOUT ANY WARRANTY; without even the implied warranty of            //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             //
// GNU General Public License for more details.                              //
//                                                                           //
// You should have received a copy of the GNU General Public License         //
// along with this program; if not, write to the Free Software               //
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA //
///////////////////////////////////////////////////////////////////////////////
package edu.cmu.tetradapp.editor;

import edu.cmu.tetrad.data.DataModel;
import edu.cmu.tetrad.data.DataModelList;
import edu.cmu.tetrad.util.JOptionUtils;
import edu.pitt.dbmi.data.reader.preview.BasicDataPreviewer;
import edu.pitt.dbmi.data.reader.preview.DataPreviewer;
import edu.pitt.dbmi.data.reader.validation.ValidationResult;

import javax.swing.*;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.io.Serial;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;

import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;

/**
 * Panel (to be put in a dialog) for letting the user choose how a data file should be loaded.
 *
 * @author josephramsey
 * @version $Id: $Id
 */
public final class LoadDataDialog extends JPanel {

    @Serial
    private static final long serialVersionUID = 2299304318793152418L;

    /**
     * The files to be loaded.
     */
    private final List loadedFiles;

    /**
     * The validation results.
     */
    private final List validationResults;

    /**
     * The files that failed to load.
     */
    private final List failedFiles;

    /**
     * The data model list.
     */
    private final DataModelList dataModelList;

    /**
     * The text pane for the validation results.
     */
    private final JTextPane validationResultTextPane;

    /**
     * The text area for the file preview.
     */
    private final JTextArea filePreviewTextArea;

    /**
     * The line to start the preview from.
     */
    private final int previewFromLine;

    /**
     * The line to end the preview at.
     */
    private final int previewToLine;

    /**
     * The number of characters to show per line in the preview.
     */
    private final int previewNumOfCharactersPerLine;

    /**
     * The list model for the file list.
     */
    private final DefaultListModel fileListModel;

    /**
     * The list model for the validated file list.
     */
    private final DefaultListModel validatedFileListModel;

    /**
     * The default border title for the preview box.
     */
    private final String defaulyPreviewBoxBorderTitle;

    /**
     * The load data settings.
     */
    private LoadDataSettings loadDataSettings;

    /**
     * The file list.
     */
    private JList fileList;

    /**
     * The validation file list.
     */
    private JList validationFileList;

    /**
     * The loading indicator dialog.
     */
    private JDialog loadingIndicatorDialog;

    /**
     * The preview box border title.
     */
    private Box filePreviewBox;

    /**
     * The preview box border title.
     */
    private String previewBoxBorderTitle;

    /**
     * The container for the dialog.
     */
    private Box container;

    /**
     * The container for the preview.
     */
    private Box previewContainer;

    /**
     * The container for the file list.
     */
    private Box fileListBox;

    /**
     * The container for the validation results.
     */
    private Box basicSettingsBox;

    /**
     * The container for the validation results.
     */
    private Box advancedSettingsBox;

    /**
     * The container for the validation results.
     */
    private Box validationResultsContainer;

    /**
     * The settings button.
     */
    private JButton settingsButton;

    /**
     * The validate button.
     */
    private JButton validateButton;

    /**
     * The load button.
     */
    private JButton loadButton;

    //================================CONSTRUCTOR=======================//

    /**
     * 

Constructor for LoadDataDialog.

* * @param files a {@link java.io.File} object */ public LoadDataDialog(File... files) { // Add all files into the loadedFiles list - Zhou // Arrays.asList: Returns a fixed-size list backed by the specified array. // You can't add to it; you can't remove from it. You can't structurally modify the List. // Create a LinkedList, which supports remove(). this.loadedFiles = new LinkedList<>(Arrays.asList(files)); // List is an Interface, you cannot instantiate an Interface // ArrayList is an implementation of List which can be instantiated // The default size of ArrayList if 10 // Here we define validationResults as ArrayList for quick retrival by index this.validationResults = new ArrayList<>(); this.failedFiles = new ArrayList<>(); this.filePreviewTextArea = new JTextArea(); // Show preview from the first line to line 20, // only display up to 100 chars per line, // apend ... if longer than that this.previewFromLine = 1; this.previewToLine = 20; this.previewNumOfCharactersPerLine = 100; this.fileListModel = new DefaultListModel(); this.validatedFileListModel = new DefaultListModel(); this.defaulyPreviewBoxBorderTitle = "Data Preview: "; this.dataModelList = new DataModelList(); this.validationResultTextPane = new JTextPane(); this.loadingIndicatorDialog = new JDialog(); } //==============================PUBLIC METHODS=========================// /** *

showDataLoaderDialog.

* * @throws java.io.IOException if any. */ public void showDataLoaderDialog() throws IOException { // Overall container // contains data preview panel, loading params panel, and load button this.container = Box.createVerticalBox(); // Must set the size of container, otherwise validationResultsContainer gets shrinked this.container.setPreferredSize(new Dimension(900, 620)); // Data loading params // The data loading params apply to all slected files // the users should know that the selected files should share these settings - Zhou this.loadDataSettings = new LoadDataSettings(this.loadedFiles); // Basic settings this.basicSettingsBox = this.loadDataSettings.basicSettings(); // Advanced settings this.advancedSettingsBox = this.loadDataSettings.advancedSettings(); // Contains file list and format/options Box settingsContainer = Box.createVerticalBox(); settingsContainer.add(this.basicSettingsBox); settingsContainer.add(Box.createVerticalStrut(10)); settingsContainer.add(this.advancedSettingsBox); //advancedSettingsBox.setVisible(false); // Add some padding between settingsContainer and preview container settingsContainer.add(Box.createVerticalStrut(10)); // Add to overall container this.container.add(settingsContainer); // Preview container, contains file list and raw data preview this.previewContainer = Box.createHorizontalBox(); this.previewContainer.setPreferredSize(new Dimension(900, 250)); // Show all chosen files in a list for (File file : this.loadedFiles) { // Add each file name to the list model this.fileListModel.addElement(file.getName()); } this.fileList = new JList(this.fileListModel); // This mode specifies that only a single item can be selected at any point of time this.fileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // Default to select the first file in the list and show its preview this.fileList.setSelectedIndex(0); // List listener // use an anonymous inner class to implement the event listener interface this.fileList.addListSelectionListener((e) -> { if (!e.getValueIsAdjusting()) { int fileIndex = this.fileList.getMinSelectionIndex(); if (fileIndex < 0) { this.filePreviewBox.setBorder(new CompoundBorder(BorderFactory.createTitledBorder(this.defaulyPreviewBoxBorderTitle), new EmptyBorder(5, 5, 5, 5))); this.filePreviewTextArea.setText(""); } else { // Update the border title and show preview this.previewBoxBorderTitle = this.defaulyPreviewBoxBorderTitle + this.loadedFiles.get(fileIndex).getName(); this.filePreviewBox.setBorder(new CompoundBorder(BorderFactory.createTitledBorder(this.previewBoxBorderTitle), new EmptyBorder(5, 5, 5, 5))); setPreview(this.loadedFiles.get(fileIndex), this.filePreviewTextArea); } } }); // Right click mouse on file name to show the close option this.fileList.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); if (SwingUtilities.isRightMouseButton(e) || e.isControlDown()) { int index = LoadDataDialog.this.fileList.getSelectedIndex(); JPopupMenu menu = new JPopupMenu(); JMenuItem close = new JMenuItem("Remove this selected file from the loading list"); menu.add(close); Point point = e.getPoint(); menu.show(LoadDataDialog.this.fileList, point.x, point.y); close.addActionListener((evt) -> { // Can't remove if there's only one file left if (LoadDataDialog.this.loadedFiles.size() == 1) { JOptionPane.showMessageDialog(JOptionUtils.centeringComp(), "You can't remove when there's only one file."); } else { // Close tab to show confirmation dialog int selectedAction = JOptionPane.showConfirmDialog(JOptionUtils.centeringComp(), "Are you sure you want to remove this data file from the data loading list?", "Confirm", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); if (selectedAction == JOptionPane.OK_OPTION) { // Remove the file from list model LoadDataDialog.this.fileListModel.remove(index); // Also need to remove it from data structure // Shifts any subsequent elements to the left in the list System.out.println("Removing file of index = " + index + " from data loading list"); LoadDataDialog.this.loadedFiles.remove(index); // Reset the default selection and corresponding preview content LoadDataDialog.this.fileList.setSelectedIndex(0); setPreview(LoadDataDialog.this.loadedFiles.get(0), LoadDataDialog.this.filePreviewTextArea); } } }); } } }); // Put the list in a scrollable area JScrollPane fileListScrollPane = new JScrollPane(this.fileList); fileListScrollPane.setAlignmentX(Component.LEFT_ALIGNMENT); this.fileListBox = Box.createVerticalBox(); this.fileListBox.setMinimumSize(new Dimension(305, 250)); this.fileListBox.setMaximumSize(new Dimension(305, 250)); this.fileListBox.add(fileListScrollPane); // Add gap between file list and add new file button this.fileListBox.add(Box.createVerticalStrut(10)); // Add new files button JButton addFileButton = new JButton("Add more files to the loading list ..."); // Add file button listener addFileButton.addActionListener((e) -> { // Show file chooser JFileChooser fileChooser = new JFileChooser(); String sessionSaveLocation = Preferences.userRoot().get("fileSaveLocation", ""); fileChooser.setCurrentDirectory(new File(sessionSaveLocation)); fileChooser.resetChoosableFileFilters(); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); // Only allow to add one file at a time fileChooser.setMultiSelectionEnabled(true); // Customize dialog title bar text fileChooser.setDialogTitle("Add more files"); // The second argument sets both the title for the dialog window and the label for the approve button int _ret = fileChooser.showDialog(this.container, "Choose"); if (_ret == JFileChooser.CANCEL_OPTION) { return; } // File array that contains only one file File[] newFiles = fileChooser.getSelectedFiles(); // Add newly added files to the loading list for (File newFile : newFiles) { // Do not add the same file twice if (!this.loadedFiles.contains(newFile)) { this.loadedFiles.add(newFile); // Also add new file name to the file list model this.fileListModel.addElement(newFile.getName()); } } }); this.fileListBox.add(addFileButton); // Use a titled border with 5 px inside padding - Zhou final String fileListBoxBorderTitle = "Files (right click to remove selected file)"; this.fileListBox.setBorder(new CompoundBorder(BorderFactory.createTitledBorder(fileListBoxBorderTitle), new EmptyBorder(5, 5, 5, 5))); this.previewContainer.add(this.fileListBox); // Add some gap between file list and preview box this.previewContainer.add(Box.createHorizontalStrut(10), 1); this.filePreviewBox = Box.createVerticalBox(); this.filePreviewBox.setMinimumSize(new Dimension(585, 250)); this.filePreviewBox.setMaximumSize(new Dimension(585, 250)); // Setup file text area. // We don't want the users to edit in the preview area - Zhou this.filePreviewTextArea.setEditable(false); this.filePreviewTextArea.setFont(new Font("Monospaced", Font.PLAIN, 12)); // Set the default preview for the default selected file setPreview(this.loadedFiles.get(0), this.filePreviewTextArea); // Add the scrollable text area in a scroller JScrollPane filePreviewScrollPane = new JScrollPane(this.filePreviewTextArea); this.filePreviewBox.add(filePreviewScrollPane); // Add gap between preview text area and the help instruction this.filePreviewBox.add(Box.createVerticalStrut(10)); JLabel previewInstructionText = new JLabel(String.format("Showing from line %d to line %d, up to %d characters per line", this.previewFromLine, this.previewToLine, this.previewNumOfCharactersPerLine)); // Add the instruction this.filePreviewBox.add(previewInstructionText); // Show the default selected filename as preview border title this.previewBoxBorderTitle = this.defaulyPreviewBoxBorderTitle + this.loadedFiles.get(0).getName(); // Use a titled border with 5 px inside padding - Zhou this.filePreviewBox.setBorder(new CompoundBorder(BorderFactory.createTitledBorder(this.previewBoxBorderTitle), new EmptyBorder(5, 5, 5, 5))); // Add to preview container this.previewContainer.add(this.filePreviewBox); // Add to overall container this.container.add(this.previewContainer); // Validation result this.validationResultsContainer = Box.createVerticalBox(); Box validationSummaryBox = Box.createHorizontalBox(); JLabel validationSummaryText = new JLabel("Please review. You can change the settings or add/remove files by clicking the Settings button."); validationSummaryBox.add(validationSummaryText); Box validationResultsBox = Box.createHorizontalBox(); // A list of files to review Box filesToValidateBox = Box.createVerticalBox(); filesToValidateBox.setMinimumSize(new Dimension(305, 430)); filesToValidateBox.setMaximumSize(new Dimension(305, 430)); // Create a new list model based on validation results this.validationFileList = new JList(this.validatedFileListModel); // This mode specifies that only a single item can be selected at any point of time this.validationFileList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // List listener this.validationFileList.addListSelectionListener((e) -> { if (!e.getValueIsAdjusting()) { int fileIndex = this.validationFileList.getSelectedIndex(); // -1 means no selection if (fileIndex != -1) { setValidationResult(this.validationResults.get(fileIndex), this.validationResultTextPane); } } }); // Put the list in a scrollable area JScrollPane filesToValidateScrollPane = new JScrollPane(this.validationFileList); filesToValidateScrollPane.setAlignmentX(Component.LEFT_ALIGNMENT); filesToValidateBox.add(filesToValidateScrollPane); validationResultsBox.add(filesToValidateBox); // Add gap between file list and message content validationResultsBox.add(Box.createHorizontalStrut(10), 1); // Review content, contains errors or summary of loading Box validationMessageBox = Box.createVerticalBox(); validationMessageBox.setMinimumSize(new Dimension(560, 430)); validationMessageBox.setMaximumSize(new Dimension(560, 430)); this.validationResultTextPane.setContentType("text/html"); this.validationResultTextPane.setEditable(false); JScrollPane summaryScrollPane = new JScrollPane(this.validationResultTextPane); validationMessageBox.add(summaryScrollPane); validationResultsBox.add(validationMessageBox); // Put things into container this.validationResultsContainer.add(validationSummaryBox); this.validationResultsContainer.add(Box.createVerticalStrut(10)); this.validationResultsContainer.add(validationResultsBox); // Show the default selected filename as preview border title String validationResultsContainerBorderTitle = "Validate"; // Use a titled border with 5 px inside padding - Zhou this.validationResultsContainer.setBorder(new CompoundBorder(BorderFactory.createTitledBorder(validationResultsContainerBorderTitle), new EmptyBorder(5, 5, 5, 5))); // Add to overall container this.container.add(this.validationResultsContainer); // Hide by default this.validationResultsContainer.setVisible(false); // Buttons // Settings button this.settingsButton = new JButton("< Settings"); // Step 2 backward button listener this.settingsButton.addActionListener((e) -> { // Show file list this.fileListBox.setVisible(true); this.basicSettingsBox.setVisible(true); // Show options this.advancedSettingsBox.setVisible(true); // Show preview this.previewContainer.setVisible(true); // Hide summary this.validationResultsContainer.setVisible(false); // Hide step 1 backward button this.settingsButton.setVisible(false); // Show validate button this.validateButton.setVisible(true); // Hide finish button this.loadButton.setVisible(false); // Reset the list model this.validatedFileListModel.clear(); // Removes all elements for each new validation this.validationResults.clear(); // Also reset the failedFiles list this.failedFiles.clear(); }); // Validate button this.validateButton = new JButton("Validate >"); // Step 3 button listener this.validateButton.addActionListener((e) -> { // First we want to do some basic form validation/checks // to eliminate user errors List inputErrors = new ArrayList(); if (!this.loadDataSettings.isColumnLabelSpecified()) { inputErrors.add("- Please specify the column labels to ignore."); } if (!this.loadDataSettings.isOtherCommentMarkerSpecified()) { inputErrors.add("- Please specify the comment marker."); } // Show all errors in one popup if (!inputErrors.isEmpty()) { StringBuilder inputErrorMessages = new StringBuilder(); for (String error : inputErrors) { inputErrorMessages.append(error).append("\n"); } JOptionPane.showMessageDialog(this.container, inputErrorMessages.toString(), "Input Error", JOptionPane.ERROR_MESSAGE); return; } // Disable the button and change the button text this.validateButton.setEnabled(false); this.validateButton.setText("Validating ..."); // New thread to run the validation and hides the loading indicator // and shows the validation results once the validation process is done - Zhou new Thread(() -> { // Validate all files and set error messages validateAllFiles(); // Schedule a Runnable which will be executed on the Event Dispatching Thread // SwingUtilities.invokeLater means that this call will return immediately // as the event is placed in Event Dispatcher Queue, // and run() method will run asynchronously SwingUtilities.invokeLater(() -> { // Hide the loading indicator hideLoadingIndicator(); // Show result summary this.validationResultsContainer.setVisible(true); // Hide all inside settingsContainer this.fileListBox.setVisible(false); this.basicSettingsBox.setVisible(false); this.advancedSettingsBox.setVisible(false); // Use previewContainer instead of previewBox // since the previewContainer also contains padding this.previewContainer.setVisible(false); // Show step 2 backward button this.settingsButton.setVisible(true); // Hide validate button this.validateButton.setVisible(false); // Show finish button this.loadButton.setVisible(true); // Determine if enable the finish button or not // Disable it // Enable it this.loadButton.setEnabled(this.failedFiles.size() <= 0); // Enable the button and hange back the button text this.validateButton.setEnabled(true); this.validateButton.setText("Validate >"); }); }).start(); // Create the loading indicator dialog and show showLoadingIndicator("Validating...", e); }); // Load button this.loadButton = new JButton("Load"); // Load data button listener this.loadButton.addActionListener((e) -> { // Change button text this.loadButton.setEnabled(false); this.loadButton.setText("Loading ..."); // Load all data files and hide the loading indicator once done new Thread(() -> { try { // Load all data files via data reader loadAllFiles(); } catch (IOException ex) { Logger.getLogger(LoadDataDialog.class.getName()).log(Level.SEVERE, null, ex); } // Schedule a Runnable which will be executed on the Event Dispatching Thread // SwingUtilities.invokeLater means that this call will return immediately // as the event is placed in Event Dispatcher Queue, // and run() method will run asynchronously SwingUtilities.invokeLater(() -> { // Hide the loading indicator hideLoadingIndicator(); // Close the data loader dialog Window w = SwingUtilities.getWindowAncestor(this.loadButton); if (w != null) { w.setVisible(false); } }); }).start(); // Create the loading indicator dialog and show showLoadingIndicator("Loading...", e); }); // Buttons container Box buttonsContainer = Box.createVerticalBox(); // Add some padding between preview/summary and buttons container buttonsContainer.add(Box.createVerticalStrut(20)); // Buttons box Box buttonsBox = Box.createHorizontalBox(); buttonsBox.add(this.settingsButton); // Don't use Box.createHorizontalStrut(20) buttonsBox.add(Box.createRigidArea(new Dimension(20, 0))); buttonsBox.add(this.validateButton); buttonsBox.add(Box.createRigidArea(new Dimension(20, 0))); buttonsBox.add(this.loadButton); // Default to only show step forward button this.settingsButton.setVisible(false); this.loadButton.setVisible(false); // Add to buttons container buttonsContainer.add(buttonsBox); // Add to overall container // container.add(buttonsContainer); JPanel mainPanel = new JPanel(new BorderLayout()); mainPanel.add(this.container, BorderLayout.CENTER); mainPanel.add(buttonsContainer, BorderLayout.SOUTH); // Dialog without dialog buttons, because we use Load button to handle data loading // If we use the buttons come with JOptionPane.showOptionDialog(), the data loader dialog // will close automatically once we click one of the buttons. // We don't want to do this. We want to keep the data loader dialog in the backgroud of the // logging info dialog and close it if all files are loaded successfully. // Otherwise, still keep the data loader dialog there if fail to load any files - Zhou // Here no need to use the returned value since we are not handling the action buttons JOptionPane.showOptionDialog(JOptionUtils.centeringComp(), mainPanel, "Data File Loader", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, new Object[]{}, null); } /** * Create the loading indicator dialog and show */ private void showLoadingIndicator(String message, ActionEvent evt) { JProgressBar progressBar = new JProgressBar(0, 100); // An indeterminate progress bar continuously displays animation progressBar.setIndeterminate(true); Box dataLoadingIndicatorBox = Box.createVerticalBox(); dataLoadingIndicatorBox.setPreferredSize(new Dimension(200, 60)); JLabel label = new JLabel(message); // JLabel label = new JLabel(message, SwingConstants.CENTER); doesn't label.setAlignmentX(Component.CENTER_ALIGNMENT); Box progressBarBox = Box.createHorizontalBox(); progressBarBox.add(Box.createRigidArea(new Dimension(10, 1))); progressBarBox.add(progressBar); progressBarBox.add(Box.createRigidArea(new Dimension(10, 1))); // Put the label on top of progress bar dataLoadingIndicatorBox.add(Box.createVerticalStrut(10)); dataLoadingIndicatorBox.add(label); dataLoadingIndicatorBox.add(Box.createVerticalStrut(10)); dataLoadingIndicatorBox.add(progressBarBox); Frame ancestor = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, (Component) evt.getSource()); // Set modal true to block user input to other top-level windows when shown this.loadingIndicatorDialog = new JDialog(ancestor, true); // Remove the whole dialog title bar this.loadingIndicatorDialog.setUndecorated(true); this.loadingIndicatorDialog.getContentPane().add(dataLoadingIndicatorBox); this.loadingIndicatorDialog.pack(); this.loadingIndicatorDialog.setLocationRelativeTo(JOptionUtils.centeringComp()); this.loadingIndicatorDialog.setVisible(true); } /** * Hide the loading indicator */ private void hideLoadingIndicator() { this.loadingIndicatorDialog.setVisible(false); // Also release all of the native screen resources used by this dialog this.loadingIndicatorDialog.dispose(); } /** * Validate files with specified settings */ private void validateAllFiles() { for (File loadedFile : this.loadedFiles) { try { StringBuilder strBuilder = new StringBuilder(); strBuilder.append("

Validation result of "); strBuilder.append(loadedFile.getName()); strBuilder.append(":> 0"); List results = this.loadDataSettings.validateDataWithSettings(loadedFile); List infos = new LinkedList<>(); List warnings = new LinkedList<>(); List errors = new LinkedList<>(); for (ValidationResult result : results) { switch (result.getCode()) { case INFO: infos.add(result); break; case WARNING: warnings.add(result); break; default: errors.add(result); } } // Show some file info if (!infos.isEmpty()) { strBuilder.append("

File info:
"); infos.forEach(e -> { strBuilder.append(e.getMessage()); strBuilder.append("
"); }); strBuilder.append("> 0"); } // Show warning messages int validationWarnErrMsgThreshold = 10; if (!warnings.isEmpty()) { int warnCount = warnings.size(); strBuilder.append("

Warning (total "); strBuilder.append(warnCount); if (warnCount > validationWarnErrMsgThreshold) { strBuilder.append(", showing the first "); strBuilder.append(validationWarnErrMsgThreshold); strBuilder.append("):
"); warnings.subList(0, validationWarnErrMsgThreshold).forEach(e -> { strBuilder.append(e.getMessage()); strBuilder.append("
"); }); } else { strBuilder.append("):
"); warnings.forEach(e -> { strBuilder.append(e.getMessage()); strBuilder.append("
"); }); } strBuilder.append("> 0"); } // Show errors if found if (!errors.isEmpty()) { int errorCount = errors.size(); String errorCountString = (errorCount > 1) ? " errors" : " error"; strBuilder.append("

Validation failed!
Please fix the following "); if (errorCount > validationWarnErrMsgThreshold) { strBuilder.append(validationWarnErrMsgThreshold); strBuilder.append(errorCountString); strBuilder.append(" (total "); strBuilder.append(errorCount); strBuilder.append(") and validate again:

"); errors.subList(0, validationWarnErrMsgThreshold).forEach(e -> { // Remember to excape the html tags if the data file contains any strBuilder.append(escapeHtml4(e.getMessage())); strBuilder.append("
"); }); } else { strBuilder.append(errorCount); strBuilder.append(errorCountString); strBuilder.append(" and validate again:
"); errors.forEach(e -> { // Remember to excape the html tags if the data file contains any strBuilder.append(escapeHtml4(e.getMessage())); strBuilder.append("
"); }); } strBuilder.append("> 0"); // Also add the file name to failed list // this determines if to show the Load button this.failedFiles.add(loadedFile.getName()); } else if (loadedFile.length() == 0) { // We don't allow users to load empty file strBuilder.append("

This is an empty data file!> 0"); // Also add the file name to failed list // this determines if to show the Load button this.failedFiles.add(loadedFile.getName()); } else { strBuilder.append("

Validation passed with no error!> 0"); } this.validationResults.add(strBuilder.toString()); } catch (IOException ex) { Logger.getLogger(LoadDataDialog.class.getName()).log(Level.SEVERE, null, ex); } } showValidationResults(); } private void showValidationResults() { // Create the validation file list with marker prefix // so users know if this file passed the validation or not // just by looking at the file name prefix - Zhou for (File loadedFile : this.loadedFiles) { // Default to the check mark String unicodePrefix = "\u2713"; if (this.failedFiles.contains(loadedFile.getName())) { // Cross mark unicodePrefix = "\u2717"; } // Add the unicode marker this.validatedFileListModel.addElement("[" + unicodePrefix + "] " + loadedFile.getName()); } // Set the default selected file // that's why we don't set the default selection when creating the JList this.validationFileList.setSelectedIndex(0); // Display validation result of the first file by default setValidationResult(this.validationResults.get(0), this.validationResultTextPane); } /** * Add all files to model once all can be loaded successfully */ private void loadAllFiles() throws IOException { // Try to load each file and store the file name for failed loading for (int i = 0; i < this.loadedFiles.size(); i++) { DataModel dataModel = this.loadDataSettings.loadDataWithSettings(this.loadedFiles.get(i)); // Add to dataModelList for further use if (dataModel != null) { // Must setName() here, file names will be used by the spreadsheet - Zhou dataModel.setName(this.loadedFiles.get(i).getName()); this.dataModelList.add(dataModel); System.out.println("File index = " + i + " has been loaded successfully"); } } } /** * This is called by LoadDataAction.java * * @return a {@link edu.cmu.tetrad.data.DataModelList} object */ public DataModelList getDataModels() { return this.dataModelList; } /** * Set the validation result content */ private void setValidationResult(String output, JTextPane textPane) { // Wrap the output in html textPane.setText(""); // Scroll back to top left textPane.setCaretPosition(0); } /** * Set the file preview content */ private void setPreview(File file, JTextArea textArea) { try { textArea.setText(""); DataPreviewer dataPreviewer = new BasicDataPreviewer(file.toPath()); List linePreviews = dataPreviewer.getPreviews(this.previewFromLine, this.previewToLine, this.previewNumOfCharactersPerLine); for (String line : linePreviews) { textArea.append(line + "\n"); } textArea.setCaretPosition(0); } catch (IOException ex) { Logger.getLogger(LoadDataDialog.class.getName()).log(Level.SEVERE, null, ex); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy