Page 1 of 1

Random Movie/File Selector Rate Topic: -----

#1 SPorter  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 11
  • View blog
  • Posts: 31
  • Joined: 29-June 12

Posted 02 July 2012 - 12:28 PM

Contents
Background
Required Knowledge
List of Classes
Section 1: The GUI (MoviePickerGui)
Section 2: The FileHandler class
Section 3: The MovieCollection class
Section 4: The Driver (MoviePicker)

Background:
Hey guys, I am relatively new to this forum as a member, but not as a user. I am halfway to my degree in computer science and I've been doing a lot of hacking (programming, not actually hacking haha) lately to get better and I really loved these tutorials when I was starting out programming for the first time (2 whole years ago)! So, I thought I would give back.

Anyhow, whenever my girlfriend would come over and we wanted to watch a movie, it was always:
"You pick"
"No, you pick"
"I don't care, you pick"
"I don't care either, you pick"

So, I figured, I needed to write a program that would randomly select a movie from where I keep my movies stored so that we just fire it up and neither of us have to pick a movie :) (She loves it by the way haha). The project is SUPER simple so I figured it would make a great tutorial for beginners :)

Required Knowledge:
This tutorial is great for the newest beginners to java programming. You don't need to know anything before starting this tutorial; however, knowing some things beforehand can make it easier to understand. I recommend knowing the following:

-Basic programming knowledge
  • Java classes and how they work together
  • if/if else statements
  • For loops
  • Constructors and objects
  • Creating methods
  • Calling methods
  • etc.

-Basic java swing components
-What is an ActionListener and ActionEvent
-I recommend using Eclipse to make your Java programs. So some Eclipse knowledge would be good.

You can find all this and more at http://101.lv/learn/Java/ch1.htm if you would like to get a better grasp on programming as a beginner.

List of Classes:
Before beginning, you should look at our list of classes and study the code so that you can get a good understanding of how things work. One goal of this tutorial is to get you to be able to read and understand code. Look at each method, try to figure out how each method works. Once you think you've got it, proceed through the tutorial and see if you were right :)

Class 1: MoviePickerGui
import java.awt.Desktop;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;


@SuppressWarnings("serial")
public class MoviePickerGui extends JFrame implements ActionListener {

	private JButton next, open, quit;
	private JLabel movieTitle;
	private JPanel buttonPanel, titlePanel;
	private JSplitPane topBotSplit;
	private JFileChooser fileChooser;
	private Font font = new Font("serif", Font.BOLD, 60);
	private FileHandler fileHandler;

	
	public MoviePickerGui(){
		this.setSize(1200,350);
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setTitle("Stephen's Super Special Show Screening Selector ---- " +
				"Made for his totally awesome, beautiful, shmexy girlfriend Alexis :)/>");
		
		initialize();
	}
	
	private void initialize(){
		setupRootDirectory();
		setupButtons();
		setupLabels();
		setupPanels();
		setupSplitPane();
		next();
	}
	
	private void setupRootDirectory() {
		fileChooser = new JFileChooser();
		
		JOptionPane.showMessageDialog(null, "Please select the directory where your movies are stored");
		
		fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		int flag = fileChooser.showOpenDialog(this);
		
		if(flag == JFileChooser.CANCEL_OPTION){
			System.exit(0);
		}
		
		File file = fileChooser.getSelectedFile();
		System.out.print(file.toString());
		fileHandler  = new FileHandler(file.toString());
	}
	
	private void setupButtons() {
		next = new JButton("No");
		open = new JButton("Yes");
		quit = new JButton("Quit");
		
		next.addActionListener(this);
		open.addActionListener(this);
		quit.addActionListener(this);
	}
	
	private void setupLabels() {
		movieTitle = new JLabel();
		movieTitle.setFont(font);
	}
	
	private void setupPanels(){
		buttonPanel = new JPanel(new GridLayout(1,3));
		buttonPanel.add(open);
		buttonPanel.add(next);
		buttonPanel.add(quit);
		
		titlePanel = new JPanel();
		titlePanel.add(movieTitle);
	}
	
	private void setupSplitPane() {
		topBotSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, titlePanel, buttonPanel);
		topBotSplit.setDividerLocation(250);
		
		this.add(topBotSplit);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == next)
			next();

		else if(e.getSource() == open)
			open();

		else if(e.getSource() == quit)
			System.exit(0);
	}
	
	private void next() {
		try {
			fileHandler.chooseRandomMovie();
			
			movieTitle.setText(fileHandler.setRandomMovieTitle() + "?");
		} catch (IOException e1) {
			JOptionPane.showMessageDialog(null, "File does not exist");
		} catch (IllegalArgumentException e1){
			JOptionPane.showMessageDialog(null, "No more movies to select, repopulating list");
			try {
				fileHandler.readInFiles();
				next();
			} catch (IOException e2) {
				JOptionPane.showMessageDialog(null, "Could not repopulate, files do not exist");
			}
		}
	}
	
	private void open() {
		try {
			if(Desktop.isDesktopSupported()){
				fileHandler.openMovie();
				System.exit(0);
			}
		} catch (IOException e1) {
			JOptionPane.showMessageDialog(null, "File does not exist");
		}
	}
	
}


Class 2: FileHandler
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;

import javax.swing.JOptionPane;

public class FileHandler {

	private MovieCollection movieCollection;
	private File file;
	private String movieWatch, rootDir;

	public FileHandler(String rootDir) {
		this.rootDir = rootDir;
		movieCollection = new MovieCollection();
		try {
			readInFiles();
		} catch (IOException e) {
			JOptionPane.showMessageDialog(null, "File does not exist");
		}
	}

	public void readInFiles() throws IOException {
		checkPath();
	}

	private void checkPath() throws IOException {
		File filename = new File(rootDir); 
		if (!filename.exists()) {
			JOptionPane.showMessageDialog(null, rootDir + " - No such file/directory exists");
			System.exit(0);
		}
		rootlist(rootDir); 
	}

	private void rootlist(String fname) throws IOException {
		File filenames = new File(fname); 
		if (!filenames.isDirectory()) { 
			movieCollection.addMovie(filenames); 
			return;
		}

		String filelists[] = filenames.list();
		for (int i = 0; i < filelists.length; i++) { 
			rootlist(fname + File.separator + filelists[i]); 
		}
	}

	public void chooseRandomMovie() throws IOException {
		file = movieCollection.randomize();
	}
	
	public String setRandomMovieTitle(){
		movieWatch = file.getName();
		trimTitle();
		return movieWatch;
	}
	
	public void openMovie() throws IOException{
		if (Desktop.isDesktopSupported()) {
			Desktop.getDesktop().open(file);
		}
	}
	
	private void trimTitle(){	
		char[] titleArray = movieWatch.toCharArray();

		for(int i=0; i<titleArray.length; i++){
			if(titleArray[i] == '[' || titleArray[i] == '(' || titleArray[i] == '.'){
				movieWatch = movieWatch.substring(0, i);
				break;
			}
		}
	}
}



Class 3: MovieCollection
import java.io.File;
import java.util.ArrayList;
import java.util.Random;

public class MovieCollection {

	private ArrayList<File> fileList;

	public MovieCollection() {
		fileList = new ArrayList<File>();
	}

	public void addMovie(File file) {
		fileList.add(file);
	}

	public File randomize() {
		Random generator = new Random();
		File file = fileList.remove(generator.nextInt(fileList.size()));
		return file;
	}
}


Class 4: MoviePicker
import java.io.IOException;

public class MoviePicker {

	public static void main(String args[]) throws IOException {
		MoviePickerGui mpg = new MoviePickerGui();
		mpg.setVisible(true);
	}
}



Section 1: The GUI (MoviePickerGui):

import java.awt.Font;
import java.awt.GridLayout; //A layout manager
import java.awt.event.ActionEvent; //The ActionEvent
import java.awt.event.ActionListener; //The ActionListener
import java.io.File; //The file object
import java.io.IOException; //The exception we need, discussed later

import javax.swing.JButton; //Swing component for buttons
import javax.swing.JFrame; //Swing component for JFrames
import javax.swing.JLabel; //Swing component for JLabels
import javax.swing.JOptionPane; //Swing component for JOPtionPanes
import javax.swing.JPanel; //Swing component for JPanels
import javax.swing.JSplitPane; //Swing component for JSplitPane
import javax.swing.JFileChooser; //Swing component for JFileChooser


@SuppressWarnings("serial")
public class MoviePickerGui extends JFrame implements ActionListener {

	private JButton next, open, quit; //Our buttons :)/>
	private JLabel movieTitle; //The title of the movie it picked
	private JPanel buttonPanel, titlePanel; //The panels to hold our stuff
	private JSplitPane topBotSplit; //Our split pane
	private Font font = new Font("serif", Font.BOLD, 150); //The font we will use for our title
	private JFileChooser fileChooser; //Let's us have the user select directories/files (directories only in our case)
	private FileHandler fileHandler; //Our own object we have made, check out the FileHandler class

	
	public MoviePickerGui(){
		//Set the size of our component. The first int is the width, the second the height
				//Yes, for you guys that see it, I am using a rather large width because it will fit
				//The font size I use and it fits my screen :)/> Remember, I use this for myself.
				//You can customize the size to however you want it, just remember to change the font
				//Size!
				this.setSize(1500,350);
				this.setLocationRelativeTo(null); //This makes our GUI appear center screen.
				this.setDefaultCloseOperation(EXIT_ON_CLOSE); //Make it close when they click on the red X
				this.setTitle("Stephen's Super Special Show Screening Selector ---- " + //Set the title. Like it? :)/>
						"Made for his totally awesome, beautiful, shmexy girlfriend Alexis :)/>");

				initialize(); //A call to the initialize method which is in this class.
			}


			private void initialize(){
				//A call to our setupRootDirectory method
				setupRootDirectory();
				//A call to our setupButtons method
				setupButtons();
				//A call to our setupLabels method
				setupLabels();
				//Get the idea?
				setupPanels();
				setupSplitPane();
				/*
				 * We call our next method in this class so that when the user selects their directory, we can populate a random pick for them already.
				 * If we didn't do this, when the GUI opened, all you would see if buttons, no movie title, so they would have to click "No" in order
				 * to populate a movie. We'll just take care of that step for them the first time :)/>
				 */
				next();
			}
	
	private void setupRootDirectory() {
		//Initialize our fileChooser
		fileChooser = new JFileChooser();
		
		//Let's prompt the user so they know what it is that they are selecting. Putting this here (before the fileChooser stuff below)
		//Will make it so it prompts the user and "pauses" the program until they click ok, then will set the program in motion again :)/>
		JOptionPane.showMessageDialog(null, "Please select the directory where your movies are stored");
		
		//Now, we only want the user to select a directory, not a specific file (how can we randomly choose files if the user selects
		//a file? That's the complete opposite of what we are doing with this program haha).
		fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		
		/* 
		 * This guy is a bit tricky to understand the first time around. Basically, I am creating an int called flag and setting
		 * it equal to fileChooser.showOpenDialog. This is because the showOpenDialog will open up the dialog window for the user to
		 * select a file, but it will also return an int value based on whether the user has selected "Cancel" or "Open". We can use this
		 * int value to decide what to do if the user clicks the cancel button or the open button. Take a look at the if statement below
		 */
		int flag = fileChooser.showOpenDialog(this);
		
		/*
		 * So here, I am saying "Hey, if the int value I got from the user is the same as the int value which means "Cancel", then let's
		 * quit the program." That's why we make the flag int value as I have stated in the above comment
		 */
		if(flag == JFileChooser.CANCEL_OPTION){
			System.exit(0);
		}
		
		//If the user didn't click cancel, then let's get the file they selcted (a directory in our case since that's all they can pick)
		File file = fileChooser.getSelectedFile();
		//Now we initialize our fileHandler object with the directory the user selected. The file.toString method will return the entire
		//Directory and not just the name of the directory which the getName method returns. We need the whole directory here
		fileHandler  = new FileHandler(file.toString());
	}
	
	private void setupButtons() {
		/*Initialize our buttons. In other words, make them exist*/
		next = new JButton("No"); //The "No" inside the constructor makes the button say No
		open = new JButton("Yes");
		quit = new JButton("Quit");

		//Add the buttons to the ActionListener so we can hear when the user clicks a button
		next.addActionListener(this);
		open.addActionListener(this);
		quit.addActionListener(this);
	}

	private void setupLabels() {
		movieTitle = new JLabel(); //Initialize our label
		movieTitle.setFont(font);  //Make it use our font
	}

	private void setupPanels(){
		/*Now we are going to set up our panels to hold our stuff*/
		buttonPanel = new JPanel(new GridLayout(1,3)); //A 1x3 grid for our buttons
		
		/*
		 * Add the button to the panel. Order matters! The layout manager will place the buttons
		 * as you add them from left to right then move down to the next row if you have more than 1
		 * row
		 */
		buttonPanel.add(open);
		buttonPanel.add(next);
		buttonPanel.add(quit);

		/*
		 * We use a separate panel for our label so that we can place them in different locations in the
		 * JFrame
		 */
		titlePanel = new JPanel();
		titlePanel.add(movieTitle);
	}

	private void setupSplitPane() {
		/*
		 * Make our split pane! The first part is whether we want a vertical split or horizontal split (we want vertical or top-bottom split).
		 * The second part is what we want to go on the top and the third is what we want on the bottom. So, we want our movie title to go on top
		 * and our buttons to go on the bottom
		 */
		topBotSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, titlePanel, buttonPanel);
		topBotSplit.setDividerLocation(250); //This sets where the divider of the split pane will go. In our case it works from top to bottom.

		this.add(topBotSplit); //Add this to our JFrame so the user can see it
	}

	/*This is our action listener. We can tell the program what to do when certain things happen, like button clicks*/
	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == next) //If the user clicks next
			next(); //Call out next method

		else if(e.getSource() == open) //If the user clicks open
			open(); //Call our open method

		else if(e.getSource() == quit) //If the user clicks quit
			System.exit(0); //Quit the application
	}

	private void next() {
		try { //Try catch means it will try running the code and if an error happens, it will catch it and let you do something.
			fileHandler.chooseRandomMovie(); //Choose our random movie in our fileHandler class
			movieTitle.setText("Watch " + fileHandler.setRandomMovieTitle() + "?"); //Set our label to show the title
			
		} catch (IOException e1) { //If the file doesn't exist
			JOptionPane.showMessageDialog(null, "File does not exist"); //Tell the user
		} catch (IllegalArgumentException e1){ //If there are no more movies in the file (the user said "No" to all the movies)
			JOptionPane.showMessageDialog(null, "No more movies to select, repopulating list"); //Tell the user
			try { //Then repopulate the list so they can look through it again.
				fileHandler.readInFiles(); //Repopulating it baby
				next(); //Call the method again to show a new random movie from the repopulated list
			} catch (IOException e2) { //Same as before
				JOptionPane.showMessageDialog(null, "Could not repopulate, files do not exist");
			}
		}
	}

	private void open() {
		try {//Same as before
			fileHandler.openMovie();//Open the movie with our fileHandler class
		} catch (IOException e1) {//Same as before
			JOptionPane.showMessageDialog(null, "File does not exist");
		}
	}
	//The Desktop API is pretty cool because it opens the file using the default program set up by the user to open it
}



Alright, here we go. Now, whenever I am making a program which will contain java swing components (GUI stuff), I always like to start with that class. That's why the first thing we are doing is building the Graphical User Interface (GUI). This will make it so we can interact with our program graphically instead of from the command line (I'm not a huge fan of command line stuff, especially for a program like this).

So, let's make our class shall we?

public class MoviePickerGui extends JFrame implements ActionListener {


We need to extend JFrame so that we can treat our class like a JFrame. If you don't know about the extend command, you should check out http://www.javacoffe...4/java104.html. We then implement an action listener so we can listen for actions and do stuff when those actions happen (open a file if the user clicks open).

To start off, let's talk about the imports we will need. If you don't know, imports are libraries which are contained in the java Application Programming Interface (API). If you are reading this, hopefully you have already downloaded the Java Development Kit (JDK) which contains these libraries and the Java Platform, Standard Edition (Java SE) which will allow you to run java applications. You can nab these HERE.

So, the imports we need for this class are:

import java.awt.Font;
import java.awt.GridLayout; //A layout manager
import java.awt.event.ActionEvent; //The ActionEvent
import java.awt.event.ActionListener; //The ActionListener
import java.io.File; //The file object
import java.io.IOException; //The exception we need, discussed later

import javax.swing.JButton; //Swing component for buttons
import javax.swing.JFrame; //Swing component for JFrames
import javax.swing.JLabel; //Swing component for JLabels
import javax.swing.JOptionPane; //Swing component for JOPtionPanes
import javax.swing.JPanel; //Swing component for JPanels
import javax.swing.JSplitPane; //Swing component for JSplitPane
import javax.swing.JFileChooser; //Swing component for JFileChooser



Terms:
Font: This is an object that let's us set our own font, font type, and font size. We use this for our movie title.
http://docs.oracle.c...a/awt/Font.html

Layout Manager: The layout manager is really nice to have. It will automatically set up your components in certain ways depending on the layout manager you are using. For the GridLayout, it will set things up in a grid form. More on layout managers can be found at http://docs.oracle.c...out/visual.html

Action Event: Indicates that an action occurred with one of our components (a button in our case and in most cases).
http://docs.oracle.c...out/visual.html

Action Listener: Receives an Action Event to allow you to say what to do when whatever action happened (like clicking a button).
http://docs.oracle.c...onListener.html

File: This is a file object which stores a file location we either set or have the user select. In our case, the user will select it.
http://docs.oracle.c...va/io/File.html

IOException: An exception (error) that happens when the program can't find the file you are looking for because you might have deleted it or entered in the wrong file path.
http://docs.oracle.c...OException.html

JButton: Just what it sounds like, a button :)
http://docs.oracle.c...ng/JButton.html

JFrame: Basically, this is the main window that holds all the other stuff.
http://docs.oracle.c...ing/JFrame.html

JLabel: This holds our text.
http://docs.oracle.c...ing/JLabel.html

JOptionPane: This is a pretty cool component that pops up another window (of your choice) and does stuff. We use this to display error messages. Definitely check out the API documentation on this guy if you are new to GUI stuff!
http://docs.oracle.c...OptionPane.html

JPanel: Kind of like a frame, but it's not the main window. It will hold our buttons and labels and stuff and we can pass a layout manager to it so the stuff it holds follows the layout manager.
http://docs.oracle.c...ing/JPanel.html

JSplitPane: This is a pretty cool component for when you want parts of your main window to be split up and have a divider. Definitely check this guy out if you are new to GUI stuff also :)
http://docs.oracle.c...JSplitPane.html
A cool example of JSplitPane in action: http://docs.oracle.c.../splitpane.html

JFileChooser: This is another nifty swing component. This guy let's you have the user select files/directories from a dialog window! It's super easy to use, but makes your code seem complex to the user, a nice win-win :)
http://docs.oracle.c...ileChooser.html

So, that's our imports. I know it sounds like a lot, but the more GUI stuff and programming you do, the more second nature this stuff will become and it will get uber easy.

Now, let's take care of our instance data (variables which can be used by any method you create. http://java.sun.com/docs/glossary.html under instance variable). We need these so that our methods can all communicate with each other through the same variables.

	
     private JButton next, open, quit; //Our buttons :)/>
	private JLabel movieTitle; //The title of the movie it picked
	private JPanel buttonPanel, titlePanel; //The panels to hold our stuff
	private JSplitPane topBotSplit; //Our split pane
	private Font font = new Font("serif", Font.BOLD, 150); //The font we will use for our title
	private FileHandler fileHandler = new FileHandler();////Our own object we have made, check out the FileHandler class



Now, we need to create our GUI constructor so that our main method can start up our GUI. Easy stuff, take a look:

	public MoviePickerGui(){
                //Set the size of our component. The first int is the width, the second the height
                //Yes, for you guys that see it, I am using a rather large width because it will fit
                //The font size I use and it fits my screen :)/> Remember, I use this for myself.
                //You can customize the size to however you want it, just remember to change the font
                //Size!
		this.setSize(1500,350);
		this.setLocationRelativeTo(null); //This makes our GUI appear center screen.
		this.setDefaultCloseOperation(EXIT_ON_CLOSE); //Make it close when they click on the red X
		this.setTitle("Stephen's Super Special Show Screening Selector ---- " + //Set the title. Like it? :)/>
				"Made for his totally awesome, beautiful, shmexy girlfriend Alexis :)/>");
		
		initialize(); //A call to the initialize method which is in this class.
	}


You will notice we are using the statement 'this'. The 'this' statement is used because our class is like a JFrame now because we are extending it. So when we say 'this' it's like we have a JFrame object and we are calling that object. (So if we had a JFrame object called myJFrame, the 'this.doSomething' statement is like saying 'myJFrame.doSomething'. Make sense?) You can read more on the 'this' statement at http://javapapers.co...a-this-keyword/

You can also see a method we are calling which is initialize(); This is a method that is actually going to be in our code. I like to separate the setting up of components into different methods so they are in their own, easy to find locations within the code. Let's take a look at our initialize method:

			private void initialize(){
				//A call to our setupRootDirectory method
				setupRootDirectory();
				//A call to our setupButtons method
				setupButtons();
				//A call to our setupLabels method
				setupLabels();
				//Get the idea?
				setupPanels();
				setupSplitPane();
				/*
				 * We call our next method in this class so that when the user selects their directory, we can populate a random pick for them already.
				 * If we didn't do this, when the GUI opened, all you would see if buttons, no movie title, so they would have to click "No" in order
				 * to populate a movie. We'll just take care of that step for them the first time :)/>
				 */
				next();
			}


Bascially, in this method we are going to call all of our setup methods which we created. Like I said before, I like to do this so that where I make my buttons and where I make my labels are in their own place making it easier for me to make changes and read my code. It's also good programming practice to separate the components like this.

So, let's start by using our JFileChooser to have the user select which root directory to look in and collect files (movies in my case, but it can be any type of file you wish to randomly select).

	private void setupRootDirectory() {
		//Initialize our fileChooser
		fileChooser = new JFileChooser();
		
		//Let's prompt the user so they know what it is that they are selecting. Putting this here (before the fileChooser stuff below)
		//Will make it so it prompts the user and "pauses" the program until they click ok, then will set the program in motion again :)/>
		JOptionPane.showMessageDialog(null, "Please select the directory where your movies are stored");
		
		//Now, we only want the user to select a directory, not a specific file (how can we randomly choose files if the user selects
		//a file? That's the complete opposite of what we are doing with this program haha).
		fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		
		/* 
		 * This guy is a bit tricky to understand the first time around. Basically, I am creating an int called flag and setting
		 * it equal to fileChooser.showOpenDialog. This is because the showOpenDialog will open up the dialog window for the user to
		 * select a file, but it will also return an int value based on whether the user has selected "Cancel" or "Open". We can use this
		 * int value to decide what to do if the user clicks the cancel button or the open button. Take a look at the if statement below
		 */
		int flag = fileChooser.showOpenDialog(this);
		
		/*
		 * So here, I am saying "Hey, if the int value I got from the user is the same as the int value which means "Cancel", then let's
		 * quit the program." That's why we make the flag int value as I have stated in the above comment
		 */
		if(flag == JFileChooser.CANCEL_OPTION){
			System.exit(0);
		}
		
		//If the user didn't click cancel, then let's get the file they selcted (a directory in our case since that's all they can pick)
		File file = fileChooser.getSelectedFile();
		//Now we initialize our fileHandler object with the directory the user selected. The file.toString method will return the entire
		//Directory and not just the name of the directory which the getName method returns. We need the whole directory here
		fileHandler  = new FileHandler(file.toString());
	}


private void setupButtons() {
		/*Initialize our buttons. In other words, make them exist*/
		next = new JButton("No"); //The "No" inside the constructor makes the button say No
		open = new JButton("Yes");
		quit = new JButton("Quit");

		//Add the buttons to the ActionListener so we can hear when the user clicks a button
		next.addActionListener(this);
		open.addActionListener(this);
		quit.addActionListener(this);
	}


Here we set up our buttons. The comments are pretty self explanatory. Remember, though, to always add your buttons to the ActionListener or when the user clicks the button, nothing will happen.

Next up we are going to set up our label (for our movie title), our panels (to hold our stuff), and our split pane (to separate our movie title and movie buttons with a re-sizable divider).

	private void setupLabels() {
		movieTitle = new JLabel(); //Initialize our label
		movieTitle.setFont(font);  //Make it use our font
	}

	private void setupPanels(){
		/*Now we are going to set up our panels to hold our stuff*/
		buttonPanel = new JPanel(new GridLayout(1,3)); //A 1x3 grid for our buttons
		
		/*
		 * Add the button to the panel. Order matters! The layout manager will place the buttons
		 * as you add them from left to right then move down to the next row if you have more than 1
		 * row
		 */
		buttonPanel.add(open);
		buttonPanel.add(next);
		buttonPanel.add(quit);

		/*
		 * We use a separate panel for our label so that we can place them in different locations in the
		 * JFrame
		 */
		titlePanel = new JPanel();
		titlePanel.add(movieTitle);
	}

	private void setupSplitPane() {
		/*
		 * Make our split pane! The first part is whether we want a vertical split or horizontal split (we want vertical or top-bottom split).
		 * The second part is what we want to go on the top and the third is what we want on the bottom. So, we want our movie title to go on top
		 * and our buttons to go on the bottom
		 */
		topBotSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, titlePanel, buttonPanel);
		topBotSplit.setDividerLocation(250); //This sets where the divider of the split pane will go. In our case it works from top to bottom.

		this.add(topBotSplit); //Add this to our JFrame so the user can see it
	}


The comments on these methods explain what we are doing here quite well.

Next up is the ActionListener. As I've said, this is essential so that when the user does something (like click a button) we can make our program do something.

/*This is our action listener. We can tell the program what to do when certain things happen, like button clicks*/
	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == next) //If the user clicks next
			next(); //Call out next method

		else if(e.getSource() == open) //If the user clicks open
			open(); //Call our open method

		else if(e.getSource() == quit) //If the user clicks quit
			System.exit(0); //Quit the application
	}


You will notice the @Override here because since we are implementing ActionListener, we HAVE to override this method in our class. (see THIS ARTICLE for information about implementing interfaces). The command e.getSource() basically "hears" which button has been clicked so you can do something. Look at the first if statement. We see which button they pressed (e.getSource()) then we say, "hey... if the button they clicked was our next button, then we are going to call the next method". You generally want your action listeners to be short and sweet.

Next up is our next method!

	private void next() {
		try { //Try catch means it will try running the code and if an error happens, it will catch it and let you do something.
			fileHandler.chooseRandomMovie(); //Choose our random movie in our fileHandler class
			movieTitle.setText("Watch " + fileHandler.setRandomMovieTitle() + "?"); //Set our label to show the title
			
		} catch (IOException e1) { //If the file doesn't exist
			JOptionPane.showMessageDialog(null, "File does not exist"); //Tell the user
		} catch (IllegalArgumentException e1){ //If there are no more movies in the file (the user said "No" to all the movies)
			JOptionPane.showMessageDialog(null, "No more movies to select, repopulating list"); //Tell the user
			try { //Then repopulate the list so they can look through it again.
				fileHandler.readInFiles(); //Repopulating it baby
				next(); //Call the method again to show a new random movie from the repopulated list
			} catch (IOException e2) { //Same as before
				JOptionPane.showMessageDialog(null, "Could not repopulate, files do not exist");
			}
		}
	}


This method just goes to the next movie in the list of movies (which is pulled from our other classes). The comments do a pretty good job explaining what we are doing.

Last up here is our open method. The comments, again, speak for themselves :)

private void open() {
		try {//Same as before
			fileHandler.openMovie();//Open the movie with our fileHandler class
		} catch (IOException e1) {//Same as before
			JOptionPane.showMessageDialog(null, "File does not exist");
		}
	}


Section 2: The FileHandler Class

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;

import javax.swing.JOptionPane;

public class FileHandler {
	/*Instance data*/
	private MovieCollection movieCollection;
	private File file;
	private String movieWatch, rootDir;

	public FileHandler(String rootDir) {
		this.rootDir = rootDir;
		movieCollection = new MovieCollection(); //Initialize our MovieCollection object
		
		try {
			readInFiles(); //Call our redInFiles method
			
		}catch (IOException e) {
			JOptionPane.showMessageDialog(null, "File does not exist");
		}
	}

	public void readInFiles() throws IOException {
		checkPath(); //Call our checkPath method
	}

	private void checkPath() throws IOException {
		File filename = new File(rootDir); //The location we are going to look in
		if (!filename.exists()) { //If the file doesn't exist
			JOptionPane.showMessageDialog(null, rootDir + " - No such file/directory exists"); //Tell the user
			return;
		}
		rootlist(rootDir); //Call our rootlist method with the directory we want to look in
	}

	private void rootlist(String fname) throws IOException {
		File filenames = new File(fname); //Make a file object out of our directory we are looking in
		if (!filenames.isDirectory()) { //If the file isn't a directory
			movieCollection.addMovie(filenames); //add it to our list of movies
			return;
		}

		String filelists[] = filenames.list(); //Make an array which will hold our directories (if more than one)
		for (int i = 0; i < filelists.length; i++) { //for however many directories we have
			rootlist(fname + File.separator + filelists[i]); //Go into them and add the movies they have to our list
			/*the .separator command just means the '\' symbol. You could use \\ also, doesn't really matter*/
		}
	}

	public void chooseRandomMovie() throws IOException {
		file = movieCollection.randomize(); //Call our randomize method
	}
	
	public String setRandomMovieTitle(){
		movieWatch = file.getName(); //What the title of the movie is
		trimTitle(); //A call to our trimTitle method below
		return movieWatch; //Give our GUI the title so we can show it to our user
	}
	
	public void openMovie() throws IOException{
		if (Desktop.isDesktopSupported()) { //Is this API supported?
			Desktop.getDesktop().open(file); //If yes, open the movie!
			/*
			 * Here we use the Desktop API which basically just finds the default program the system uses to open the file, then opens it with that program
			 * http://docs.oracle.com/javase/6/docs/api/java/awt/Desktop.html
			 */
		}
	}
	
	/*
	 * We want to trim down our title so we don't have to see things like "movie.mp4" or "movie.wmb" or "movie[2010].avi".
	 * This is why we have this method, we are going to take that stuff off before we show the user what the title is that
	 * way the user get's only the movie title :)/> 
	 */
	private void trimTitle(){
		/*
		 * The toCharArray is an awesome method when it comes to strings. I use this a lot in my toString methods. Basically,
		 * it takes your string and breaks it apart one by one. So, the string "abcd" turns into the array [a][b][c][d].
		 * Unfortuantely this method returns these as characters, so you will need to learn some tricks about how to go from
		 * characters to strings and strings to characters if you plan on switching letters around and making new strings using
		 * this method. I recommend reading up on the StringBuilder :)/>
		 * http://docs.oracle.com/javase/tutorial/java/data/buffers.html
		 */
		char[] titleArray = movieWatch.toCharArray();

		/*
		 * Alright, so we encounter our for loop here. Basically this is saying "Hey, so let's start from 0 (where the first index
		 * of the array is at) and let's go until we hit the end of the array (titleArray.length) and every time we go through the loop
		 * once, up our count once so we know when we hit the end". 
		 */
		for(int i=0; i<titleArray.length; i++){
			//Here we loop until we hit either the character [, (, or . (the || symbol means or).
			if(titleArray[i] == '[' || titleArray[i] == '(' || titleArray[i] == '.'){
				//If we hit one of these characters, return everything up to that character
				//and end the loop which returns only our title.
				movieWatch = movieWatch.substring(0, i);
				break;
			}
		}
		/*
		 * The way in which the loop works is simple, though I know it may seem complicated. Let's say we have a movie and it's title is
		 * "Movie(2009).avi". Our loop works like this:
		 * 
		 * Start at M
		 * is 'M' the same as '[' or '(' or '.'?
		 * No, then move to the next one which is 'o'
		 * 
		 * o -> v -> i -> e -> (
		 * 
		 * Wait! We have a '(' which is the same as the '(' we are looking for
		 * Return everything up to that point in a substring which was Movie
		 * Stop the loop
		 */
	}
}



For this code, the comments are pretty self explanatory, so I won't go as in depth as I did with the GUI class. This tutorial is about you learning how to read and understand code, so this is a good way to practice that.

Section 3: The MovieCollection class
import java.io.File;
import java.util.ArrayList;
import java.util.Random;

public class MovieCollection {
	/*
	 * An ArrayList which will hold all the movies that we have
	 * http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html
	 */
	private ArrayList<File> fileList;

	public MovieCollection() {
		fileList = new ArrayList<File>(); //Initialize our list
	}

	public void addMovie(File file) {
		fileList.add(file); //Add the movies we find to our list (called by FileHandler)
	}

	/*Let's pick a random movie shall we?*/
	public File randomize() {
		Random generator = new Random(); //Get a random number generator
		
		/*
		 * Here we are creating a file which holds the path to the random movie
		 * You will notice that we are calling the remove method of the ArrayList class.
		 * This is because the remove method actually returns what we are removing that way
		 * we can get the random movie's file path, then remove it from the list so that the
		 * movie picker won't randomly go to the same movie if the user already said "No" to watching
		 * the movie. The generator.nextInt(fileList.size()) call is saying "hey... so I want you to pick
		 * out of the list a number that is between 0 and the amount of movies you have in your list.
		 * 
		 * So, all togehter this one line of code says
		 * "Hey, create a new file and get the file path from our list of movies by getting the movie
		 * then removing it from our list at a random location between 0 and the amount of movies
		 * in your list"
		 * 
		 * Pretty crazy huh?
		 */
		File file = fileList.remove(generator.nextInt(fileList.size()));
		return file; //Return it to the caller (FileHandler in our case).
	}
}


The comments here, again, are extremely self explanatory :)

Section 4: The Driver (MoviePicker)
import java.io.IOException;

public class MoviePicker {

	public static void main(String args[]) throws IOException {
		/*
		 * We need to make our GUI an object so that we can display it to the user 
		 */
		MoviePickerGui mpg = new MoviePickerGui();
		mpg.setVisible(true); //Make it visible to the user!
	}
}


Once again, self explanatory haha. This is the easiest class in the world huh?

So that's it, that's all your code! It wasn't too bad was it? I do want to offer one piece of advice though if you are trying to get better at programming. Yes, these tutorials do help, but you will never get any better if you always have someone holding your hand and walking you through it. Do a few tutorials then tackle a challenge on your own. I suggest doing what I did here:

1) Recognize a problem (in my case, me and my girlfriend never knowing what we want to watch haha)
2) Think about how you could write a program to solve it and rate it's difficulty (for me, this was uber easy)
3) Sit down and try something. Just start... even if you don't know where to start, pick something that you know you have to do (I like picking the GUI first) and just do it. Next thing you know, you have been programming for a hours, forgot to eat, and you have working code :)

I hope you enjoyed this tutorial. I had a lot of fun making it. It really took me back to when I started program and I thought this stuff was super hard, and now I can write it on paper haha. Keep at it, you will get it and it will become easier and easier :)

Is This A Good Question/Topic? 1
  • +

Page 1 of 1