书上的程序、编译的时候报错,是什么原因?
- Java code
/* * Core Java P407 **/// 本程序是《Java核心技术 卷一:基础知识》(第八版)(中文版 机械工业出版社出版)第407页的源程序// 我在编译的时候出了错误,但是却找不出来,望高人指点package first;import java.awt.*;import java.awt.event.*;import java.beans.*;import java.io.File;import javax.swing.*;import javax.swing.filechooser.*;import javax.swing.filechooser.FileFilter;/* 这里书上还导入了另一个包: import java.util.*; 但是我在eclipse上编译的时候编译器提示说这个包从来没有用到过*/public class FileChooserTest { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { ImageViewerFrame frame = new ImageViewerFrame(); // 这里报错 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setTitle("FileChooserTest"); frame.setVisible(true); } }); }}/* * A frame that has a menu for loading an image and a display area for the loaded image * */class ImageViewerFrame extends DrawFrame // 这里的DrawFrame是我自己定义的一个类,主要是设置Frame // 的宽和高{ /** * */ private static final long serialVersionUID = 1L; private JLabel label ; private JFileChooser chooser ; public ImageViewerFrame() { // set a menu bar JMenuBar mBar = new JMenuBar(); setJMenuBar(mBar); JMenu menu = new JMenu("File"); mBar.add(menu); JMenuItem openItem = new JMenuItem("Open"); menu.add(openItem); openItem.addActionListener(new FileOpenListener()); JMenuItem exitItem = new JMenuItem("Exit"); menu.add(exitItem); exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } }); // use a label to display the image label = new JLabel(); add(label); // set up file chooser chooser = new JFileChooser(); // accept all image files ending with .jpg .jpeg .gif /* final ExtensionFileFilter filter = new ExtensionFileFilter(); filter.addExtension("jpg"); filter.addExtension("jpeg"); filter.addExtension("gif"); filter.setDescription("Image files"); */ FileNameExtensionFilter filter = new FileNameExtensionFilter("Image files", "jpg", "jpeg", "gif"); chooser.setFileFilter(filter); chooser.setAccessory(new ImagePreviewer(chooser)); //这里报错 chooser.setFileView(new FileIconView(filter, new ImageIcon("palette.gif"))); } private class FileOpenListener implements ActionListener { public void actionPerformed(ActionEvent event) { chooser.setCurrentDirectory(new File(".")); // shoe file chooser dialog int result = chooser.showOpenDialog(ImageViewerFrame.this); // if image file accepted , set it as icon of the label if(result == JFileChooser.APPROVE_OPTION) { String name = chooser.getSelectedFile().getPath(); label.setIcon(new ImageIcon(name)); } } }}/* * A file view that display an icon for all files that match a file filter * */class FileIconView extends FileView{ private FileFilter filter ; private Icon icon ; // constructs a FileIconView public FileIconView(FileFilter aFilter, Icon anIcon) { filter = aFilter; icon = anIcon; } public Icon getIcon(File f) { if(!f.isDirectory() && filter.accept(f)) return icon; else return null; }}/* * A file chooser accessory that previews images * */class ImagePreviewer extends JLabel{ /** * */ private static final long serialVersionUID = 1L; // constructs an ImagePreviewer public ImagePreviewer(JFileChooser chooser) { setPreferredSize(new Dimension(100, 100)); setBorder(BorderFactory.createEtchedBorder()); chooser.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { if(event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY); { // the user has selected a new file File f = (File) event.getNewValue(); //这里报错 if(f == null) { setIcon(null); return; } // read the image into an icon ImageIcon icon = new ImageIcon(f.getPath()); // if the icon is too large to fit ,scale it if(icon.getIconWidth() > getWidth()) icon = new ImageIcon(icon.getImage().getScaledInstance(getWidth(), -1, Image.SCALE_DEFAULT)); setIcon(icon); } } }); }}
编译的时候报错是这样的
- Java code
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: first.ImagePreviewer cannot be cast to java.io.File at first.ImagePreviewer$1.propertyChange(FileChooserTest.java:153) at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:339) at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:276) at java.awt.Component.firePropertyChange(Component.java:8132) at javax.swing.JFileChooser.setAccessory(JFileChooser.java:1235) at first.ImageViewerFrame.<init>(FileChooserTest.java:83) at first.FileChooserTest$1.run(FileChooserTest.java:21) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
[解决办法]
first.ImagePreviewer 不能转换成 java.io.File
[解决办法]
刚才试了下代码,确实
event.getNewValue()返回一个object,而且这个是chooser的事件,为啥会运行时变成ImagePreviewer 的对象了
mark下
[解决办法]
File f = (File) event.getNewValue();
event.getNewValue()得到的是一个ImagePreviewer,强制转换为File,肯定会有问题啊
[解决办法]
首先,你这不叫编译错误,叫运行时错误
错误的原因在于
- Java code
public void propertyChange(PropertyChangeEvent event) { if(event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY); { // the user has selected a new file File f = (File) event.getNewValue(); //这里报错
[解决办法]
be careful!!
[解决办法]
因为很多地方都会导致propertyChange事件发生,不一定每次发生都是因为选择了文件,比如你调用
chooser.setFileFilter(filter);
chooser.setAccessory(new ImagePreviewer(chooser));
chooser.setFileView(new FileIconView(filter, new ImageIcon("palette.gif")));
这些都会导致chooser的属性发生改变而发生事件,所以你修改一下你的事件里的代码,判断一下属性改变的是否是文件,是再继续强行转换,就可以了,比如
- Java code
public ImagePreviewer(JFileChooser chooser) { setPreferredSize(new Dimension(100, 100)); setBorder(BorderFactory.createEtchedBorder()); chooser.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { if(event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY); { // the user has selected a new file if (event.getNewValue() instanceof File) { //追加一个判断 File f = (File) event.getNewValue(); //这里报错 if(f == null) { setIcon(null); return; } // read the image into an icon ImageIcon icon = new ImageIcon(f.getPath()); // if the icon is too large to fit ,scale it if(icon.getIconWidth() > getWidth()) icon = new ImageIcon(icon.getImage().getScaledInstance(getWidth(), -1, Image.SCALE_DEFAULT)); setIcon(icon); } } } }); }
[解决办法]
7L好眼力
if(event.getPropertyName() == JFileChooser.SELECTED_FILE_CHANGED_PROPERTY);
这个本身就是对选择文件造成propertyg改变发生事件作的判断,只是因为后面多了个; 所以if相当于后面接的是空代码,然后后面的{}内的代买相当无条件执行。