Java tutorial
/* * Copyright (c) 2004 David Flanagan. All rights reserved. * This code is from the book Java Examples in a Nutshell, 3nd Edition. * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied. * You may study, use, and modify it for any non-commercial purpose, * including teaching and use in open-source projects. * You may distribute it non-commercially as long as you retain this notice. * For a commercial use license, or to purchase the book, * please visit http://www.davidflanagan.com/javaexamples3. */ import java.awt.Button; import java.awt.FileDialog; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Frame; import java.awt.List; import java.awt.Panel; import java.awt.TextArea; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.FileReader; import java.io.FilenameFilter; import java.io.IOException; import java.text.DateFormat; /** * This class creates and displays a window containing a list of files and * sub-directories in a specified directory. Clicking on an entry in the list * displays more information about it. Double-clicking on an entry displays it, * if a file, or lists it if a directory. An optionally-specified FilenameFilter * filters the displayed list. */ public class FileLister extends Frame implements ActionListener, ItemListener { private List list; // To display the directory contents in private TextField details; // To display detail info in. private Panel buttons; // Holds the buttons private Button up, close; // The Up and Close buttons private File currentDir; // The directory currently listed private FilenameFilter filter; // An optional filter for the directory private String[] files; // The directory contents private DateFormat dateFormatter = // To display dates and time correctly DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); /** * Constructor: create the GUI, and list the initial directory. */ public FileLister(String directory, FilenameFilter filter) { super("File Lister"); // Create the window this.filter = filter; // Save the filter, if any // Destroy the window when the user requests it addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); } }); list = new List(12, false); // Set up the list list.setFont(new Font("MonoSpaced", Font.PLAIN, 14)); list.addActionListener(this); list.addItemListener(this); details = new TextField(); // Set up the details area details.setFont(new Font("MonoSpaced", Font.PLAIN, 12)); details.setEditable(false); buttons = new Panel(); // Set up the button box buttons.setLayout(new FlowLayout(FlowLayout.RIGHT, 15, 5)); buttons.setFont(new Font("SansSerif", Font.BOLD, 14)); up = new Button("Up a Directory"); // Set up the two buttons close = new Button("Close"); up.addActionListener(this); close.addActionListener(this); buttons.add(up); // Add buttons to button box buttons.add(close); this.add(list, "Center"); // Add stuff to the window this.add(details, "North"); this.add(buttons, "South"); this.setSize(500, 350); listDirectory(directory); // And now list initial directory. } /** * This method uses the list() method to get all entries in a directory and * then displays them in the List component. */ public void listDirectory(String directory) { // Convert the string to a File object, and check that the dir exists File dir = new File(directory); if (!dir.isDirectory()) throw new IllegalArgumentException("FileLister: no such directory"); // Get the (filtered) directory entries files = dir.list(filter); // Sort the list of filenames. java.util.Arrays.sort(files); // Remove any old entries in the list, and add the new ones list.removeAll(); list.add("[Up to Parent Directory]"); // A special case entry for (int i = 0; i < files.length; i++) list.add(files[i]); // Display directory name in window titlebar and in the details box this.setTitle(directory); details.setText(directory); // Remember this directory for later. currentDir = dir; } /** * This ItemListener method uses various File methods to obtain information * about a file or directory. Then it displays that info. */ public void itemStateChanged(ItemEvent e) { int i = list.getSelectedIndex() - 1; // minus 1 for Up To Parent entry if (i < 0) return; String filename = files[i]; // Get the selected entry File f = new File(currentDir, filename); // Convert to a File if (!f.exists()) // Confirm that it exists throw new IllegalArgumentException("FileLister: " + "no such file or directory"); // Get the details about the file or directory, concatenate to a string String info = filename; if (f.isDirectory()) info += File.separator; info += " " + f.length() + " bytes "; info += dateFormatter.format(new java.util.Date(f.lastModified())); if (f.canRead()) info += " Read"; if (f.canWrite()) info += " Write"; // And display the details string details.setText(info); } /** * This ActionListener method is invoked when the user double-clicks on an * entry or clicks on one of the buttons. If they double-click on a file, * create a FileViewer to display that file. If they double-click on a * directory, call the listDirectory() method to display that directory */ public void actionPerformed(ActionEvent e) { if (e.getSource() == close) this.dispose(); else if (e.getSource() == up) { up(); } else if (e.getSource() == list) { // Double click on an item int i = list.getSelectedIndex(); // Check which item if (i == 0) up(); // Handle first Up To Parent item else { // Otherwise, get filename String name = files[i - 1]; File f = new File(currentDir, name); // Convert to a File String fullname = f.getAbsolutePath(); if (f.isDirectory()) listDirectory(fullname); // List dir else new FileViewer(fullname).show(); // display file } } } /** A convenience method to display the contents of the parent directory */ protected void up() { String parent = currentDir.getParent(); if (parent == null) return; listDirectory(parent); } /** A convenience method used by main() */ public static void usage() { System.out.println("Usage: java FileLister [directory_name] " + "[-e file_extension]"); System.exit(0); } /** * A main() method so FileLister can be run standalone. Parse command line * arguments and create the FileLister object. If an extension is specified, * create a FilenameFilter for it. If no directory is specified, use the * current directory. */ public static void main(String args[]) throws IOException { FileLister f; FilenameFilter filter = null; // The filter, if any String directory = null; // The specified dir, or the current dir // Loop through args array, parsing arguments for (int i = 0; i < args.length; i++) { if (args[i].equals("-e")) { if (++i >= args.length) usage(); final String suffix = args[i]; // final for anon. class below // This class is a simple FilenameFilter. It defines the // accept() method required to determine whether a specified // file should be listed. A file will be listed if its name // ends with the specified extension, or if it is a directory. filter = new FilenameFilter() { public boolean accept(File dir, String name) { if (name.endsWith(suffix)) return true; else return (new File(dir, name)).isDirectory(); } }; } else { if (directory != null) usage(); // If already specified, fail. else directory = args[i]; } } // if no directory specified, use the current directory if (directory == null) directory = System.getProperty("user.dir"); // Create the FileLister object, with directory and filter specified. f = new FileLister(directory, filter); // Arrange for the application to exit when the window is closed f.addWindowListener(new WindowAdapter() { public void windowClosed(WindowEvent e) { System.exit(0); } }); // Finally, pop the window up up. f.show(); } } class FileViewer extends Frame implements ActionListener { String directory; // The default directory to display in the FileDialog TextArea textarea; // The area to display the file contents into /** Convenience constructor: file viewer starts out blank */ public FileViewer() { this(null, null); } /** Convenience constructor: display file from current directory */ public FileViewer(String filename) { this(null, filename); } /** * The real constructor. Create a FileViewer object to display the specified * file from the specified directory */ public FileViewer(String directory, String filename) { super(); // Create the frame // Destroy the window when the user requests it addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); } }); // Create a TextArea to display the contents of the file in textarea = new TextArea("", 24, 80); textarea.setFont(new Font("MonoSpaced", Font.PLAIN, 12)); textarea.setEditable(false); this.add("Center", textarea); // Create a bottom panel to hold a couple of buttons in Panel p = new Panel(); p.setLayout(new FlowLayout(FlowLayout.RIGHT, 10, 5)); this.add(p, "South"); // Create the buttons and arrange to handle button clicks Font font = new Font("SansSerif", Font.BOLD, 14); Button openfile = new Button("Open File"); Button close = new Button("Close"); openfile.addActionListener(this); openfile.setActionCommand("open"); openfile.setFont(font); close.addActionListener(this); close.setActionCommand("close"); close.setFont(font); p.add(openfile); p.add(close); this.pack(); // Figure out the directory, from filename or current dir, if necessary if (directory == null) { File f; if ((filename != null) && (f = new File(filename)).isAbsolute()) { directory = f.getParent(); filename = f.getName(); } else directory = System.getProperty("user.dir"); } this.directory = directory; // Remember the directory, for FileDialog setFile(directory, filename); // Now load and display the file } /** * Load and display the specified file from the specified directory */ public void setFile(String directory, String filename) { if ((filename == null) || (filename.length() == 0)) return; File f; FileReader in = null; // Read and display the file contents. Since we're reading text, we // use a FileReader instead of a FileInputStream. try { f = new File(directory, filename); // Create a file object in = new FileReader(f); // And a char stream to read it char[] buffer = new char[4096]; // Read 4K characters at a time int len; // How many chars read each time textarea.setText(""); // Clear the text area while ((len = in.read(buffer)) != -1) { // Read a batch of chars String s = new String(buffer, 0, len); // Convert to a string textarea.append(s); // And display them } this.setTitle("FileViewer: " + filename); // Set the window title textarea.setCaretPosition(0); // Go to start of file } // Display messages if something goes wrong catch (IOException e) { textarea.setText(e.getClass().getName() + ": " + e.getMessage()); this.setTitle("FileViewer: " + filename + ": I/O Exception"); } // Always be sure to close the input stream! finally { try { if (in != null) in.close(); } catch (IOException e) { } } } /** * Handle button clicks */ public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if (cmd.equals("open")) { // If user clicked "Open" button // Create a file dialog box to prompt for a new file to display FileDialog f = new FileDialog(this, "Open File", FileDialog.LOAD); f.setDirectory(directory); // Set the default directory // Display the dialog and wait for the user's response f.show(); directory = f.getDirectory(); // Remember new default directory setFile(directory, f.getFile()); // Load and display selection f.dispose(); // Get rid of the dialog box } else if (cmd.equals("close")) // If user clicked "Close" button this.dispose(); // then close the window } /** * The FileViewer can be used by other classes, or it can be used standalone * with this main() method. */ static public void main(String[] args) throws IOException { // Create a FileViewer object Frame f = new FileViewer((args.length == 1) ? args[0] : null); // Arrange to exit when the FileViewer window closes f.addWindowListener(new WindowAdapter() { public void windowClosed(WindowEvent e) { System.exit(0); } }); // And pop the window up f.show(); } }