package gui.main; import gui.settings.Settings; import gui.settings.SettingsDialog; import importexport.ExportLogic; import importexport.ImportLogic; import importexport.util.InvalidFileException; import importexport.util.UnsupportedFileExtensionException; import java.awt.Checkbox; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.filechooser.FileNameExtensionFilter; import db.Database; import db.DatabaseAccessException; import db.IncompatibleVersionException; import db.InvalidDriverException; /** * MenuPanel class holds the most basic functions of the program. Can be used to change current workspace, data file, * options. Enables the user to export/import data and to see information about the program. */ public class MenuPanel extends JPanel { private static final long serialVersionUID = 2913009660116831977L; /** * Reference to MainWindow. */ private final MainWindow mainWindow; /** * Button for changing the workspace. */ private JButton newButton; /** * Button for importing a file. */ private JButton importButton; /** * Button for exporting data in a file. */ private JButton exportButton; /** * Button showing information about the program. */ private JButton infoButton; /** * Button showing the settings dialog */ private JButton settingsButton; /** * ResourceBundle for the Strings. */ private final ResourceBundle rb; /** * Defines what is done when changing the workspace. */ private NewWSAction newWS; /** * Defines what is done when importing. */ private ImportAction importAction; /** * Defines what is done when viewing information. */ private InfoAction infoAction; /** * Defines what is done when exporting. */ private ExportAction exportAction; private SettingsAction settingsAction; private String path; private boolean flag; /** * Info dialog */ private final InfoDialog idialog; /** * Constructor. * * @param mainWindow * Reference to the MainWindow. */ public MenuPanel(MainWindow mainWindow) { super(); if (mainWindow == null) { throw new IllegalArgumentException("Argument cannot be null"); } this.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.GRAY)); this.setLayout(new FlowLayout(FlowLayout.LEADING, 8, 5)); this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); this.mainWindow = mainWindow; this.rb = Settings.getInstance().getResourceBundle(); flag = true; initActions(); initButtons(); this.idialog = new InfoDialog(EventController.getInstance().getRootFrame()); this.add(Box.createHorizontalStrut(6)); this.add(newButton); this.add(importButton); this.add(exportButton); this.add(settingsButton); this.add(infoButton); } /** * Create new workspace. */ public void newWorkspace() { this.newButton.doClick(); } /** * Loads a new database, starts the import logic if the database is empty and finally loads the project UI. * * @param path * the path for the database */ public void loadDatabase(String path) { Database db = null; try { db = new Database(path); MainWindow.curBSVFile = path; } catch (InvalidDriverException e2) { JOptionPane.showMessageDialog(mainWindow, rb.getString("DatabaseBadDriver"), rb.getString("error"), JOptionPane.ERROR_MESSAGE); } catch (IncompatibleVersionException e2) { JOptionPane.showMessageDialog(mainWindow, rb.getString("DatabaseBadVersion"), rb.getString("error"), JOptionPane.ERROR_MESSAGE); } catch (DatabaseAccessException e2) { JOptionPane.showMessageDialog(mainWindow, rb.getString("DatabaseNoAccess"), rb.getString("error"), JOptionPane.ERROR_MESSAGE); } // start the import logic if (db != null && db.isEmpty()) { ImportLogic.init(db); flag = true; importButton.doClick(); } // reload the UI if (db != null && !db.isEmpty()) { mainWindow.loadProject(db); flag = false; } else { JOptionPane.showMessageDialog(mainWindow, rb.getString("DatabaseNoData"), rb.getString("error"), JOptionPane.ERROR_MESSAGE); } } /** * Initializes all actions used in this class. */ private void initActions() { newWS = new NewWSAction(); importAction = new ImportAction(); infoAction = new InfoAction(); exportAction = new ExportAction(); settingsAction = new SettingsAction(); // Register all action for shortcuts EventController.getInstance().setAction(newWS, "eventSetNewWorkspace"); EventController.getInstance().setAction(importAction, "eventImportNewData"); EventController.getInstance().setAction(infoAction, "eventShowInfo"); EventController.getInstance().setAction(settingsAction, "eventOpenSettings"); EventController.getInstance().setAction(exportAction, "eventExportData"); } /** * Initializes all Buttons used in this class. */ private void initButtons() { try { Dimension buttonSize = new Dimension(28, 28); newButton = new JButton(this.newWS); newButton.setIcon(new ImageIcon(ImageIO.read(MenuPanel.class.getResourceAsStream("/new.png")))); newButton.setToolTipText(rb.getString("newButton")); newButton.setPreferredSize(buttonSize); newButton.setMaximumSize(buttonSize); importButton = new JButton(this.importAction); importButton.setIcon(new ImageIcon(ImageIO.read(MenuPanel.class.getResourceAsStream("/import.png")))); importButton.setToolTipText(rb.getString("importButton")); importButton.setPreferredSize(buttonSize); importButton.setMaximumSize(buttonSize); exportButton = new JButton(this.exportAction); exportButton.setIcon(new ImageIcon(ImageIO.read(MenuPanel.class.getResourceAsStream("/export.png")))); exportButton.setToolTipText(rb.getString("exportButton")); exportButton.setPreferredSize(buttonSize); exportButton.setMaximumSize(buttonSize); infoButton = new JButton(this.infoAction); infoButton.setIcon(new ImageIcon(ImageIO.read(MenuPanel.class.getResourceAsStream("/info.png")))); infoButton.setToolTipText(rb.getString("infoButton")); infoButton.setPreferredSize(buttonSize); infoButton.setMaximumSize(buttonSize); settingsButton = new JButton(this.settingsAction); settingsButton.setIcon(new ImageIcon(ImageIO.read(MenuPanel.class.getResourceAsStream("/settings.png")))); settingsButton.setToolTipText(rb.getString("settings")); settingsButton.setPreferredSize(buttonSize); settingsButton.setMaximumSize(buttonSize); } catch (IOException ex) { ex.printStackTrace(); } } /** * Defines the new workspace action. * */ class NewWSAction extends AbstractAction { private static final long serialVersionUID = 6925671419464405501L; /** * Defines what happens when this action is triggered. * * @param e * - action event. */ @Override public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(System.getProperty("user.dir")); fc.setDialogTitle(rb.getString("workspaceDialog")); fc.setFileSelectionMode(JFileChooser.FILES_ONLY); FileNameExtensionFilter filter = new FileNameExtensionFilter(".bsv", "bsv"); fc.setAcceptAllFileFilterUsed(false); fc.addChoosableFileFilter(filter); int ret = fc.showOpenDialog(EventController.getInstance().getRootFrame()); if (ret == JFileChooser.APPROVE_OPTION) { mainWindow.removeComponents(); path = fc.getSelectedFile().getAbsolutePath(); String extension = ".bsv"; if (!path.endsWith(extension)) { path = path + extension; } boolean restart = MainWindow.curBSVFile != null && !mainWindow.equals(path); if (restart) { try { mainWindow.restartApplication(path); } catch (IOException ex) { ex.printStackTrace(); } } else { loadDatabase(path); } } } } /** * Defines the import action. * */ class ImportAction extends AbstractAction { private static final long serialVersionUID = -6848965362765706037L; /** * Import dialog window. */ private JDialog importDialog; /** * Describes the first path. */ private JLabel path1Label; /** * Describes the second path. */ private JLabel path2Label; /** * Displays the first path. */ private JTextField path1; /** * Displays the second path. */ private JTextField path2; /** * Opens a file chooser for the first path. */ private JButton first; /** * Opens a file chooser for the second path. */ private JButton second; /** * Imports the selected files */ private JButton ok; /** * Cancels the import. */ private JButton cancel; /* * Files */ private File file1; private File file2; /** * Defines what happens when choosing the first file in the import dialog. */ private FirstAction firstAction; /** * Defines what happens when choosing the second file in the import dialog. */ private SecondAction secondAction; /** * Defines what happens when clicked on the import button in the import dialog. */ private ImportButtonAction importButtonAction; /** * Defines what happens when clicked on the cancel button in the import dialog. */ private CancelButtonAction cancelButtonAction; /** * Defines what happens when this action is triggered. * * @param e * - action event. */ @Override public void actionPerformed(ActionEvent e) { if (flag) { importDialog = new JDialog(mainWindow, true); importDialog.setLayout(null); importDialog.setSize(500, 270); importDialog.setPreferredSize(importDialog.getSize()); importDialog.setResizable(false); importDialog.setTitle(rb.getString("importDialog")); importDialog.setLocationRelativeTo(mainWindow); initImportDialogActions(); path1Label = new JLabel(); path1Label.setText(rb.getString("importText1")); path1Label.setBounds(20, 20, 250, 25); path1 = new JTextField(); path1.setBounds(20, 50, 400, 25); path2Label = new JLabel(); path2Label.setText(rb.getString("importText2")); path2Label.setBounds(20, 100, 250, 25); path2 = new JTextField(); path2.setBounds(20, 130, 400, 25); first = new JButton(this.firstAction); first.setText(rb.getString("fileChooserButton")); first.setBounds(420, 50, 50, 25); second = new JButton(this.secondAction); second.setText(rb.getString("fileChooserButton")); second.setBounds(420, 130, 50, 25); ok = new JButton(this.importButtonAction); ok.setText(rb.getString("importButton")); ok.setBounds(270, 200, 100, 25); cancel = new JButton(this.cancelButtonAction); cancel.setText(rb.getString("abortButton")); cancel.setBounds(380, 200, 100, 25); importDialog.add(path1Label); importDialog.add(path1); importDialog.add(path2Label); importDialog.add(path2); importDialog.add(first); importDialog.add(second); importDialog.add(ok); importDialog.add(cancel); importDialog.pack(); importDialog.setVisible(true); } else { JOptionPane.showMessageDialog(mainWindow, rb.getString("DatabaseAlreadyLoaded"), rb.getString("error"), JOptionPane.ERROR_MESSAGE); } } private void initImportDialogActions() { this.firstAction = new FirstAction(); this.secondAction = new SecondAction(); this.cancelButtonAction = new CancelButtonAction(); this.importButtonAction = new ImportButtonAction(); } private void closeImportDialog() { importDialog.setVisible(false); } /** * Action done when choosing the first file to import. * */ class FirstAction extends AbstractAction { private static final long serialVersionUID = -5928081343404964680L; /** * Defines what happens when this action is triggered. * * @param e * - action event. */ @Override public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(System.getProperty("user.dir")); if (path2.getText() != null) { fc.setCurrentDirectory(new File(path2.getText())); } if (path1.getText() != null) { fc.setCurrentDirectory(new File(path1.getText())); } fc.setDialogTitle(rb.getString("importDialog1")); fc.setFileSelectionMode(JFileChooser.FILES_ONLY); FileNameExtensionFilter filter = new FileNameExtensionFilter(".arff and .csv only", "arff", "csv"); fc.setAcceptAllFileFilterUsed(false); fc.addChoosableFileFilter(filter); int ret = fc.showOpenDialog(null); if (ret == JFileChooser.APPROVE_OPTION) { file1 = fc.getSelectedFile(); path1.setText(file1.toString()); } } } /** * Action done when choosing the second file to import. * */ class SecondAction extends AbstractAction { private static final long serialVersionUID = -8983474343923949214L; /** * Defines what happens when this action is triggered. * * @param e * - action event. */ @Override public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(System.getProperty("user.dir")); fc.setDialogTitle(rb.getString("importDialog2")); if (path1.getText() != null) { fc.setCurrentDirectory(new File(path1.getText())); } if (path2.getText() != null) { fc.setCurrentDirectory(new File(path2.getText())); } fc.setFileSelectionMode(JFileChooser.FILES_ONLY); FileNameExtensionFilter filter = new FileNameExtensionFilter(".ssd", "ssd"); fc.setAcceptAllFileFilterUsed(false); fc.addChoosableFileFilter(filter); int ret = fc.showOpenDialog(null); if (ret == JFileChooser.APPROVE_OPTION) { file2 = fc.getSelectedFile(); path2.setText(file2.toString()); } } } /** * Action done when clicking the import button in the import dialog. * */ class ImportButtonAction extends AbstractAction { private static final long serialVersionUID = 9131387291577584095L; /** * Defines what happens when this action is triggered. * * @param e * - action event. */ @Override public void actionPerformed(ActionEvent e) { if (ImportLogic.getInstance() != null && flag) { // the 4 if statements check if the given files have valid extensions and exist. if (!path1.getText().endsWith(".arff") && !path1.getText().endsWith(".csv")) { JOptionPane.showMessageDialog(mainWindow, rb.getString("importUnsupportedFileExtension1"), rb.getString("warning"), JOptionPane.WARNING_MESSAGE); return; } if (!path2.getText().endsWith(".ssd")) { JOptionPane.showMessageDialog(mainWindow, rb.getString("importUnsupportedFileExtension2"), rb.getString("warning"), JOptionPane.WARNING_MESSAGE); return; } if(new File(path1.getText()).exists() == false) { JOptionPane.showMessageDialog(mainWindow, rb.getString("importNonExistingFile1"), rb.getString("warning"), JOptionPane.WARNING_MESSAGE); return; } if(new File(path2.getText()).exists() == false) { JOptionPane.showMessageDialog(mainWindow, rb.getString("importNonExistingFile2"), rb.getString("warning"), JOptionPane.WARNING_MESSAGE); return; } try { file1 = new File(path1.getText()); file2 = new File(path2.getText()); ImportLogic.getInstance().importFile(file1, file2); } catch (UnsupportedFileExtensionException ex) { JOptionPane.showMessageDialog(mainWindow, rb.getString("importNotValidExtension"), rb.getString("warning"), JOptionPane.WARNING_MESSAGE); ex.printStackTrace(); } catch (InvalidFileException ex) { JOptionPane.showMessageDialog(mainWindow, rb.getString("importCorruptedFile"), rb.getString("warning"), JOptionPane.WARNING_MESSAGE); ex.printStackTrace(); } catch (IOException ex) { JOptionPane.showMessageDialog(mainWindow, rb.getString("SystemFailure"), rb.getString("warning"), JOptionPane.WARNING_MESSAGE); ex.printStackTrace(); } catch (DatabaseAccessException ex) { JOptionPane.showMessageDialog(mainWindow, rb.getString("DatabaseNoAccess"), rb.getString("warning"), JOptionPane.WARNING_MESSAGE); ex.printStackTrace(); } catch (InterruptedException ex) { JOptionPane.showMessageDialog(mainWindow, rb.getString("SystemFailure"), rb.getString("warning"), JOptionPane.WARNING_MESSAGE); ex.printStackTrace(); } } else { JOptionPane.showMessageDialog(null, rb.getString("DatabaseAlreadyLoaded"), rb.getString("error"), JOptionPane.ERROR_MESSAGE); } closeImportDialog(); } } /** * Action done when clicking the cancel button in the import dialog. * */ class CancelButtonAction extends AbstractAction { private static final long serialVersionUID = -5094716053672516965L; /** * Defines what happens when this action is triggered. * * @param e * - action event. */ @Override public void actionPerformed(ActionEvent e) { closeImportDialog(); } } } /** * Defines the info action. * */ class InfoAction extends AbstractAction { private static final long serialVersionUID = 3582128685945841012L; /** * Defines what happens when this action is triggered. * * @param e * - action event. */ @Override public void actionPerformed(ActionEvent e) { idialog.setVisible(true); } } /** * Defines the export action. * */ class ExportAction extends AbstractAction { private static final long serialVersionUID = -6498753362256775129L; JDialog dialog; ExportLogic exLogic; JButton fcButton; JButton export; JButton abort; JTextField path; JLabel pathText; Checkbox check; JLabel checkLbl; FCAction fcAction; AbortAction abortAction; ExportButtonAction exportButtonAction; File f; /** * Defines what happens when this action is triggered. * * @param e * - action event. */ @Override public void actionPerformed(ActionEvent e) { initExportDialogActions(); dialog = new JDialog(mainWindow, true); dialog.setTitle(rb.getString("exportDialog")); fcButton = new JButton(rb.getString("fileChooserButton")); export = new JButton(rb.getString("exportButton")); abort = new JButton(rb.getString("abortButton")); pathText = new JLabel(rb.getString("exportText")); check = new Checkbox(); checkLbl = new JLabel(rb.getString("ExportGenSSD")); dialog.setLayout(null); dialog.setSize(500, 220); dialog.setPreferredSize(dialog.getSize()); dialog.setLocationRelativeTo(mainWindow); pathText.setBounds(20, 20, 150, 25); path = new JTextField(); path.setBounds(20, 50, 400, 25); fcButton = new JButton(this.fcAction); fcButton.setText(rb.getString("fileChooserButton")); fcButton.setBounds(420, 50, 50, 25); export = new JButton(this.exportButtonAction); export.setText(rb.getString("exportButton")); export.setBounds(260, 130, 100, 25); abort = new JButton(this.abortAction); abort.setText(rb.getString("abortButton")); abort.setBounds(370, 130, 100, 25); checkLbl.setBounds(20, 84, 220, 25); check.setBounds(250, 85, 24, 24); dialog.add(pathText); dialog.add(path); dialog.add(fcButton); dialog.add(export); dialog.add(abort); dialog.add(checkLbl); dialog.add(check); dialog.setVisible(true); } private void initExportDialogActions() { this.fcAction = new FCAction(); this.abortAction = new AbortAction(); this.exportButtonAction = new ExportButtonAction(); } private void closeExportDialog() { dialog.setVisible(false); } /** * Action done when choosing the first file to import. */ class FCAction extends AbstractAction { private static final long serialVersionUID = -4812857764306737393L; /** * Defines what happens when this action is triggered. * * @param e * - action event. */ @Override public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(System.getProperty("user.dir")); if (path.getText() != null) { fc.setCurrentDirectory(new File(path.getText())); } fc.setDialogTitle(rb.getString("exportDialog")); fc.setFileSelectionMode(JFileChooser.FILES_ONLY); fc.setAcceptAllFileFilterUsed(false); String[] extensions = ExportLogic.getInstance().getExportFormats(); for (String s : extensions) { fc.addChoosableFileFilter(new FileNameExtensionFilter("." + s + " files", s)); } int ret = fc.showSaveDialog(null); if (ret == JFileChooser.APPROVE_OPTION) { f = fc.getSelectedFile(); boolean validExtension = true; String[] usedExtensions = ((FileNameExtensionFilter) fc.getFileFilter()).getExtensions(); for (String s : usedExtensions) { validExtension &= f.getName().endsWith(s); } if (!validExtension) { String path = f.getAbsolutePath() + "." + usedExtensions[0]; f = new File(path); } path.setText(f.toString()); } else { JOptionPane.showMessageDialog(null, rb.getString("badFileType"), rb.getString("warning"), JOptionPane.WARNING_MESSAGE); } } } /** * Action that is performed to abort the export dialog */ class AbortAction extends AbstractAction { private static final long serialVersionUID = -7051496563140565735L; @Override public void actionPerformed(ActionEvent e) { closeExportDialog(); } } /** * Action that is performed to export the data finally */ class ExportButtonAction extends AbstractAction { private static final long serialVersionUID = -7832468903808405788L; @Override public void actionPerformed(ActionEvent e) { try { ExportLogic el = ExportLogic.getInstance(); el.exportFile(f, check.getState()); } catch (IOException ex) { Logger.getLogger(MenuPanel.class.getName()).log(Level.SEVERE, null, ex); } catch (InvalidFileException ex) { Logger.getLogger(MenuPanel.class.getName()).log(Level.SEVERE, null, ex); } catch (DatabaseAccessException ex) { Logger.getLogger(MenuPanel.class.getName()).log(Level.SEVERE, null, ex); } closeExportDialog(); } } } private class SettingsAction extends AbstractAction { private static final long serialVersionUID = 9106668603221120596L; @Override public void actionPerformed(ActionEvent e) { SettingsDialog sd = new SettingsDialog(mainWindow); sd.setVisible(true); } } }