Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

For this programming assignment you will write a recursive algorithm to display

ID: 3872215 • Letter: F

Question

For this programming assignment you will write a recursive algorithm to display the contents of a directory in a computer’s file system. You will also get a little experience using the API documentation for several components of the JDK library, including the File class. Additionally, you will get some exposure to a graphical user interface (GUI), which you may or may not have had in your previous Java work. The Explorer program that serves as the default file system browser for the Windows XP operating system allows you to see the first-level contents of a given folder. It does not allow you to see the contents of any nested subfolders—you have to click on each subfolder, one at a time, to see the contents of these folders. Suppose you wanted to see the entire contents of a given folder; i.e., not just the first-level files and subfolders, but everything that is contained in all the nested subfolders, regardless of how many nested subfolders there are. You could write an algorithm that iterates through all the subfolders using a loop, but since you have no way of knowing beforehand how many levels of nested subfolders there are, implementing an iterative algorithm to do this would be tricky. This problem is perfectly suited for a recursive algorithm. Each subfolder constitutes a problem that is similar to the initial problem (i.e., the root-level folder), only smaller. Recursion can theoretically (though not practically) handle an infinite amount of nesting. Your goal for this assignment is to implement a recursive method that will enumerate the contents of a chosen folder in a computer’s file system, and display the following information about all the files and subfolders in the chosen folder: 1. absolute path name (i.e., the path name beginning with the drive letter or network share; e.g.: “C:My DocumentsmyFile.txt”) 2. size, in kilobytes 3. type (file or folder) 4. the date and time on which the file or folder was last modified Download Files Download the DirectoryLister.zip file. It contains 3 files you will need to use for this assignment: 1. Driver.java 2. GUI.java 3. DirectoryLister.java The only file you will need to modify for this assignment will be DirectoryLister.java. You will not need to create any additional classes for this assignment. You should be able to compile the project as it is. It will allow you to select a directory, but it won’t do anything else. How the Program Should Work A screen capture of how the user interface appears when the program is first launched is shown below. This is what you should see if you compile and run the provided source files as they are, with no medications. Clicking the “Browse...” button will bring up a JFileChooser dialog where you can select a folder from the file system. Once you have selected a folder, a table will be generated showing the name, size, type, and date last modified for every file and folder in the selected folder, as well as all nested subfolders. With the files you download in the directoryLister.zip file, selecting a folder will do nothing. You must complete the implementation to process the selected folder and display all the required information. What you need to do All you need to do for this assignment is complete the following 2 methods of the DirectoryLister class. The method declarations have been provided for you. All you need to do is provide the implementations. You will need to understand how the GUI works, though in order to get your results to display properly. /** * Show the directory listing. * An error message is displayed if basePath does not represent a valid directory. * * @param basePath the absolute path of a directory in the file system. */ public void showDirectoryContents(String basePath) { // TODO } /** * Recursive method to enumerate the contents of a directory. * * @param f directory to enumerate */ private void enumerateDirectory(File f) { // TODO } The value returned by the JFileChooser dialog is a string representing the absolute path of the selected folder. This value is passed as an argument to the showDirectoryContents method. There are a few exceptional situations you should try to make sure are handled in the showDirectoryContents method: 1. If the user clicks the “Cancel” button or the “Close” button on the JFileChooser dialog, without choosing a folder. In this case “null” is passed as an argument to the showDirectoryContents method. 2. If the user enters an invalid folder path directly into the textbox on the JFileChooser dialog, or modifies a path selected by clicking on a folder in the dialog’s file/folder view. In this case you should use the method exists in the File class to check whether the selected folder is valid (see below for the relevant classes in Java API). You may find that setting up a try-catch block to handle these situations is helpful. In any event, the program should not exit or crash when one of these situations occurs, but it should behave appropriately; for instance, you may use JOptionPane dialog to inform the user what has occurred. If the chosen directory is valid, then the enumerateDirectory method should be called, which should recursively enumerate the contents of the chosen folder. To get full credit for this part of the assignment, your enumerateDirectory method must be recursive, and it should update the display with all the required information. You can use the updateListing method of the GUI class for displaying the required information of a file. Open the GUI class and find updateListing method you can see the method parameters and their documentation. If you look at the parameters of the updateListing you may notice that the last parameter “dateLastModified” is of type string. According to “File” API documentation (http://docs.oracle.com/javase/7/docs/api/java/io/File.html) the method lastModified returns a long integer. To convert this long integer to a string, use the utility method formattedDateString in the DirectoryLister class. Relevant Classes in the Java API • File (http://docs.oracle.com/javase/7/docs/api/java/io/File.html ) • JOptionPane The File class is an abstract representation of either a file or a folder in the file system. To create a File object, you will probably want to use the constructor, File (String pathname), since this is the type of information returned when the initial folder is chosen from the JFileChooser dialog. The File class provides many useful methods, including ones to retrieve all the information you need to display for each file or folder. You will probably need to use the following methods from the File class: I will leave it to you to read through the API docs to figure out what each method does: exists isDirectory getAbsolutePath length lastModified listFiles The JOptionPane class is used to display a simple modal dialog box containing a message. It can also display things like warning icons to indicate the seriousness of the message. You don’t need to create an instance of the JOptionPane class in order to use it. You can use one of the many static methods the JOp- tionPane class provides. For example, the following statement will display an error message that reads, “The specified filename is invalid!”: JOptionPane.showMessageDialog(null, “The specified filename is invalid! “, “Error”, JOptionPane.ERROR_MESSAGE); The first argument here refers to the parent component of the JOptionPane. Since we’re calling one of the static methods, we don’t need to specify a parent component, so we pass a null value. The second argument is the error text that will be displayed in the main part of the message dialog. The third argument specifies the text that should appear in the title bar of the dialog. Finally, the fourth argument specifies which type of icon should be displayed along with the error message (warning, information, or error). Hints 1. Don’t make this project harder than it really is! I’ve given you 2 weeks to finish it, but you don’t really have to do that much work—you only need to implement the two methods I’ve indicated. 2. You should not need to create any additional methods or classes. The user interface is built for you, so you do not have to create any additional UI components. You will need to understand how the user interface works, though, so you can make your implementation communicate with it. 3. Your showDirectoryContents method needs to call your enumerateDirectory method, which requires a File object as a parameter, so at some point you will need to create a File object in your showDirectoryContents method. 4. Your enumerateDirectory method must be recursive, so you will need to determine what the base case(s) are, and what the recursive case(s) are. If you think about how a computer’s file system is structured, you should be able to figure this out pretty quickly. 6. Use updateListing method of the GUI class to display file information. 5. Test your program before you submit it! Make sure your test cases cover all the possible scenarios: a. a non-existent folder (you can do this by typing an invalid path in the text box of the interface, instead of choosing an existing directory) b. an empty folder c. a folder containing only one file d. a folder containing only one subfolder e. a folder containing multiple files (but no subfolders) f. a folder containing multiple, non-nested subfolders (but no files) g. a folder containing both files and subfolders (all folders are non-nested) h. a folder containing multiple, nested subfolders (but no files) i. a folder containing an arbitrary mix of files and subfolders (some nested, some nonnested) 6. Don’t worry about exhaustively testing your program on a folder containing a huge number of files and subfolders. While recursion is elegant, it can quickly eat up all the stack space in your computer’s memory, and if this happens the program will crash. Test your program on folders with moderate numbers of files and subfolders, and assume that if your program works on those folders, it will work for all folders. For this programming assignment you will write a recursive algorithm to display the contents of a directory in a computer’s file system. You will also get a little experience using the API documentation for several components of the JDK library, including the File class. Additionally, you will get some exposure to a graphical user interface (GUI), which you may or may not have had in your previous Java work. The Explorer program that serves as the default file system browser for the Windows XP operating system allows you to see the first-level contents of a given folder. It does not allow you to see the contents of any nested subfolders—you have to click on each subfolder, one at a time, to see the contents of these folders. Suppose you wanted to see the entire contents of a given folder; i.e., not just the first-level files and subfolders, but everything that is contained in all the nested subfolders, regardless of how many nested subfolders there are. You could write an algorithm that iterates through all the subfolders using a loop, but since you have no way of knowing beforehand how many levels of nested subfolders there are, implementing an iterative algorithm to do this would be tricky. This problem is perfectly suited for a recursive algorithm. Each subfolder constitutes a problem that is similar to the initial problem (i.e., the root-level folder), only smaller. Recursion can theoretically (though not practically) handle an infinite amount of nesting. Your goal for this assignment is to implement a recursive method that will enumerate the contents of a chosen folder in a computer’s file system, and display the following information about all the files and subfolders in the chosen folder: 1. absolute path name (i.e., the path name beginning with the drive letter or network share; e.g.: “C:My DocumentsmyFile.txt”) 2. size, in kilobytes 3. type (file or folder) 4. the date and time on which the file or folder was last modified Download Files Download the DirectoryLister.zip file. It contains 3 files you will need to use for this assignment: 1. Driver.java 2. GUI.java 3. DirectoryLister.java The only file you will need to modify for this assignment will be DirectoryLister.java. You will not need to create any additional classes for this assignment. You should be able to compile the project as it is. It will allow you to select a directory, but it won’t do anything else. How the Program Should Work A screen capture of how the user interface appears when the program is first launched is shown below. This is what you should see if you compile and run the provided source files as they are, with no medications. Clicking the “Browse...” button will bring up a JFileChooser dialog where you can select a folder from the file system. Once you have selected a folder, a table will be generated showing the name, size, type, and date last modified for every file and folder in the selected folder, as well as all nested subfolders. With the files you download in the directoryLister.zip file, selecting a folder will do nothing. You must complete the implementation to process the selected folder and display all the required information. What you need to do All you need to do for this assignment is complete the following 2 methods of the DirectoryLister class. The method declarations have been provided for you. All you need to do is provide the implementations. You will need to understand how the GUI works, though in order to get your results to display properly. /** * Show the directory listing. * An error message is displayed if basePath does not represent a valid directory. * * @param basePath the absolute path of a directory in the file system. */ public void showDirectoryContents(String basePath) { // TODO } /** * Recursive method to enumerate the contents of a directory. * * @param f directory to enumerate */ private void enumerateDirectory(File f) { // TODO } The value returned by the JFileChooser dialog is a string representing the absolute path of the selected folder. This value is passed as an argument to the showDirectoryContents method. There are a few exceptional situations you should try to make sure are handled in the showDirectoryContents method: 1. If the user clicks the “Cancel” button or the “Close” button on the JFileChooser dialog, without choosing a folder. In this case “null” is passed as an argument to the showDirectoryContents method. 2. If the user enters an invalid folder path directly into the textbox on the JFileChooser dialog, or modifies a path selected by clicking on a folder in the dialog’s file/folder view. In this case you should use the method exists in the File class to check whether the selected folder is valid (see below for the relevant classes in Java API). You may find that setting up a try-catch block to handle these situations is helpful. In any event, the program should not exit or crash when one of these situations occurs, but it should behave appropriately; for instance, you may use JOptionPane dialog to inform the user what has occurred. If the chosen directory is valid, then the enumerateDirectory method should be called, which should recursively enumerate the contents of the chosen folder. To get full credit for this part of the assignment, your enumerateDirectory method must be recursive, and it should update the display with all the required information. You can use the updateListing method of the GUI class for displaying the required information of a file. Open the GUI class and find updateListing method you can see the method parameters and their documentation. If you look at the parameters of the updateListing you may notice that the last parameter “dateLastModified” is of type string. According to “File” API documentation (http://docs.oracle.com/javase/7/docs/api/java/io/File.html) the method lastModified returns a long integer. To convert this long integer to a string, use the utility method formattedDateString in the DirectoryLister class. Relevant Classes in the Java API • File (http://docs.oracle.com/javase/7/docs/api/java/io/File.html ) • JOptionPane The File class is an abstract representation of either a file or a folder in the file system. To create a File object, you will probably want to use the constructor, File (String pathname), since this is the type of information returned when the initial folder is chosen from the JFileChooser dialog. The File class provides many useful methods, including ones to retrieve all the information you need to display for each file or folder. You will probably need to use the following methods from the File class: I will leave it to you to read through the API docs to figure out what each method does: exists isDirectory getAbsolutePath length lastModified listFiles The JOptionPane class is used to display a simple modal dialog box containing a message. It can also display things like warning icons to indicate the seriousness of the message. You don’t need to create an instance of the JOptionPane class in order to use it. You can use one of the many static methods the JOp- tionPane class provides. For example, the following statement will display an error message that reads, “The specified filename is invalid!”: JOptionPane.showMessageDialog(null, “The specified filename is invalid! “, “Error”, JOptionPane.ERROR_MESSAGE); The first argument here refers to the parent component of the JOptionPane. Since we’re calling one of the static methods, we don’t need to specify a parent component, so we pass a null value. The second argument is the error text that will be displayed in the main part of the message dialog. The third argument specifies the text that should appear in the title bar of the dialog. Finally, the fourth argument specifies which type of icon should be displayed along with the error message (warning, information, or error). Hints 1. Don’t make this project harder than it really is! I’ve given you 2 weeks to finish it, but you don’t really have to do that much work—you only need to implement the two methods I’ve indicated. 2. You should not need to create any additional methods or classes. The user interface is built for you, so you do not have to create any additional UI components. You will need to understand how the user interface works, though, so you can make your implementation communicate with it. 3. Your showDirectoryContents method needs to call your enumerateDirectory method, which requires a File object as a parameter, so at some point you will need to create a File object in your showDirectoryContents method. 4. Your enumerateDirectory method must be recursive, so you will need to determine what the base case(s) are, and what the recursive case(s) are. If you think about how a computer’s file system is structured, you should be able to figure this out pretty quickly. 6. Use updateListing method of the GUI class to display file information. 5. Test your program before you submit it! Make sure your test cases cover all the possible scenarios: a. a non-existent folder (you can do this by typing an invalid path in the text box of the interface, instead of choosing an existing directory) b. an empty folder c. a folder containing only one file d. a folder containing only one subfolder e. a folder containing multiple files (but no subfolders) f. a folder containing multiple, non-nested subfolders (but no files) g. a folder containing both files and subfolders (all folders are non-nested) h. a folder containing multiple, nested subfolders (but no files) i. a folder containing an arbitrary mix of files and subfolders (some nested, some nonnested) 6. Don’t worry about exhaustively testing your program on a folder containing a huge number of files and subfolders. While recursion is elegant, it can quickly eat up all the stack space in your computer’s memory, and if this happens the program will crash. Test your program on folders with moderate numbers of files and subfolders, and assume that if your program works on those folders, it will work for all folders.

Directry lister.java

package testPackage2;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
* DirectoryLister class. This class allows the user to recursively display the
* contents of a selected directory in the file system.
*/
public class DirectoryLister {

// -----------------------------------------------------------------------
// Attributes
// -----------------------------------------------------------------------

/** GUI used to display results */
private GUI gui;

/** base path of directory to be traversed */
private String basePath;

// -----------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------

/**
* Create a new DirectoryLister that uses the specified GUI.
*/
public DirectoryLister(GUI gui) {
this.gui = gui;
}

// -----------------------------------------------------------------------
// Methods
// -----------------------------------------------------------------------

/**
* Allow user to select a directory for traversal.
*/
public void selectDirectory() {
// clear results of any previous traversal
gui.resetGUI();

// allow user to select a directory from the file system
basePath = gui.getAbsoluteDirectoryPath();

// update the address label on the GUI
gui.setAddressLabelText(basePath);

// traverse the selected directory, and display the contents
showDirectoryContents(basePath);
}

/**
* Show the directory listing. An error message is displayed if basePath does
* not represent a valid directory.
*
* @param basePath
* the absolute path of a directory in the file system.
*/
public void showDirectoryContents(String basePath) {
// TODO
}

/**
* Recursive method to enumerate the contents of a directory.
*
* @param f
* directory to enumerate
*/
private void enumerateDirectory(File f) {
// TODO
}

/**
* Convert a size from bytes to kilobytes, rounded down, and return an
* appropriate descriptive string. Example: 123456 bytes returns 120 KB
*
* @param size
* size, in bytes
* @return size, in kilobytes (rounded down) + "KB"
*/
private String getSizeString(long size) {
long kbSize = size / 1024;

return "" + kbSize + " KB";
}

/**
* Return a numeric time value as a formatted date string.
*
* @param time
* numeric time value in milliseconds
* @return formatted string using the format "MM/dd/yyyy hh:mm:ss aaa" Example:
* 01/15/2010 12:37:52 PM
*/
private String formattedDateString(long time) {
// create Date object from numeric time
Date d = new Date(time);

// create formatter
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss aaa");

// return formatted date string
return sdf.format(d);
}
}

Driver.java

package testPackage2;

/**
* Driver class for DirectoryLister assignment. This class simply instantiates
* the classes needed to run the program, and executes the program.
*/
public class Driver {

public static void main(String[] args) {
GUI gui = new GUI();
DirectoryLister dl = new DirectoryLister(gui);
gui.registerModel(dl);
}

}

GUI.java

package testPackage2;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

/**
* GUI for Module 3 DirectoryLister assignment
*
* Simple interface that allows user to select a directory using a file chooser
* dialog, and display all the files and folders in the selected directory
*/
public class GUI extends JFrame {

// -----------------------------------------------------------------------
// Attributes
// -----------------------------------------------------------------------

/** Event handler for button click events. */
private ButtonHandler buttonHandler;

/** Container for displaying Browse button and address of selected directory */
private JPanel addressPanel;

/** Text container for displaying address of selected directory */
private JLabel addressLabel;

/** Button for bringing up file chooser dialog */
private JButton browseButton;

/**
* Underlying model for the JTable that displays contents of selected directory
*/
private DefaultTableModel tableModel;

/** Table that displays contents of selected directory */
private JTable directoryContentsTable;

/** Allows filesTable to be scrollable */
private JScrollPane tablePane;

/** Object containing non-GUI logic for program */
private DirectoryLister model;

// -----------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------

/**
* Create a new GUI.
*/
public GUI() {
// use small default size for low-res screens
setSize(800, 600);

// set value for title bar of window
setTitle("Directory Lister");

// allows the program to exit when the window is closed
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
});

// create window components
initGUI();

// make sure everything is visible
validate();
repaint();
setVisible(true);
}

// -----------------------------------------------------------------------
// Methods
// -----------------------------------------------------------------------

/**
* Create all the components to be displayed in the main window.
*/
private void initGUI() {
// use standard BorderLayout for the window itself
setLayout(new BorderLayout());

// event handler for button clicks
buttonHandler = new ButtonHandler();

// create text label for displaying selected directory
addressLabel = new JLabel();

// create Browse button
browseButton = new JButton("Browse...");
browseButton.addActionListener(buttonHandler);

// create panel for showing Browse button and value for selected directory
addressPanel = new JPanel();

// ensure components are laid out from left to right
addressPanel.setLayout(new FlowLayout(FlowLayout.LEFT));

// add components to addressPanel
addressPanel.add(browseButton);
addressPanel.add(addressLabel);

// create the table for displaying the directory contents
createDirectoryContentsTable();

// make sure table is scrollable
tablePane = new JScrollPane(directoryContentsTable);

// add components to main window
add(addressPanel, BorderLayout.NORTH);
add(tablePane, BorderLayout.CENTER);
}

/**
* Create the table for displaying the contents of the selected directory.
*/
private void createDirectoryContentsTable() {
// create underlying model for table that displays contents of selected
// directory
tableModel = new DefaultTableModel();

// table model has 4 columns, to display: file/folder name, size (files only),
// type (file or folder), and date last modified
tableModel.addColumn("Name");
tableModel.addColumn("Size");
tableModel.addColumn("Type");
tableModel.addColumn("Date Modified");

// create GUI table component
directoryContentsTable = new JTable(tableModel);

// disallow reordering of table columns
directoryContentsTable.getTableHeader().setReorderingAllowed(false);

// create a TableCellRenderer for displaying left justified text
DefaultTableCellRenderer leftJustifiedRenderer = new DefaultTableCellRenderer();
leftJustifiedRenderer.setHorizontalAlignment(SwingConstants.LEFT);

// create a TableCellRenderer for displaying right justified text
DefaultTableCellRenderer rightJustifiedRenderer = new DefaultTableCellRenderer();
rightJustifiedRenderer.setHorizontalAlignment(SwingConstants.RIGHT);

// set cell renderers for data cells
directoryContentsTable.getColumn("Name").setCellRenderer(leftJustifiedRenderer);
directoryContentsTable.getColumn("Size").setCellRenderer(rightJustifiedRenderer);
directoryContentsTable.getColumn("Type").setCellRenderer(leftJustifiedRenderer);
directoryContentsTable.getColumn("Date Modified").setCellRenderer(leftJustifiedRenderer);

// create and format headers for column that displays file/folder names
JLabel nameLabel = new JLabel(" Name", SwingConstants.LEFT);
nameLabel.setBorder(UIManager.getBorder("TableHeader.cellBorder"));

directoryContentsTable.getColumn("Name").setHeaderRenderer(new CustomTableCellRenderer());
directoryContentsTable.getColumn("Name").setHeaderValue(nameLabel);

// create and format header for column that displays file/folder sizes
JLabel sizeLabel = new JLabel("Size ", SwingConstants.RIGHT);
sizeLabel.setBorder(UIManager.getBorder("TableHeader.cellBorder"));

directoryContentsTable.getColumn("Size").setHeaderRenderer(new CustomTableCellRenderer());
directoryContentsTable.getColumn("Size").setHeaderValue(sizeLabel);

// create and format header for column that displays file/folder types
JLabel typeLabel = new JLabel(" Type", SwingConstants.LEFT);
typeLabel.setBorder(UIManager.getBorder("TableHeader.cellBorder"));

directoryContentsTable.getColumn("Type").setHeaderRenderer(new CustomTableCellRenderer());
directoryContentsTable.getColumn("Type").setHeaderValue(typeLabel);

// create and format header for column that displays dates last modified for
// files/folders
JLabel dateModifiedLabel = new JLabel(" Date Modified", SwingConstants.LEFT);
dateModifiedLabel.setBorder(UIManager.getBorder("TableHeader.cellBorder"));

directoryContentsTable.getColumn("Date Modified").setHeaderRenderer(new CustomTableCellRenderer());
directoryContentsTable.getColumn("Date Modified").setHeaderValue(dateModifiedLabel);
}

/**
* Register the specified model with this GUI.
*/
public void registerModel(DirectoryLister model) {
this.model = model;
}

/**
* Return the absolute path of a directory selected by the user via a
* JFileChooser.
*/
public String getAbsoluteDirectoryPath() {
// display file chooser dialog
JFileChooser jfc = new JFileChooser();

// only display directories (folders)
jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

// show the dialog
jfc.showOpenDialog(this);

// return the selected directory, if one is chosen; otherwise, return null
if (jfc.getSelectedFile() != null) {
return jfc.getSelectedFile().getAbsolutePath();
} else {
return null;
}
}

/**
* Set the text of the address label.
*/
public void setAddressLabelText(String text) {
addressLabel.setText(text);
}

/**
* Update the table with the specified file/folder information. The information
* for each file/folder occupies a single row in the table.
*
* Information is displayed in the following order:
*
* Column 1: absolute path of file or folder Column 2: size of file in
* kilobytes, or "" for folders Column 3: type - "File" or "Folder" Column 4:
* date last modified in format: month/day/year hour:minute:second AM/PM
*/
public void updateListing(String absolutePath, String size, String type, String dateLastModified) {
// add information in new row in table
tableModel.addRow(new String[] { " " + absolutePath, size + " ", " " + type, " " + dateLastModified });
}

/**
* Clear the contents of the previous directory traversal, and clear the address
* showing the current directory.
*/
public void resetGUI() {
// clear address
addressLabel.setText("");

// remove all rows from table
while (tableModel.getRowCount() > 0) {
tableModel.removeRow(0);
}
}

// -----------------------------------------------------------------------
// Inner Classes
// -----------------------------------------------------------------------

/**
* Inner class for allowing customization of the appearance of a table cell.
* This class is used in this class to allow left or right justification of text
* in a table header cell, without losing the borders of those cells.
*/
class CustomTableCellRenderer implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
return (JComponent) value;
}
}

/**
* Inner class to handle button events.
*/
class ButtonHandler implements ActionListener {

// -----------------------------------------------------------------------
// Methods
// -----------------------------------------------------------------------

/**
* Respond to a button click event.
*/
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();

if (b.getText().equals("Browse...")) {
// prompt user to select directory
model.selectDirectory();
}
}
}

}

Explanation / Answer

Directry lister.java

package testPackage2;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
* DirectoryLister class. This class allows the user to recursively display the
* contents of a selected directory in the file system.
*/
public class DirectoryLister {

// -----------------------------------------------------------------------
// Attributes
// -----------------------------------------------------------------------

/** GUI used to display results */
private GUI gui;

/** base path of directory to be traversed */
private String basePath;

// -----------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------

/**
* Create a new DirectoryLister that uses the specified GUI.
*/
public DirectoryLister(GUI gui) {
this.gui = gui;
}

// -----------------------------------------------------------------------
// Methods
// -----------------------------------------------------------------------

/**
* Allow user to select a directory for traversal.
*/
public void selectDirectory() {
// clear results of any previous traversal
gui.resetGUI();

// allow user to select a directory from the file system
basePath = gui.getAbsoluteDirectoryPath();

// update the address label on the GUI
gui.setAddressLabelText(basePath);

// traverse the selected directory, and display the contents
showDirectoryContents(basePath);
}

/**
* Show the directory listing. An error message is displayed if basePath does
* not represent a valid directory.
*
* @param basePath
* the absolute path of a directory in the file system.
*/
public void showDirectoryContents(String basePath) {
// TODO
}

/**
* Recursive method to enumerate the contents of a directory.
*
* @param f
* directory to enumerate
*/
private void enumerateDirectory(File f) {
// TODO
}

/**
* Convert a size from bytes to kilobytes, rounded down, and return an
* appropriate descriptive string. Example: 123456 bytes returns 120 KB
*
* @param size
* size, in bytes
* @return size, in kilobytes (rounded down) + "KB"
*/
private String getSizeString(long size) {
long kbSize = size / 1024;

return "" + kbSize + " KB";
}

/**
* Return a numeric time value as a formatted date string.
*
* @param time
* numeric time value in milliseconds
* @return formatted string using the format "MM/dd/yyyy hh:mm:ss aaa" Example:
* 01/15/2010 12:37:52 PM
*/
private String formattedDateString(long time) {
// create Date object from numeric time
Date d = new Date(time);

// create formatter
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss aaa");

// return formatted date string
return sdf.format(d);
}
}

Driver.java

package testPackage2;

/**
* Driver class for DirectoryLister assignment. This class simply instantiates
* the classes needed to run the program, and executes the program.
*/
public class Driver {

public static void main(String[] args) {
GUI gui = new GUI();
DirectoryLister dl = new DirectoryLister(gui);
gui.registerModel(dl);
}

}

GUI.java

package testPackage2;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

/**
* GUI for Module 3 DirectoryLister assignment
*
* Simple interface that allows user to select a directory using a file chooser
* dialog, and display all the files and folders in the selected directory
*/
public class GUI extends JFrame {

// -----------------------------------------------------------------------
// Attributes
// -----------------------------------------------------------------------

/** Event handler for button click events. */
private ButtonHandler buttonHandler;

/** Container for displaying Browse button and address of selected directory */
private JPanel addressPanel;

/** Text container for displaying address of selected directory */
private JLabel addressLabel;

/** Button for bringing up file chooser dialog */
private JButton browseButton;

/**
* Underlying model for the JTable that displays contents of selected directory
*/
private DefaultTableModel tableModel;

/** Table that displays contents of selected directory */
private JTable directoryContentsTable;

/** Allows filesTable to be scrollable */
private JScrollPane tablePane;

/** Object containing non-GUI logic for program */
private DirectoryLister model;

// -----------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------

/**
* Create a new GUI.
*/
public GUI() {
// use small default size for low-res screens
setSize(800, 600);

// set value for title bar of window
setTitle("Directory Lister");

// allows the program to exit when the window is closed
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
System.exit(0);
}
});

// create window components
initGUI();

// make sure everything is visible
validate();
repaint();
setVisible(true);
}

// -----------------------------------------------------------------------
// Methods
// -----------------------------------------------------------------------

/**
* Create all the components to be displayed in the main window.
*/
private void initGUI() {
// use standard BorderLayout for the window itself
setLayout(new BorderLayout());

// event handler for button clicks
buttonHandler = new ButtonHandler();

// create text label for displaying selected directory
addressLabel = new JLabel();

// create Browse button
browseButton = new JButton("Browse...");
browseButton.addActionListener(buttonHandler);

// create panel for showing Browse button and value for selected directory
addressPanel = new JPanel();

// ensure components are laid out from left to right
addressPanel.setLayout(new FlowLayout(FlowLayout.LEFT));

// add components to addressPanel
addressPanel.add(browseButton);
addressPanel.add(addressLabel);

// create the table for displaying the directory contents
createDirectoryContentsTable();

// make sure table is scrollable
tablePane = new JScrollPane(directoryContentsTable);

// add components to main window
add(addressPanel, BorderLayout.NORTH);
add(tablePane, BorderLayout.CENTER);
}

/**
* Create the table for displaying the contents of the selected directory.
*/
private void createDirectoryContentsTable() {
// create underlying model for table that displays contents of selected
// directory
tableModel = new DefaultTableModel();

// table model has 4 columns, to display: file/folder name, size (files only),
// type (file or folder), and date last modified
tableModel.addColumn("Name");
tableModel.addColumn("Size");
tableModel.addColumn("Type");
tableModel.addColumn("Date Modified");

// create GUI table component
directoryContentsTable = new JTable(tableModel);

// disallow reordering of table columns
directoryContentsTable.getTableHeader().setReorderingAllowed(false);

// create a TableCellRenderer for displaying left justified text
DefaultTableCellRenderer leftJustifiedRenderer = new DefaultTableCellRenderer();
leftJustifiedRenderer.setHorizontalAlignment(SwingConstants.LEFT);

// create a TableCellRenderer for displaying right justified text
DefaultTableCellRenderer rightJustifiedRenderer = new DefaultTableCellRenderer();
rightJustifiedRenderer.setHorizontalAlignment(SwingConstants.RIGHT);

// set cell renderers for data cells
directoryContentsTable.getColumn("Name").setCellRenderer(leftJustifiedRenderer);
directoryContentsTable.getColumn("Size").setCellRenderer(rightJustifiedRenderer);
directoryContentsTable.getColumn("Type").setCellRenderer(leftJustifiedRenderer);
directoryContentsTable.getColumn("Date Modified").setCellRenderer(leftJustifiedRenderer);

// create and format headers for column that displays file/folder names
JLabel nameLabel = new JLabel(" Name", SwingConstants.LEFT);
nameLabel.setBorder(UIManager.getBorder("TableHeader.cellBorder"));

directoryContentsTable.getColumn("Name").setHeaderRenderer(new CustomTableCellRenderer());
directoryContentsTable.getColumn("Name").setHeaderValue(nameLabel);

// create and format header for column that displays file/folder sizes
JLabel sizeLabel = new JLabel("Size ", SwingConstants.RIGHT);
sizeLabel.setBorder(UIManager.getBorder("TableHeader.cellBorder"));

directoryContentsTable.getColumn("Size").setHeaderRenderer(new CustomTableCellRenderer());
directoryContentsTable.getColumn("Size").setHeaderValue(sizeLabel);

// create and format header for column that displays file/folder types
JLabel typeLabel = new JLabel(" Type", SwingConstants.LEFT);
typeLabel.setBorder(UIManager.getBorder("TableHeader.cellBorder"));

directoryContentsTable.getColumn("Type").setHeaderRenderer(new CustomTableCellRenderer());
directoryContentsTable.getColumn("Type").setHeaderValue(typeLabel);

// create and format header for column that displays dates last modified for
// files/folders
JLabel dateModifiedLabel = new JLabel(" Date Modified", SwingConstants.LEFT);
dateModifiedLabel.setBorder(UIManager.getBorder("TableHeader.cellBorder"));

directoryContentsTable.getColumn("Date Modified").setHeaderRenderer(new CustomTableCellRenderer());
directoryContentsTable.getColumn("Date Modified").setHeaderValue(dateModifiedLabel);
}

/**
* Register the specified model with this GUI.
*/
public void registerModel(DirectoryLister model) {
this.model = model;
}

/**
* Return the absolute path of a directory selected by the user via a
* JFileChooser.
*/
public String getAbsoluteDirectoryPath() {
// display file chooser dialog
JFileChooser jfc = new JFileChooser();

// only display directories (folders)
jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

// show the dialog
jfc.showOpenDialog(this);

// return the selected directory, if one is chosen; otherwise, return null
if (jfc.getSelectedFile() != null) {
return jfc.getSelectedFile().getAbsolutePath();
} else {
return null;
}
}

/**
* Set the text of the address label.
*/
public void setAddressLabelText(String text) {
addressLabel.setText(text);
}

/**
* Update the table with the specified file/folder information. The information
* for each file/folder occupies a single row in the table.
*
* Information is displayed in the following order:
*
* Column 1: absolute path of file or folder Column 2: size of file in
* kilobytes, or "" for folders Column 3: type - "File" or "Folder" Column 4:
* date last modified in format: month/day/year hour:minute:second AM/PM
*/
public void updateListing(String absolutePath, String size, String type, String dateLastModified) {
// add information in new row in table
tableModel.addRow(new String[] { " " + absolutePath, size + " ", " " + type, " " + dateLastModified });
}

/**
* Clear the contents of the previous directory traversal, and clear the address
* showing the current directory.
*/
public void resetGUI() {
// clear address
addressLabel.setText("");

// remove all rows from table
while (tableModel.getRowCount() > 0) {
tableModel.removeRow(0);
}
}

// -----------------------------------------------------------------------
// Inner Classes
// -----------------------------------------------------------------------

/**
* Inner class for allowing customization of the appearance of a table cell.
* This class is used in this class to allow left or right justification of text
* in a table header cell, without losing the borders of those cells.
*/
class CustomTableCellRenderer implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
return (JComponent) value;
}
}

/**
* Inner class to handle button events.
*/
class ButtonHandler implements ActionListener {

// -----------------------------------------------------------------------
// Methods
// -----------------------------------------------------------------------

/**
* Respond to a button click event.
*/
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();

if (b.getText().equals("Browse...")) {
// prompt user to select directory
model.selectDirectory();
}
}
}

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote