6 Replies - 738 Views - Last Post: 05 August 2010 - 06:27 AM Rate Topic: -----

#1 gretty  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 123
  • Joined: 25-May 09

Advice & Criticism: Swing Application

Posted 04 August 2010 - 08:21 PM

Hello

I have made a Swing application that just creates a Random Playlist of media files & plays or deletes them.

I have never seen a full Swing application's code, so I dont know if I am writting Swing applications correctly. So I am looking for people to go over my code & give me advice on how to improve it in any way, & most importantly tell me if there is a common Swing structure that maybe I should follow.

Please give me your advice & criticism on my Random Playlist App:

Main Application class:
/*
   ******************************************************************************************
   Random Playlist Application
   
   Author:   
   Platform: Java Swing & AWT
   
   ******************************************************************************************
   Main Logic & Frame Class:
   
   Handles all application events & creates the main frame window 
   
   ******************************************************************************************
*/


import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;


public class RandomPlaylist extends JFrame implements ActionListener
{
	
	/// Class Variables:
	
	private static final long serialVersionUID = 1L; // How come I have to have this???
	private JPanel componentPanel;
	private FolderPathPanel pathPanel;
	private JTextField playlistSizeTf;
	private JTable playlistTb;
	private JRadioButton listAllMediaRb;
	private JRadioButton randomListMediaRb;
	private JButton createPlaylistBt;
	private JButton clearPlaylistBt;
	private JButton deleteFileBt;
	private JButton playAllFileBt;
	private JButton playFileBt;
	
	private enum ListType { ALLLIST, RANDOMLIST };
	private Vector <File> mediaList;
	private Vector <File> directoryList;
	private Vector <File> playlist;
	private int playlistSize;
	private ListType playlistType;
	private boolean directoryAltered;
	private FileFilter directoryFilter;
	
	
	/// Class Methods:
	
	/**
	 * Constructor:
	 * 
	 */
	public RandomPlaylist()
	{
		
		this.setTitle( "Random Playlist Creator" );
		this.setDefaultCloseOperation( EXIT_ON_CLOSE );
		this.setResizable( false );
		
		initialiseVariables();
		initialiseComponents();
		bindComponents();
		
		pack();
		validate();
		this.setVisible( true );
		
	}
	
	
	/**
	 * Post: Handle all action events sent to this frame
	 * 
	 * @param ev
	 * 
	 */
	public void actionPerformed( ActionEvent ev )
	{
		
		if ( ev.getSource() == createPlaylistBt )
		{
			
			if ( verifyPlaylistSize() )
			{
				// Get folder paths if the directories have been altered
				if ( directoryAltered )
				{
					directoryList.clear();
					directoryList = pathPanel.getFolderDirectories();
					searchFoldersForMedia();
				}
				
				if ( directoryList.size() > 0 )
				{
					createPlaylist();
					displayPlaylist();
					directoryAltered = false;
				}
				else JOptionPane.showMessageDialog( this, "Please specify a folder of media files", 
						                            "Error", JOptionPane.ERROR_MESSAGE );
			}
		}
		if ( ev.getSource() == clearPlaylistBt )
		{
			
			// Should I put the below code in a function?
			DefaultTableModel model = (DefaultTableModel) playlistTb.getModel();
			
			while ( model.getRowCount() > 0 )
			{
				model.removeRow( 0 );
			}
			
			playlist.clear();
			// OR model.getDataVector().removeAllElements();
			// playlistTb.repaint();
			
		}
		if ( ev.getSource() == deleteFileBt )
		{
		
			File selFiles[] = getSelectedFiles();

		    if ( selFiles.length > 0 )
			{
		    	deleteMedia( selFiles );
			}
		     
		}
		if ( ev.getSource() == playAllFileBt )
		{
			
			Vector <File> playlistCpy = (Vector <File>) playlist.clone();
			File selFiles[] = (File[]) playlistCpy.toArray();
			 
			if ( selFiles.length > 0 )
			{
				playMedia( selFiles );
			}
		     
		}
		if ( ev.getSource() == playFileBt )
		{
			
		     File selFiles[] = getSelectedFiles();

		     if ( selFiles.length > 0 )
			 {
				 playMedia( selFiles );
			 }
		     
		}
		else if ( ev.getSource() == listAllMediaRb )
		{
			playlistType = ListType.ALLLIST;
		}
		else if ( ev.getSource() == randomListMediaRb )
		{
			playlistType = ListType.RANDOMLIST;
		}
		
	}
	
	
	/**
	 * Post: Set all class variables to their default value
	 * 
	 * Question: If a function is void & has no parameters, what do I add to its javadoc? 
	 *           Just what the function does? Anything else (info about the variables inside 
	 *           the function maybe?)?
	 */
	private void initialiseVariables()
	{
		
		mediaList     = new Vector <File>();
		directoryList = new Vector <File>();
		playlist      = new Vector <File>();
		playlistSize  = 8;
		playlistType  = ListType.RANDOMLIST;
		directoryAltered = true;
		
		directoryFilter = new FileFilter() 
		{
		    public boolean accept(File file) 
		    {
		    	if ( file.isDirectory() || isMediaFile( file ) )
		        {
		    		return true;
		        }
		    	else return false;
		    }
		};

	}
	
	
	/**
	 * Post: Set all JComponents to their default values & call buildPanel 
	 *       function
	 */
	private void initialiseComponents()
	{
		
		String colNames[] = {"Media Name", "Type", "Size"};
		
		componentPanel    = (JPanel) getContentPane();
		pathPanel         = new FolderPathPanel( this );
		playlistSizeTf    = new JTextField( "8", 3 );
		playlistTb        = new JTable( new DefaultTableModel(null, colNames) );
		createPlaylistBt  = new JButton( "Create Playlist" );
		clearPlaylistBt   = new JButton( "Clear" );
		deleteFileBt      = new JButton( "Delete" );
		playAllFileBt     = new JButton( "Play All" );
		playFileBt        = new JButton( "Play" );
		listAllMediaRb    = new JRadioButton( "List All" );
		randomListMediaRb = new JRadioButton( "Random List" );
		JLabel playlistSizeLb = new JLabel( "Playlist Size: " );
		ButtonGroup playlistTypeGrp = new ButtonGroup();
		
		playlistTypeGrp.add( listAllMediaRb );
		playlistTypeGrp.add( randomListMediaRb );
		randomListMediaRb.setSelected( true );
		playlistTb.setPreferredSize( new Dimension(300,150) );
		playlistTb.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION );
		
		// Q. All the below code doesn't work, it should make the JTable
		//    display horiz & vert lines & show the column names but they
		//    dont show up??
		playlistTb.setShowHorizontalLines( true ); // 
		playlistTb.setShowVerticalLines( true );
		JTableHeader header = playlistTb.getTableHeader();
	    header.setBackground(Color.yellow);
	    JScrollPane pane = new JScrollPane( playlistTb );
	    
	    componentPanel.add(pane);
	    
		
		buildPanelEx2( playlistSizeLb ); // add JComponents to this frame
		
	}
	
	
	/**
	 * Post: Add all application JComponents to main panel using the Grid Layout format
	 */
	private void buildPanel( JLabel playlistSizeLb )
	{
		
		Box horizBox = Box.createHorizontalBox();
		componentPanel.setLayout( new GridLayout( 5, 1, 0, 10 ) );
		componentPanel.setBorder( new CompoundBorder (BorderFactory.createRaisedBevelBorder(),
                                                      new EmptyBorder(10,10,0,10)));

		componentPanel.add( pathPanel );

		horizBox.add( listAllMediaRb );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( randomListMediaRb );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( playlistSizeLb );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( playlistSizeTf );
		componentPanel.add( horizBox );
		
		horizBox = Box.createHorizontalBox();
		horizBox.add( Box.createHorizontalGlue() );
		horizBox.add( createPlaylistBt );
		componentPanel.add( horizBox );
		componentPanel.add( playlistTb );
		
		horizBox = Box.createHorizontalBox();
		horizBox.add( clearPlaylistBt );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( deleteFileBt );
		horizBox.add( Box.createHorizontalGlue() );
		horizBox.add( playAllFileBt );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( playFileBt );
		horizBox.setBackground( Color.blue );
		horizBox.setForeground( Color.red );
		componentPanel.add( horizBox );
		
	}
	
	
	/**
	 * Post: Add all application JComponents to main panel using the Border Layout format
	 */
	private void buildPanelEx( JLabel playlistSizeLb )
	{
		
		Box horizBox = Box.createHorizontalBox();
		componentPanel.setLayout( new BorderLayout(5,5) ); // 5, 1, 0, 10 ) );
		componentPanel.setBorder( new CompoundBorder (BorderFactory.createRaisedBevelBorder(),
                                                      new EmptyBorder(0,10,10,10)));

		componentPanel.add( pathPanel, BorderLayout.PAGE_START );

		horizBox.add( listAllMediaRb );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( randomListMediaRb );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( playlistSizeLb );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( playlistSizeTf );
		componentPanel.add( horizBox, BorderLayout.LINE_END );
		
		horizBox = Box.createHorizontalBox();
		horizBox.add( Box.createHorizontalGlue() );
		horizBox.add( createPlaylistBt );
		componentPanel.add( horizBox, BorderLayout.LINE_START );
		componentPanel.add( playlistTb, BorderLayout.AFTER_LAST_LINE );
		
		horizBox = Box.createHorizontalBox();
		horizBox.add( clearPlaylistBt );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( deleteFileBt );
		horizBox.add( Box.createHorizontalGlue() );
		horizBox.add( playAllFileBt );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( playFileBt );
		horizBox.setBackground( Color.blue );
		horizBox.setForeground( Color.red );
		componentPanel.add( horizBox, BorderLayout.PAGE_END );
		
	}
	
	
	/**
	 * Post: Add all application JComponents to main panel using one main Box where
	 *       horizontal boxes are added to it
	 */
	private void buildPanelEx2( JLabel playlistSizeLb )
	{
		
		Box mainBox = Box.createVerticalBox();
		Box horizBox = Box.createHorizontalBox();
		componentPanel.setLayout( new BorderLayout() );
		componentPanel.setBorder( new CompoundBorder (BorderFactory.createRaisedBevelBorder(),
                                                      new EmptyBorder(0,10,10,10)));

		mainBox.add( pathPanel );

		horizBox.setBorder( new EmptyBorder(0,0,10,0) );
		horizBox.add( listAllMediaRb );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( randomListMediaRb );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( playlistSizeLb );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( playlistSizeTf );
		mainBox.add( horizBox );
		
		horizBox = Box.createHorizontalBox();
		horizBox.setBorder( new EmptyBorder(0,0,10,0) );
		horizBox.add( Box.createHorizontalGlue() );
		horizBox.add( createPlaylistBt );
		mainBox.add( horizBox );
		mainBox.add( playlistTb );
		
		horizBox = Box.createHorizontalBox();
		horizBox.setBorder( new EmptyBorder(10,0,0,0) );
		horizBox.add( clearPlaylistBt );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( deleteFileBt );
		horizBox.add( Box.createHorizontalGlue() );
		horizBox.add( playAllFileBt );
		horizBox.add( Box.createHorizontalStrut(10) );
		horizBox.add( playFileBt );
		horizBox.setBackground( Color.blue );
		horizBox.setForeground( Color.red );
		mainBox.add( horizBox );
		
		componentPanel.add( mainBox, BorderLayout.CENTER );
	}
	
	
	/**
	 * Post: Register/Add event listeners to JComponents
	 */
	private void bindComponents()
	{
		
		// playlistTb add a listener
		listAllMediaRb.addActionListener( this );
		randomListMediaRb.addActionListener( this );
		createPlaylistBt.addActionListener( this );
		clearPlaylistBt.addActionListener( this );
		deleteFileBt.addActionListener( this );
		playAllFileBt.addActionListener( this );
		playFileBt.addActionListener( this );
	
	}
	
	
	/**
	 * Post: Record whenever a new 'folder destination' has been input or a folder 
	 *       path has been altered within the JComponent FolderPathPanel pathPanel.
	 */
	public void adviseDirectoryChange()
	{
		directoryAltered = true;
	}
	
	
	/**
	 * 
	 * Post: Returns true if the value in playlistTf is a valid integer 
	 *       value and stores the value in the variable playlistSize
	 *       
	 *       
	 * @return Returns true if value in playlist is an int > 0, else false
	 * 
	 */
	private boolean verifyPlaylistSize()
	{
		try 
		{
			int size = Integer.parseInt( playlistSizeTf.getText() );
			
			// Make sure size is not 0 or less
			if ( size < 1 )
			{
				return false;
			}
			
			playlistSize = size;
		}
		catch ( NumberFormatException ne )
		{
			JOptionPane.showMessageDialog( this, "Playlist Size must be an integer greater than 0", 
					                       "Error", JOptionPane.ERROR_MESSAGE );
			return false;
		}
		
		return true;	
	}
	
	
	/**
	 * Post: Search directories for media files & store them in the vector 
	 *       mediaList
	 */
	private void searchFoldersForMedia()
	{
		
		mediaList.clear(); 
		
		for ( int i=0; i < directoryList.size(); i++)
		{
			File folder = directoryList.elementAt( i );
			File directoryFiles[] = folder.listFiles( directoryFilter );
			
			// If folder actually exists
			if ( directoryFiles != null )
			{
				recursiveCollectMedia( directoryFiles, 1 );
			}
			else JOptionPane.showMessageDialog( this, 
					folder.getName() + " is an invalid directory or does not exist", 
					"Error", JOptionPane.ERROR_MESSAGE );
		}
		
	}
	
	
	/**
	 * 
	 * Post: Recursively collect all media files inside the array files. This
	 *       function will also search in any directories within 'files' array
	 *       if the degree of separation is above zero/within a specified 
	 *       limit
	 *       
	 */
	private void recursiveCollectMedia( File files[], int degreeSeparation )
	{
		
		int fileIndex = 0;
		int maxIndex  = files.length;
		
		while ( fileIndex < maxIndex )
		{
            // if this file is a directory search in there too
			if ( files[ fileIndex ].isDirectory() && degreeSeparation > 0 )
			{
				recursiveCollectMedia( files[ fileIndex ].listFiles( directoryFilter ), 
						               degreeSeparation - 1 );
			}
			else if ( files[ fileIndex ].isFile() )
			{
				mediaList.add( files[ fileIndex ] );
			}
			
			fileIndex++;
		}
		
		
		/* To make it a REAL recursive function
		
		if ( files.length > 0 )
		{
			// if this file is a directory search in there too
			if ( files[ 0 ].isDirectory() && degreeSeparation > 0 )
			{
				recursiveCollectMedia( files[ 0 ].listFiles( directoryFilter ), 
						               degreeSeparation - 1 );
			}
			else if ( files[ 0 ].isFile() )
			{
				mediaList.add( files[ 0 ] );
				files.deleteElement(0);
				recursiveCollectMedia( files, degreeSeparation );
			}
		}
		else return;      */
	}
	
	
	/**
	 * 
	 * Post: Returns true if the parameter is a media file with a valid extension.
	 *       Valid extension types; avi, wmv, flv, mpeg, mp3, mp4.
	 *       
	 * @param  f  file found in specified directory
	 * @return Returns true if file extension type meets criteria else false
	 * 
	 */
	private boolean isMediaFile( File f )
	{
		/*  
		Q. Is there a better way to determine the file type/extension of a file?
		
		The below code seems to only be able to identify between applications & directories?
		FileDataSource ds = new FileDataSource( f );   
        String fileType = ds.getContentType();   
		
        System.out.println( fileType );
		System.out.println( f.getName()  );
		
        if ( fileType == "application/octet-stream" ) //"video/quicktime" || fileType == "video/x-msvideo" ) // || 
			 //fileType == "mpeg" || fileType == "wmv" )
		{
			return true;
		}
		
		*/
        
        if ( f.getName().endsWith("rmvb") )
        {
        	return true;
        }
        else if ( f.getName().endsWith("avi") )
        {
        	return true;
        }
        else if ( f.getName().endsWith("mp3") )
        {
        	return true;
        }
        else if ( f.getName().endsWith("mp4") )
        {
        	return true;
        }
        else if ( f.getName().endsWith("mpeg") )
        {
        	return true;
        }
        else if ( f.getName().endsWith("wmv") )
        {
        	return true;
        }
        else if ( f.getName().endsWith("flv") )
        {
        	return true;
        }
		else return false;
	}
	
	
	/**
	 * Post: Create a playlist of random media files found in directories
	 */
	private void createPlaylist()
	{
		
		playlist.clear();
		
		// If no media files exist in directories
		if ( mediaList.size() <= 0 )
		{
			JOptionPane.showMessageDialog( this, "No media files found in directories",
					                       "Notify", JOptionPane.INFORMATION_MESSAGE );
			return;
		}
		// Build a playlist of randomly selected media
		else if ( playlistType == ListType.RANDOMLIST )
		{
			
			if ( mediaList.size() < playlistSize )
			{
				playlistSize = mediaList.size();
			}
			
			Vector <Integer> randomNums = randomGenerate( playlistSize, mediaList.size() );
			
			for (int i=0; i<playlistSize; i++)
			{
				playlist.add( mediaList.elementAt( randomNums.elementAt(i) ) );
			}
			
		}
		// Build a playlist containing all media files
		else playlist = (Vector <File>) mediaList.clone();
		
	}
	

	/**
	 * Post: Display random selection of media files in JTable
	 */
	private void displayPlaylist()
	{
		
		DefaultTableModel model = (DefaultTableModel) playlistTb.getModel();
		
		for (int i=0; i<playlist.size(); i++)
		{
			File selFile = playlist.elementAt(i);
			Object newRow[] = { selFile.getName(), "", selFile.getTotalSpace() };
			model.addRow( newRow );
		}
		
		validate();
		// playlistTb.repaint();  // do I need to do these???
		// pack();
	}
	
	
	/**
	 * 
	 * Post: Return a vector containing random numbers with no repeats. 
	 * 
	 * @param  size  the size of the vector to be returned
	 * @param  max   the maximum value a random number can have
	 * @return       Returns an integer vector of random numbers
	 * 
	 */
	private Vector<Integer> randomGenerate( int size, int max )
	{
		
		Vector <Integer> randomNums = new Vector<Integer>();

		// max must be greater than the perferred size to avoid infinite loop
		if ( max < size )
		{
			return null;
		}
		
		
		while ( randomNums.size() < size )
		{
			
			int rand = (int) Math.abs(Math.random() * max) ;
			
			// Make sure rand is not a repeated number
			if ( !randomNums.contains( rand )  )
			{
				randomNums.add( rand );
				
			}
			
		}
		
		return randomNums;
		
	}
	
	
	/**
	 * 
	 * Post: Determine which JTable rows the user has selected therefore what files
	 *       the user has selected
	 * 
	 * @return  Returns an array of files associated with the JTable rows the
	 *          user has selected
	 *          
	 */
	private File[] getSelectedFiles()
	{
		
		int selRows[] = playlistTb.getSelectedRows();
		
		// if nothing is selected
		if ( selRows.length == -1 )
		{
			return null;
		}
		
		File selFiles[] = new File[ selRows.length ];
		
		for (int i=0; i< selFiles.length; i++)
		{
			selFiles[i] = playlist.elementAt( selRows[i] );
		}

		return selFiles;
		
	}
	
	
	/**
	 * 
	 * Post: Play all selected media files with the operating systems default player
	 * 
	 * @param  media  a file array containing all files the user wants to play/open
	 * 
	 */
	private void playMedia( File media[] )
	{
		
		Desktop myDesktop = null;
			
		
		if ( !Desktop.isDesktopSupported() )
		{	
			JOptionPane.showMessageDialog( this, 
                    "The Java class java.awt.Desktop is not supported on the current platform ",
                    "Error:", JOptionPane.ERROR_MESSAGE );
			return;
		}
		else myDesktop = Desktop.getDesktop();
		
		
		// Play all media files
		for (int i=0; i< media.length; i++)
		{
			try 
			{
				myDesktop.open( media[i] );
				System.out.println( "Should be playing it ");
			}
			catch ( IOException e )
			{
				JOptionPane.showMessageDialog( this, 
						    "Error opening media file","Failed to open file: " + media[i].getName(),
						     JOptionPane.ERROR_MESSAGE );
			}
		}
		
	}
	
	
	/**
	 * 
	 * Post: Delete all files within the array 'media' from the users hard drive
	 * 
	 * @param  media  a file array containing all files the user has selected to 
	 *                delete from their hard drive 
	 *                
	 */
	private void deleteMedia( File media[] )
	{
		
		int decision = JOptionPane.showConfirmDialog( this, 
				                   "Are you sure you want to delete " + media.length + " files?",
				                   "Prompt", JOptionPane.YES_NO_CANCEL_OPTION );
				               
		if ( decision == JOptionPane.YES_OPTION ) 
		{		          
		
			for (int i=0; i<media.length; i++)
			{
				boolean success = false;
				
				if ( !media[i].exists() )
				{
					throw new IllegalArgumentException(
					          "Delete Function: no such file or directory: " + media[i].getName());
				}
				else if ( !media[i].canWrite() )
				{
					throw new IllegalArgumentException( 
							  "Delete Function: write protected " + media[i].getName() );
				}
				else success = media[i].delete();
				
				if ( success )
				{
					// delete cell from JTable
					
				}
				else JOptionPane.showMessageDialog( this, 
			                     "Failed to delete " + media[i].getName(),
			                     "Error:", JOptionPane.ERROR_MESSAGE );
			}
			
		}
		
		JOptionPane.showMessageDialog( this, 
	               "Delete Function finished",
	               "Notify:", JOptionPane.INFORMATION_MESSAGE );
	}
	
	
	/**
	 *  Main:
	 */
	public static void main(String[] args)
	{
		RandomPlaylist test = new RandomPlaylist();
		
	}
	
}


Folder Destination JPanel class:
/*
   ******************************************************************************************
   Random Playlist Application
   
   Author:   
   Platform: Java Swing & AWT
   
   ******************************************************************************************
   'Folder Path' Panel Class:
   
   Allows us to dynamically create JComponents which allow the user to specify a 
   specific folder to import media files(to create a playlist) from. 
   
   ******************************************************************************************
*/


import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.*;


public class FolderPathPanel extends JPanel implements ActionListener
{
	
	/// Class Variables:
	
	private RandomPlaylist parent;
	private Vector <JTextField> textFields;
	private Vector <JButton> browseBts;
	private JButton addNewElementBt;
	
	
	/// Class Methods:
	
	/**
	 * Constructor:
	 * 
	 */
	public FolderPathPanel( RandomPlaylist nParent )
	{
		
		parent          = nParent;
		textFields      = new Vector <JTextField>();
		browseBts       = new Vector <JButton>();
		addNewElementBt = new JButton( "Add" );
		
		initialise();
		insertNewElement();
		insertNewElement();
		
	}
	
	
	/**
	 * Post: Handle all action messages sent to this panel
	 */
	public void actionPerformed( ActionEvent ev )
	{
		
		if ( ev.getSource() == addNewElementBt )
		{
			insertNewElement();
			parent.pack();
		}
		else if ( ev.getSource() instanceof JButton )
		{
			// User has selected to choose a folder to import media files from
			
			JFileChooser folderDialog = new JFileChooser();
            folderDialog.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
            
            if ( folderDialog.showDialog(null, "Select") == JFileChooser.APPROVE_OPTION )
	        {
            	File folder = folderDialog.getSelectedFile();
	               
	            int textFieldIndex = browseBts.indexOf( ev.getSource() );
	            textFields.elementAt( textFieldIndex ).setText( folder.getPath() );
	            parent.adviseDirectoryChange();
	        }
			
            /* OR
            int returnVal = folderDialog.showOpenDialog( LoadAction.this );
            
            if ( JFileChooser.APPROVE_OPTION == folderDialog.showOpenDialog(LoadAction.this) ) 
            {
                System.out.println("==> Dir="+returnVal); 
            }
            */
            
		}
		else if ( (ev.getSource() instanceof JTextField) ) //&& ev.getActionCommand() == keyChange)
		{
			// The user has altered the contents of a text field so advice parent
			// we need to research/search new directories for media files
			
			parent.adviseDirectoryChange();
		}
		
	}
	
	
	/**
	 * Post: Add main JComponents to this panel
	 */
	private void initialise()
	{
		
		Box hBox = Box.createHorizontalBox();
		this.setLayout( new GridLayout(1,1,0,5) );
		this.setBorder( new EmptyBorder(0,5,0,5) );
		addNewElementBt.addActionListener( this );
		
		hBox.add( Box.createHorizontalGlue() );
		hBox.add( Box.createHorizontalStrut(10) );
		hBox.add( addNewElementBt );
		this.add( hBox );
		
		this.validate();
		
	}
	
	
	/**
	 * Post: Add a new JTextField & JButton to allow the user to select another
	 *       folder to import media files from
	 */
	private void insertNewElement()
	{
		
		GridLayout panelLayout = (GridLayout) this.getLayout();
		Box hBox = Box.createHorizontalBox();
		textFields.add( new JTextField() );
		browseBts.add( new JButton("Browse") );
		browseBts.lastElement().addActionListener( this );
		
		hBox.add( textFields.lastElement() );
		hBox.add( Box.createHorizontalStrut(10) );
		hBox.add( browseBts.lastElement() );
		
		// add new grid cell to panel
		panelLayout.setRows( panelLayout.getRows() + 2 );
		panelLayout.removeLayoutComponent( addNewElementBt );
		this.add( hBox);              // add to 2nd last grid cell
		this.add( addNewElementBt );
		
		this.validate();
		this.repaint();
		
	}
	
	
	/**
	 * 
	 * Post: Send all the directories in this panels' JTextFields to Random Playlist
	 *       class (so it can search them for media files)
	 * 
	 * @return  Returns a string vector containing the absolute directories the user
	 *          has chosen/identified for importing media files
	 *          
	 */
	public Vector <String> getFolderPaths()
	{
		
		Vector <String> folderPaths = new Vector <String>();
		
		for ( int i=0; i<textFields.size(); i++ )
		{
			String folderDir = textFields.elementAt( i ).getText();
			
			if ( folderDir != "" || folderDir != null )
			{
				folderPaths.add( folderDir );
			}
		}
		
		return folderPaths;
		
	}
	
	
	/**
	 * 
	 * Post: Send all the directories in this panels' JTextFields to Random Playlist
	 *       class (so it can search them for media files)
	 * 
	 * @return  Returns a file vector containing the absolute directories the user
	 *          has chosen/identified for importing media files
	 *          
	 */
	public Vector <File> getFolderDirectories()
	{
		
		Vector <File> folderPaths = new Vector <File>();
		
		for ( int i=0; i<textFields.size(); i++ )
		{
			String folderDir = textFields.elementAt( i ).getText();
			
			if ( !folderDir.equals("") && !folderDir.equals(null) )
			{
				folderPaths.add( new File(folderDir) );
			}
		}
		
		return folderPaths;
		
	}
}




Is This A Good Question/Topic? 0
  • +

Replies To: Advice & Criticism: Swing Application

#2 Luckless  Icon User is offline

  • </luck>
  • member icon

Reputation: 292
  • View blog
  • Posts: 1,146
  • Joined: 31-August 09

Re: Advice & Criticism: Swing Application

Posted 04 August 2010 - 09:40 PM

it's a lot to go through, but it seems like you did the major thing--building your GUI yourself AND doing it through a constructor. Looks nice
Was This Post Helpful? 0
  • +
  • -

#3 Crunch  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 139
  • View blog
  • Posts: 1,222
  • Joined: 28-July 09

Re: Advice & Criticism: Swing Application

Posted 04 August 2010 - 10:15 PM

That's a lot to go through :sweatdrop:
Was This Post Helpful? 0
  • +
  • -

#4 gretty  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 123
  • Joined: 25-May 09

Re: Advice & Criticism: Swing Application

Posted 05 August 2010 - 12:19 AM

View PostLuckless, on 04 August 2010 - 08:40 PM, said:

it's a lot to go through, but it seems like you did the major thing--building your GUI yourself AND doing it through a constructor. Looks nice


Thanks :), it was soo difficult getting the layout to work I think I'm going to use netbeans from now on.

View PostCrunch, on 04 August 2010 - 09:15 PM, said:

That's a lot to go through :sweatdrop:


Yeah lol its alot of code but the way its displayed makes it look alot more
Was This Post Helpful? 0
  • +
  • -

#5 bcranger  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 252
  • View blog
  • Posts: 1,199
  • Joined: 01-February 10

Re: Advice & Criticism: Swing Application

Posted 05 August 2010 - 03:55 AM

In your actionperformed method, better to have an Object that has the source than call it every time.
Object source = e.getSource();


Don't use NetBeans GUI Generator as it produces unmaintainable and cumbersome code. If you use that, nobody here will help you with your code. Swing is simple to write in most cases :)

Instead of using Math.random() every time, better to create one Random object as a class variable and call nextInt() on it, specifying the max range through your parameter, exclusive.
Was This Post Helpful? 0
  • +
  • -

#6 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5796
  • View blog
  • Posts: 12,631
  • Joined: 16-October 07

Re: Advice & Criticism: Swing Application

Posted 05 August 2010 - 05:03 AM

public void actionPerformed( ActionEvent ev ) {
	Object src = ev.getSource(); // method calls van be expensive, only do them once
	
	if ( src == createPlaylistBt ) {
		// if this is true, there's no need to process again, else if is also good
		// you started doing this later, be consistent
	} else if ( src == clearPlaylistBt ) {
	} else if ( src == deleteFileBt ) {
	} else if ( src == playAllFileBt ) {
	} else if ( src == playFileBt ) {
	} else if ( src == listAllMediaRb ) {
	} else if ( src == randomListMediaRb ) {
	}
}

private boolean isMediaFile( File f ) {
	// same problem, use one call to method
	String fileName  = f.getName();
	
	// your endsWith is also sloppy, presumably the . is also important?
	// perhaps
	int pos = fileName.lastIndexOf(".");
	if (pos!=-1) {
		String ext = fileName.substring(pos);
		
		String [] mediaTypes = new String [] { "rmvb","avi","mp3","mp4","mpeg","wmv","flv"};
		for(String s : mediaTypes ) {
			if (ext.equals(s)) { return true; }
		}
	}
	return false;
}

// again, all things you do have impact
// the earlier you can figure out you don't have to go any farther, the better

// this
Vector <File> playlistCpy = (Vector <File>) playlist.clone();
File selFiles[] = (File[]) playlistCpy.toArray();
 
if ( selFiles.length > 0 )
{
	playMedia( selFiles );
}


// can be this
if (playlist.size()>0) {
	playMedia( (File[]) playlist.toArray() ); // when you call the toArray you're making copies
}



Was This Post Helpful? 0
  • +
  • -

#7 Luckless  Icon User is offline

  • </luck>
  • member icon

Reputation: 292
  • View blog
  • Posts: 1,146
  • Joined: 31-August 09

Re: Advice & Criticism: Swing Application

Posted 05 August 2010 - 06:27 AM

all I have to say to Netbeans is blah. Don't you dare go down that programing path. This is an accomplishment you should be proud of and it is 40X more compact than generated code will be.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1