Java tutorial
/** * ***************************************************************************** * Copyright (c) 2015 CodeJumble.com. All rights reserved. * * This file is part of OpenTube - www.codejumble.com * * OpenTube is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * OpenTube 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 Lesser General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * OpenTube. If not, see <http://www.gnu.org/licenses/>. * ***************************************************************************** */ package com.codejumble.opentube; import com.codejumble.opentube.downloader.DownloadManager; import java.awt.Cursor; import java.awt.Desktop; import java.awt.Font; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.List; import javax.swing.AbstractButton; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextField; import javax.swing.SwingWorker; import javax.swing.filechooser.FileNameExtensionFilter; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.io.FileUtils; import org.apache.commons.validator.UrlValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Main frame of the program. Implements functionalities related to the view * * @author alopcas */ public class Main extends javax.swing.JFrame implements PropertyChangeListener { /** * Software version */ public static String SOFTWARE_VERSION = "0.2"; // Font set private final Font PLACEHOLDER_FONT = new Font("Verdana", Font.ITALIC, 12); private final Font INPUT_FONT = new Font("Verdana", Font.PLAIN, 12); // Configuration private PropertiesConfiguration configuration; private ImageIcon appLogo; private UrlValidator urlValidator; // Strings where settings are stored during execution private String configuredFolderForDownloadedMedia; private String tmpFilesFolder; private String logsFolder; private String settingsFilePath = "conf" + File.separator + "settings.conf"; // Download manager to be used by default private DownloadManager defaultDownloadManager; // Logging static Logger logger = LoggerFactory.getLogger(Main.class); /** * Initilizes the main frame of the program. Loads settings and initializes * the components of the view. */ public Main() { // Load configuration try { configuration = loadConfiguration(); } catch (ConfigurationException e) { createErrorDialog(this, e.getMessage(), "Fatal error"); System.exit(1); } catch (Exception e) { createErrorDialog(this, e.getMessage(), "Fatal error"); System.exit(1); } initParameters(); initComponents(); } /** * This method is called from within the constructor to initialize the form. */ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { mediaFormatButtonGroup = new javax.swing.ButtonGroup(); defaultFileChooser = new javax.swing.JFileChooser(); importListFileChooser = new javax.swing.JFileChooser(); videoURLDownloadButton = new javax.swing.JButton(); downloadProgressBar = new javax.swing.JProgressBar(); videoURLField = new javax.swing.JTextField(); pathURLLabel = new javax.swing.JLabel(); pathField = new javax.swing.JTextField(); videoURLLabel1 = new javax.swing.JLabel(); fileNameField = new javax.swing.JTextField(); resetVideoFileName(); fileURLLabel = new javax.swing.JLabel(); mp4FormatOption = new javax.swing.JRadioButton(); aacFormatOption = new javax.swing.JRadioButton(); aviFormatOption = new javax.swing.JRadioButton(); fileFormatLabel = new javax.swing.JLabel(); statusLabel = new javax.swing.JLabel(); status = new javax.swing.JLabel(); mp3FormatOption = new javax.swing.JRadioButton(); flvFormatOption = new javax.swing.JRadioButton(); oggFormatOption = new javax.swing.JRadioButton(); downloadQueueProgress = new javax.swing.JLabel(); browseButton = new javax.swing.JButton(); menuBar = new javax.swing.JMenuBar(); fileMenu = new javax.swing.JMenu(); settingsItem = new javax.swing.JMenuItem(); importItem = new javax.swing.JMenuItem(); quitItem = new javax.swing.JMenuItem(); toolsMenu = new javax.swing.JMenu(); clearItem = new javax.swing.JMenuItem(); queueItem = new javax.swing.JMenuItem(); helpMenu = new javax.swing.JMenu(); helpPagesItem = new javax.swing.JMenuItem(); aboutItem = new javax.swing.JMenuItem(); defaultFileChooser.setFileSelectionMode(javax.swing.JFileChooser.DIRECTORIES_ONLY); importListFileChooser.setDialogTitle(""); importListFileChooser.setFileFilter(new FileNameExtensionFilter("Text files", "txt", "text")); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("OpenTube v" + SOFTWARE_VERSION + "- www.codejumble.com"); setIconImage(getIconImage()); setName("OpenTubeMainFrame"); // NOI18N setResizable(false); videoURLDownloadButton.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N videoURLDownloadButton.setText("Download!"); videoURLDownloadButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { videoURLDownloadButtonActionPerformed(evt); } }); downloadProgressBar.setMaximum(100); downloadProgressBar.setMinimum(0); downloadProgressBar.setStringPainted(true); videoURLField.setFont(new java.awt.Font("Verdana", 2, 11)); // NOI18N videoURLField.setText("Video URL"); videoURLField.setToolTipText(""); videoURLField.addFocusListener(new java.awt.event.FocusAdapter() { public void focusGained(java.awt.event.FocusEvent evt) { videoURLFieldFocusGained(evt); } public void focusLost(java.awt.event.FocusEvent evt) { videoURLFieldFocusLost(evt); } }); pathURLLabel.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N pathURLLabel.setText("Path"); pathField.setEditable(false); pathField.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N pathField.setText(configuredFolderForDownloadedMedia); pathField.setToolTipText(""); pathField.addFocusListener(new java.awt.event.FocusAdapter() { public void focusGained(java.awt.event.FocusEvent evt) { pathFieldFocusGained(evt); } public void focusLost(java.awt.event.FocusEvent evt) { pathFieldFocusLost(evt); } }); videoURLLabel1.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N videoURLLabel1.setText("URL"); fileNameField.setFont(new java.awt.Font("Verdana", 2, 11)); // NOI18N fileNameField.setText("Destiny file name"); fileNameField.setToolTipText(""); fileNameField.addFocusListener(new java.awt.event.FocusAdapter() { public void focusGained(java.awt.event.FocusEvent evt) { fileNameFieldFocusGained(evt); } public void focusLost(java.awt.event.FocusEvent evt) { fileNameFieldFocusLost(evt); } }); fileURLLabel.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N fileURLLabel.setText("File"); mediaFormatButtonGroup.add(mp4FormatOption); mp4FormatOption.setSelected(true); mp4FormatOption.setText("mp4"); mediaFormatButtonGroup.add(aacFormatOption); aacFormatOption.setText("aac"); aacFormatOption.setEnabled(false); mediaFormatButtonGroup.add(aviFormatOption); aviFormatOption.setText("avi"); aviFormatOption.setEnabled(false); fileFormatLabel.setFont(new java.awt.Font("Noto Sans", 1, 12)); // NOI18N fileFormatLabel.setText("Format"); statusLabel.setText("Status:"); status.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N status.setText("Ready"); mediaFormatButtonGroup.add(mp3FormatOption); mp3FormatOption.setText("mp3"); mp3FormatOption.setEnabled(false); mediaFormatButtonGroup.add(flvFormatOption); flvFormatOption.setText("flv"); mediaFormatButtonGroup.add(oggFormatOption); oggFormatOption.setText("ogg"); oggFormatOption.setEnabled(false); downloadQueueProgress.setText("0 of 0"); browseButton.setFont(new java.awt.Font("Verdana", 0, 11)); // NOI18N browseButton.setText("Browse"); browseButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { browseButtonActionPerformed(evt); } }); fileMenu.setText("File"); settingsItem.setText("Settings"); settingsItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { settingsItemActionPerformed(evt); } }); fileMenu.add(settingsItem); importItem.setText("Import list..."); importItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { importItemActionPerformed(evt); } }); fileMenu.add(importItem); quitItem.setText("Quit"); quitItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { quitItemActionPerformed(evt); } }); fileMenu.add(quitItem); menuBar.add(fileMenu); toolsMenu.setText("Tools"); clearItem.setText("Clear cache"); clearItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { clearItemActionPerformed(evt); } }); toolsMenu.add(clearItem); queueItem.setText("Download queue"); queueItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { queueItemActionPerformed(evt); } }); toolsMenu.add(queueItem); menuBar.add(toolsMenu); helpMenu.setText("Help"); helpPagesItem.setText("Help pages"); helpPagesItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { helpPagesItemActionPerformed(evt); } }); helpMenu.add(helpPagesItem); aboutItem.setText("About"); aboutItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { aboutItemActionPerformed(evt); } }); helpMenu.add(aboutItem); menuBar.add(helpMenu); setJMenuBar(menuBar); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup().addGap(59, 59, 59) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(downloadProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, 765, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(52, Short.MAX_VALUE)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup().addGap(11, 11, 11).addGroup(layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(videoURLLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(pathURLLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 40, Short.MAX_VALUE) .addComponent( fileURLLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 40, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout .createParallelGroup( javax.swing.GroupLayout.Alignment.LEADING) .addComponent(pathField).addComponent(videoURLField) .addComponent( fileNameField, javax.swing.GroupLayout.Alignment.TRAILING)) .addPreferredGap( javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout .createParallelGroup( javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(videoURLDownloadButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent( browseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(18, 18, 18) .addGroup(layout .createParallelGroup( javax.swing.GroupLayout.Alignment.LEADING) .addComponent(fileFormatLabel) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup( javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(mp4FormatOption) .addComponent(mp3FormatOption)) .addGap(2, 2, 2) .addGroup(layout.createParallelGroup( javax.swing.GroupLayout.Alignment.LEADING) .addComponent( aacFormatOption) .addComponent(flvFormatOption)) .addPreferredGap( javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup( javax.swing.GroupLayout.Alignment.LEADING) .addComponent(aviFormatOption) .addComponent(oggFormatOption)))) .addGap(36, 36, 36)))) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup().addGap(26, 26, 26).addComponent(downloadQueueProgress) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(statusLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(status).addGap(77, 77, 77))); layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup().addGap(63, 63, 63).addComponent(fileFormatLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup().addGroup(layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(videoURLDownloadButton) .addComponent(videoURLField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(videoURLLabel1)) .addComponent(mp4FormatOption)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout .createParallelGroup( javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(pathField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(pathURLLabel).addComponent(browseButton)) .addGroup(layout .createParallelGroup( javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(mp3FormatOption).addComponent(aacFormatOption) .addComponent(oggFormatOption)))) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(flvFormatOption).addComponent(aviFormatOption))) .addGap(11, 11, 11) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(fileURLLabel).addComponent(fileNameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 16, Short.MAX_VALUE) .addComponent(downloadProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(46, 46, 46) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(statusLabel).addComponent(status) .addComponent(downloadQueueProgress)))); getAccessibleContext().setAccessibleDescription(""); pack(); }// </editor-fold>//GEN-END:initComponents /** * Puts or removes placeholder text in the video URL field to make it more * user friendly. Also resets the file name in case of no input. * * @param evt Swing event */ private void videoURLFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_videoURLFieldFocusGained if (videoURLField.getText().length() <= 0 || videoURLField.getText().equals("Video URL")) { videoURLField.setFont(INPUT_FONT); videoURLField.setText(""); if (fileNameField.getText().length() <= 0 || fileNameField.getText().equals("Destiny file name")) { resetVideoFileName(); } } }//GEN-LAST:event_videoURLFieldFocusGained /** * Puts a placeholder in case that the field is still empty after losing the * focus * * @param evt Swing event */ private void videoURLFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_videoURLFieldFocusLost if (videoURLField.getText().length() <= 0 || videoURLField.getText().equals("Video URL")) { videoURLField.setFont(PLACEHOLDER_FONT); videoURLField.setText("Video URL"); } }//GEN-LAST:event_videoURLFieldFocusLost /** * Puts or removes placeholder text in the file path field to make it more * user friendly. Also resets the file name in case of no input. * * @param evt Swing event */ private void pathFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_pathFieldFocusGained if (pathField.getText().length() <= 0 || pathField.getText().equals("Destiny file path")) { pathField.setFont(INPUT_FONT); pathField.setText(""); } }//GEN-LAST:event_pathFieldFocusGained /** * Puts a placeholder in case that the field is still empty after losing the * focus * * @param evt Swing event */ private void pathFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_pathFieldFocusLost if (pathField.getText().length() <= 0 || pathField.getText().equals("Destiny file path")) { pathField.setFont(PLACEHOLDER_FONT); pathField.setText("Destiny file path"); } }//GEN-LAST:event_pathFieldFocusLost /** * Adds the video to the queue and, in case there are not active downloads * currently, starts them. * * @param evt Swing event */ private void videoURLDownloadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_videoURLDownloadButtonActionPerformed updateDownloadManagerWithNewURL(videoURLField.getText()); }//GEN-LAST:event_videoURLDownloadButtonActionPerformed /** * Updates the download manager with a new link, if the manager hasn't * started it will be initialized. * * @param url URL address to add */ private void updateDownloadManagerWithNewURL(String url) { videoURLDownloadButton.setEnabled(false); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); try { if (isWaitingForTasks() && defaultDownloadManager.getState().equals(SwingWorker.StateValue.DONE)) { defaultDownloadManager = new DownloadManager(this, tmpFilesFolder, configuredFolderForDownloadedMedia); } defaultDownloadManager.addDownloadToQueue(url, fileNameField.getText(), getSelectedFormatOption()); defaultDownloadManager.execute(); } catch (MalformedURLException ex) { createErrorDialog(this, "The inputted URL doesn't match a valid format", "Wrong URL format"); } catch (RuntimeException ex) { createErrorDialog(this, "The provided website is not supported", "Unsupported website"); } catch (Exception e) { createErrorDialog(this, e.getMessage(), "Unexpected error"); } videoURLDownloadButton.setEnabled(true); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); resetVideoFileName(); } /** * Puts or removes placeholder text in the file name field to make it more * user friendly. Also resets the file name in case of no input. * * @param evt Swing event */ private void fileNameFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_fileNameFieldFocusGained if (fileNameField.getText().length() <= 0 || fileNameField.getText().equals("Destiny file name")) { fileNameField.setFont(INPUT_FONT); fileNameField.setText(""); } }//GEN-LAST:event_fileNameFieldFocusGained /** * Puts a placeholder in case that the field is still empty after losing the * focus * * @param evt Swing event */ private void fileNameFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_fileNameFieldFocusLost if (fileNameField.getText().length() <= 0 || fileNameField.getText().equals("Destiny file name")) { fileNameField.setFont(PLACEHOLDER_FONT); fileNameField.setText("Destiny file name"); } }//GEN-LAST:event_fileNameFieldFocusLost /** * Opens http://www.codejumble.com at System's default browser * * @param evt Swing event */ private void helpPagesItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_helpPagesItemActionPerformed try { URI uri = new URL("http://www.codejumble.com").toURI(); Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null; if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) { try { desktop.browse(uri); } catch (Exception e) { createErrorDialog(this, e.getMessage(), "Error!"); } } } catch (Exception ex) { createErrorDialog(this, ex.getMessage(), "Unexpected error"); } }//GEN-LAST:event_helpPagesItemActionPerformed /** * Opens a small dialog showing some info about OpenTube * * @param evt Swing event */ private void aboutItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_aboutItemActionPerformed JOptionPane.showMessageDialog(this, "OpenTube v" + SOFTWARE_VERSION + "\nVisit www.codejumble.com", "About OpenTube", JOptionPane.PLAIN_MESSAGE); }//GEN-LAST:event_aboutItemActionPerformed /** * Exits the program * * @param evt Swing event */ private void quitItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_quitItemActionPerformed System.exit(0); }//GEN-LAST:event_quitItemActionPerformed /** * Opens the settings dialog and processes the changes performed (if * necessary) * * @param evt Swing event */ private void settingsItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_settingsItemActionPerformed JTextField setting = new JTextField(configuredFolderForDownloadedMedia); Object[] settings = { "Downloads folder", setting }; int option = JOptionPane.showConfirmDialog(null, settings, "Settings", JOptionPane.OK_CANCEL_OPTION); if (option == JOptionPane.OK_OPTION) { configuration.setProperty("downloadFolder", setting.getText()); try { logger.info("Saving settings"); configuration.save(); } catch (ConfigurationException ex) { createErrorDialog(this, ex.getMessage(), "Fatal error"); } } }//GEN-LAST:event_settingsItemActionPerformed /** * Imports a list of videos contained in a csv file or plaintext format to * the download queue directly and starts downloading. * * @param evt Swing event */ private void importItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importItemActionPerformed importListFileChooser.showOpenDialog(this); if (importListFileChooser.getSelectedFile() != null) { logger.error("Importing file located at {}", importListFileChooser.getSelectedFile().getAbsolutePath()); List<String> urls = null; try { urls = renderDownloadQueue(importListFileChooser.getSelectedFile()); } catch (IOException ex) { createErrorDialog(this, ex.getMessage(), "Error"); } int downloadQueueSize = 0; if (!urls.isEmpty()) { logger.error("Loading the URLs in the download manager"); downloadQueueSize = defaultDownloadManager.getDownloadQueueSize(); for (String url : urls) { updateDownloadManagerWithNewURL(url); } } else { createErrorDialog(this, "No valid links were found, the file must format a url/row file", "ERROR"); } // Notify the user of the success JOptionPane.showMessageDialog(this, defaultDownloadManager.getDownloadQueueSize() - downloadQueueSize + " were successfully imported"); } }//GEN-LAST:event_importItemActionPerformed private List<String> renderDownloadQueue(File importedFile) throws IOException { logger.error("Rendering the download page..."); List<String> lines = Files.readAllLines(Paths.get(importedFile.getAbsolutePath()), Charset.defaultCharset()); List<String> linesToRemove = new ArrayList<String>(); for (String line : lines) { if (!urlValidator.isValid(line)) { linesToRemove.add(line); } } lines.removeAll(linesToRemove); logger.error("Valid urls found: {}", lines.size()); return lines; } /** * Deletes all the files contained in temporal files folder (Default: 'tmp') * * @param evt Swing event */ private void clearItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearItemActionPerformed try { //Clear tmp folder FileUtils.cleanDirectory(new File(tmpFilesFolder)); } catch (IOException ex) { createErrorDialog(this, ex.getMessage(), "Fatal error"); } }//GEN-LAST:event_clearItemActionPerformed /** * Displays the download queue, with certain information * * @param evt Swing event */ private void queueItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_queueItemActionPerformed createErrorDialog(this, "This operation is not supported in this version", "Fatal error"); throw new UnsupportedOperationException(); }//GEN-LAST:event_queueItemActionPerformed /** * Allows to select the destiny of the download using a browse dialog * * @param evt Swing event */ private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed defaultFileChooser.showOpenDialog(this); if (defaultFileChooser.getSelectedFile() != null) { File selectedDestiny = defaultFileChooser.getSelectedFile(); pathField.setText(selectedDestiny.getAbsolutePath()); } }//GEN-LAST:event_browseButtonActionPerformed /** * Starts the program off. * * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { logger.error("Java error with text {}", ex.getMessage()); } catch (InstantiationException ex) { logger.error("Java error with text {}", ex.getMessage()); } catch (IllegalAccessException ex) { logger.error("Java error with text {}", ex.getMessage()); } catch (javax.swing.UnsupportedLookAndFeelException ex) { logger.error("Java error with text {}", ex.getMessage()); } //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { logger.info("Starting the main frame"); new Main().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton aacFormatOption; private javax.swing.JMenuItem aboutItem; private javax.swing.JRadioButton aviFormatOption; private javax.swing.JButton browseButton; private javax.swing.JMenuItem clearItem; private javax.swing.JFileChooser defaultFileChooser; private javax.swing.JProgressBar downloadProgressBar; private javax.swing.JLabel downloadQueueProgress; private javax.swing.JLabel fileFormatLabel; private javax.swing.JMenu fileMenu; private javax.swing.JTextField fileNameField; private javax.swing.JLabel fileURLLabel; private javax.swing.JRadioButton flvFormatOption; private javax.swing.JMenu helpMenu; private javax.swing.JMenuItem helpPagesItem; private javax.swing.JMenuItem importItem; private javax.swing.JFileChooser importListFileChooser; private javax.swing.ButtonGroup mediaFormatButtonGroup; private javax.swing.JMenuBar menuBar; private javax.swing.JRadioButton mp3FormatOption; private javax.swing.JRadioButton mp4FormatOption; private javax.swing.JRadioButton oggFormatOption; private javax.swing.JTextField pathField; private javax.swing.JLabel pathURLLabel; private javax.swing.JMenuItem queueItem; private javax.swing.JMenuItem quitItem; private javax.swing.JMenuItem settingsItem; private javax.swing.JLabel status; private javax.swing.JLabel statusLabel; private javax.swing.JMenu toolsMenu; private javax.swing.JButton videoURLDownloadButton; private javax.swing.JTextField videoURLField; private javax.swing.JLabel videoURLLabel1; // End of variables declaration//GEN-END:variables /** * Checks if progress has changed and updates the download progress bar * value. * * @param pce property */ @Override public void propertyChange(PropertyChangeEvent pce) { if ("progress".equals(pce.getPropertyName())) { int progress = (Integer) pce.getNewValue(); downloadProgressBar.setValue(progress); } } /** * Returns the version selected by the user for the output file * * @return desired format */ private String getSelectedFormatOption() { String format = "mp4"; for (Enumeration<AbstractButton> buttons = mediaFormatButtonGroup.getElements(); buttons .hasMoreElements();) { AbstractButton button = buttons.nextElement(); if (button.isSelected()) { format = button.getText(); } } return format; } /** * Returns the current status of the program ('Ready', 'Downloading', * 'Converting') * * @return status of the program */ public boolean isWaitingForTasks() { return status.getText().equals("Ready"); } /** * Changes the current status to a new one * * @param newStatus */ public void changeStatus(String newStatus) { logger.info("Status changed to {}", newStatus); status.setText(newStatus); } /** * Creates an error dialog with the desired content and dialog name * * @param frame target frame * @param content content of the dialog * @param name name of the dialog */ public void createErrorDialog(JFrame frame, String content, String name) { logger.error("Error! with message {}", content); JOptionPane.showMessageDialog(frame, content, name, JOptionPane.ERROR_MESSAGE); } /** * Initializes the parameters of the program such as folder paths, program * icons, etc. */ private void initParameters() { logger.info("Initilizing parameters"); String relativePathToDownloadFolder = (String) configuration.getProperty("downloadFolder"); configuredFolderForDownloadedMedia = new File(relativePathToDownloadFolder).getAbsolutePath() + File.separator; String relativePathToTmpFolder = (String) configuration.getProperty("tmpFolder"); tmpFilesFolder = new File(relativePathToTmpFolder).getAbsolutePath() + File.separator; String relativePathToLogsFolder = (String) configuration.getProperty("logsFolder"); logsFolder = new File(relativePathToLogsFolder).getAbsolutePath() + File.separator; defaultDownloadManager = new DownloadManager(this, tmpFilesFolder, configuredFolderForDownloadedMedia); // ImageIcon img = new ImageIcon("C:\\Users\\lope115\\Documents\\NetBeansProjects\\tmpot\\src\\main\\resources\\media" + File.separator + "icon.png"); // this.appLogo = img; urlValidator = new UrlValidator(); } /** * Returns the configuration from the settings file. * * @return user settings * @throws ConfigurationException in case the file is corrupted or * unavailable/missing. */ private PropertiesConfiguration loadConfiguration() throws ConfigurationException { logger.info("Loading user settings..."); PropertiesConfiguration prop = new PropertiesConfiguration(settingsFilePath); return prop; } /** * Resets the file name field to a new value following the patern * 'video-yearMonthDay' */ private void resetVideoFileName() { fileNameField.setText("video-" + new SimpleDateFormat("yyyyMMdd HHmmssSSS").format(new Date())); } /** * Updates the download queue status on the bottom. This method is called * every time the download manager enques a new download or a download is * done * * @param currentlyDownloadingIndex index of the current download in the * queue * @param downloadQueueSize total queue size */ public void updateDownloadQueueStatus(int currentlyDownloadingIndex, int downloadQueueSize) { downloadQueueProgress.setText(currentlyDownloadingIndex + " of " + downloadQueueSize); } }