Insubstantial / insubstantial

Swing look-and-feel library and assorted widgets
195 stars 57 forks source link

Breadbar randomly but rarely throws a ClassCastException #21

Open dan-ryan opened 13 years ago

dan-ryan commented 13 years ago

This doesn't seem to be from my code. This also happened in substance 6.1.

Running 6.3.

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: org.pushingpixels.flamingo.api.bcb.BreadcrumbItem cannot be cast to org.pushingpixels.flamingo.internal.ui.bcb.BreadcrumbItemChoices at org.pushingpixels.flamingo.internal.ui.bcb.BasicBreadcrumbBarUI.updateComponents(BasicBreadcrumbBarUI.java:461) at org.pushingpixels.flamingo.internal.ui.bcb.BasicBreadcrumbBarUI$3$1.process(BasicBreadcrumbBarUI.java:278) at javax.swing.SwingWorker$3.run(Unknown Source) at sun.swing.AccumulativeRunnable.run(Unknown Source) at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(Unknown Source) at sun.swing.AccumulativeRunnable.run(Unknown Source) at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(Unknown Source) at javax.swing.Timer.fireActionPerformed(Unknown Source) at javax.swing.Timer$DoPostEvent.run(Unknown Source) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$000(Unknown Source) at java.awt.EventQueue$1.run(Unknown Source) at java.awt.EventQueue$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at com.community.xanadu.debug.EventDispatchThreadHangMonitor.dispatchEvent(EventDispatchThreadHangMonitor.java:216) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)

disrvptor commented 13 years ago

zammbi, do you have test code that can reproduce this problem? I know you said it was random and rare, which leads me to believe it's some sort of race condition, but I would like to see if maybe it's something in what you are doing to expose this issue.

dan-ryan commented 13 years ago

Its quite a quite a bit of code. Can't you just do a instanceof check on where that line is for now?

But here is the JBreadCrumbBar class (hope this helps a little):

package file;

import helpers.FileHelper;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import manager.RootManager;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.pushingpixels.flamingo.api.bcb.BreadcrumbBarCallBack;
import org.pushingpixels.flamingo.api.bcb.BreadcrumbItem;
import org.pushingpixels.flamingo.api.bcb.JBreadcrumbBar;
import org.pushingpixels.flamingo.api.common.StringValuePair;

import cache.ImageCache;

/**
 * Breadcrumb bar that allows browsing a file system.
 */
public class BreadcrumbFileObjectSelector extends JBreadcrumbBar<FileCacheItem> {

    private static final long serialVersionUID = 1L;
    /**
     * file system specific implementation of the
     * {@link BreadcrumbBarCallBack}.
     */
    public static class DirCallback extends BreadcrumbBarCallBack<FileCacheItem> {
        /*
         * (non-Javadoc)
         *
         * @see org.jvnet.flamingo.bcb.BreadcrumbBarCallBack#setup()
         */
        @Override
        public void setup() {
        }

        private FileCacheItem[] getFiles(final FileCacheItem file){

            if(file.isContainerFile()){
                if(file.getName().equalsIgnoreCase("local"))
                    //System.out.print("local");
                    return RootManager.getInstance().getRootsDataCache();
                else{

                }
            }else{
                if(!FileHelper.isLikeFolder(file))
                    return new FileCacheItem[0];
                try {
                    final FileObject[] tempfile = file.getFile().getChildren();
                    final ArrayList<FileCacheItem> fileList = new ArrayList<FileCacheItem>(tempfile.length);
                    for(final FileObject fo: tempfile)
                    {
                        if(!FileHelper.isLikeFolder(fo)) {
                            continue;
                        }
                        fileList.add(new FileCacheItem(fo,FileHelper.getFormatedName(fo)));
                    }
                    return fileList.toArray(new FileCacheItem[fileList.size()]);
                } catch (final FileSystemException e) {
                    System.out.println("Unable to get children: " + file.getFile().getName().getFriendlyURI() + " " + e.getMessage());
                    return new FileCacheItem[0];
                }
            }
            return new FileCacheItem[0];
        }

        @Override
        public List<StringValuePair<FileCacheItem>> getPathChoices( final List<BreadcrumbItem<FileCacheItem>> path) {

            if (path == null) {

                //TODO: Create a list of file systems.
                //Local-> roots, ftp -> base, etc....

                final LinkedList<StringValuePair<FileCacheItem>> bRoots = new LinkedList<StringValuePair<FileCacheItem>>();
                final StringValuePair<FileCacheItem> local = new StringValuePair<FileCacheItem>("Local", new FileCacheItem(null,"Local",true));
                bRoots.add(local);

                return bRoots;
            }
            if (path.size() == 0)
                return null;
            final FileCacheItem lastInPath = path.get(path.size() - 1).getData();

            final FileCacheItem[] files = getFiles(lastInPath);

            final LinkedList<StringValuePair<FileCacheItem>> lResult = new LinkedList<StringValuePair<FileCacheItem>>();

            for (final FileCacheItem child : files) {
                final StringValuePair<FileCacheItem> pair = new StringValuePair<FileCacheItem>(child.getName(), child);
                pair.set("icon", ImageCache.getInstance().getImageIcon(child.getFile()));
                lResult.add(pair);
            }
            Collections.sort(lResult, new Comparator<StringValuePair<FileCacheItem>>() {
                @Override
                public int compare( final StringValuePair<FileCacheItem> o1,  final StringValuePair<FileCacheItem> o2) {
                    //String key1 = fsv.isFileSystemRoot(o1.getValue()) ? o1.getValue().getAbsolutePath() : o1.getKey();
                    //String key2 = fsv.isFileSystemRoot(o2.getValue()) ? o2.getValue().getAbsolutePath() : o2.getKey();
                    final String key1 = o1.getKey();
                    final String key2 = o2.getKey();

                    return key1.toLowerCase(Locale.getDefault()).compareTo(key2.toLowerCase(Locale.getDefault()));
                }
            });
            return lResult;
        }

        /*
         * (non-Javadoc)
         *
         * @see
         * org.jvnet.flamingo.bcb.BreadcrumbBarCallBack#getLeafContent(java.
         * lang.Object)
         */

        @Override
        public InputStream getLeafContent( final FileCacheItem leaf) {
            try {
                return leaf.getFile().getContent().getInputStream();
            } catch ( final FileSystemException e) {
                System.out.println("Failed to get input: " + leaf.getFile().getName().getFriendlyURI());
                return null;
            }
        }
    }

    /**
     * Creates a new breadcrumb bar file selector that uses native icons and the
     * default file system view.
     */
    public BreadcrumbFileObjectSelector() {
        super(new DirCallback());
    }

    /**
     * Sets the selected path based of the specified file. If this file is
     * either <code>null</code> or not a directory, the home directory is
     * selected.
     *
     * @param dir Points to a directory to be selected.
     */
    public void setPath( final FileCacheItem dir) {
        if (dir == null)
            return;

        final ArrayList<BreadcrumbItem<FileCacheItem>> path = new ArrayList<BreadcrumbItem<FileCacheItem>>();
        FileObject parent = dir.getFile();
        BreadcrumbItem<FileCacheItem> bci = new BreadcrumbItem<FileCacheItem>(FileHelper.getFormatedName(dir.getFile()), dir);
        bci.setIcon(ImageCache.getInstance().getImageIcon(dir.getFile()));
        path.add(bci);
        while (true) {
            try {
                parent = parent.getParent();
            } catch ( final FileSystemException e) {
                System.out.println("Failed to get parent:" + dir.getFile().getName().getFriendlyURI());
            }
            if (parent == null) {
                break;
            }
            final String name = FileHelper.getFormatedName(parent);
            final FileCacheItem fd = new FileCacheItem(parent, name,false);

            bci = new BreadcrumbItem<FileCacheItem>(name, fd);

            bci.setIcon(ImageCache.getInstance().getImageIcon(parent));
            path.add(bci);
        }
        Collections.reverse(path);
        this.setPath(path);
    }
}
benfortuna commented 13 years ago

I am familiar with this problem, but I think in my case it was caused by an uncaught exception in the BreadcrumbBarCallBack.

The exception is quite misleading, perhaps handling RuntimeExceptions thrown by the BreadcrumBarCallBack will solve this..