我正在寻找一些帮助,以便在后面的代码中自定义JFileChooser.getSelectedFile()
方法。我正在研究处理这个类的异常。一切都很好,但我发现在运行程序并且对话框提示浏览并选择目录时,如果我在不存在的文件夹名称框中键入目录,则抛出空指针异常。
我可以做些什么来避免抛出此NullPointerException
将禁用键入文件夹名称框的功能。这意味着只能选择浏览框中列出的目录。有没有办法禁用键入文件夹名称框的功能?如果没有,有没有人有任何建议?我希望能够在文件夹名称框中禁用输入,这样我就可以想到我可以将该框从文本框更改为显示面板等。
代码:
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;
}
}
例外:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at directorylister.DirectoryLister.enumerateDirectory(DirectoryLister.java:88)
at directorylister.DirectoryLister.showDirectoryContents(DirectoryLister.java:77)
at directorylister.DirectoryLister.selectDirectory(DirectoryLister.java:65)
at directorylister.GUI$ButtonHandler.actionPerformed(GUI.java:336)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6516)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6281)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:740)
at java.awt.EventQueue.access$300(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:699)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:713)
at java.awt.EventQueue$4.run(EventQueue.java:711)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:710)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
完整代码:
package directorylister;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
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;
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);
}
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);
}
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);
}
public void registerModel(DirectoryLister model)
{
this.model = model;
}
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;
}
}
public void setAddressLabelText(String text)
{
addressLabel.setText(text);
}
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});
}
public void resetGUI()
{
// clear address
addressLabel.setText("");
// remove all rows from table
while (tableModel.getRowCount() > 0)
{
tableModel.removeRow(0);
}
}
class CustomTableCellRenderer implements TableCellRenderer
{
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column)
{
return (JComponent)value;
}
}
class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JButton b = (JButton)e.getSource();
if (b.getText().equals("Browse..."))
{
// prompt user to select directory
model.selectDirectory();
}
}
}
}
package directorylister;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.awt.*;
import javax.swing.*;
public class DirectoryLister
{
/** GUI used to display results */
private GUI gui;
/** base path of directory to be traversed */
private String basePath;
public DirectoryLister(GUI gui)
{
this.gui = gui;
}
/**
* 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);
}
public void showDirectoryContents(String basePath){
File basePathFile = new File(basePath);
enumerateDirectory(basePathFile);
}
/**
* Recursive method to enumerate the contents of a directory.
*
* @param f directory to enumerate
*/
private void enumerateDirectory(File f)
{
File[] files = f.listFiles();
for (File file : files) {
if (file.isDirectory()) {
file.getAbsolutePath();
String fSize = getSizeString(file.length());
String fType = "Directory";
String fDate = formattedDateString(file.lastModified());
gui.updateListing(file.getAbsolutePath(), fSize, fType, fDate);
enumerateDirectory(file);
}
else
for(int i = 0; i < files.length && files[i].isDirectory()==false; i++) {
file.getAbsolutePath();
String fSize = getSizeString(file.length());
String fType = "File";
String fDate = formattedDateString(file.lastModified());
gui.updateListing(file.getAbsolutePath(), fSize, fType, fDate);
}
}
}
private String getSizeString(long size)
{
long kbSize = size / 1024;
if (kbSize < 1) {
return "File size is " + size + " bytes";
}
else {
return "File size is " + kbSize + "KB";
}
}
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);
}
}