Question

All buttons are added fine apart from the color buttons
I get this error while adding buttons to a toolbar
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: Sketcher.SketcherFrame$ColorAction cannot be cast to javax.swing.Icon

ColorAction is a class to create toolbar buttons that change the background color of the JFrame. It extends javax.swing.AbstractAction.
Buttons of type ColorAction are stored in a ColorActions[] array and have their SMALL_ICON property set to appropriate values.

Stack Trace:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: Sketcher.SketcherFrame$ColorAction cannot be cast to javax.swing.Icon
    at javax.swing.AbstractButton.setIconFromAction(Unknown Source)
    at javax.swing.AbstractButton.configurePropertiesFromAction(Unknown Source)
    at javax.swing.AbstractButton.setAction(Unknown Source)
    at javax.swing.JButton.<init>(Unknown Source)
    at Sketcher.SketcherFrame.addToolBarButton(SketcherFrame.java:182)
    at Sketcher.SketcherFrame.createToolbar(SketcherFrame.java:174)
    at Sketcher.SketcherFrame.<init>(SketcherFrame.java:27)
    at Sketcher.Sketcher.createGUI(Sketcher.java:16)
    at Sketcher.Sketcher.access$1(Sketcher.java:15)
    at Sketcher.Sketcher$1.run(Sketcher.java:10)
    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$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    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)

Highlighted Methods

private void createColorMenu() {
    createElementColorActions();
    colorMenu = new JMenu("Color");
    colorMenu.setMnemonic('M');
    createRadioButtonDropDown(colorMenu,colorActions,blueAction);
    menuBar.add(colorMenu);
}  

and

private void createRadioButtonDropDown(JMenu menu, Action[] actions,Action selected){
        ButtonGroup group = new ButtonGroup();
        JRadioButtonMenuItem item = null;
        for(Action action : actions){
            group.add(menu.add(item = new JRadioButtonMenuItem(action)));
            if(action==selected){
                item.setSelected(true);
            }
        }
    }

and

private void addToolBarButton(Action action){
        >>JButton button = new JButton(action);
        button.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(2,5,5,2),
                            BorderFactory.createRaisedBevelBorder()));
        button.setHideActionText(true);
        toolBar.add(button);
    }

and

private void createToolbar(){
        for(FileAction action : fileActions){
            if(action!=exitAction && action!=closeAction){
                addToolBarButton(action);
            }
        }
        toolBar.addSeparator();
        for(ColorAction action : colorActions){
            >>addToolBarButton(action);
        }
        toolBar.addSeparator();
        for(TypeAction action : typeActions){
            addToolBarButton(action);
        }
    }

Constants File containing paths to images

import java.awt.Color;
import javax.swing.*;
public class SketcherConstants {
    public final static int LINE = 101;
    public final static int RECTANGLE = 102;
    public final static int CIRCLE = 103;
    public final static int CURVE = 104;

    public final static int DEFAULT_ELEMENT_TYPE = LINE;
    public final static Color DEFAULT_ELEMENT_COLOR = Color.blue;

    public final static String imagePath = "H:/Fasih/SketcherIcons/";
    public static final Icon NEW16 = new ImageIcon(imagePath+"new.GIF");
    public static final Icon OPEN16 = new ImageIcon(imagePath+"open.GIF");
    public static final Icon SAVE16 = new ImageIcon(imagePath+"save.GIF");
    public static final Icon PRINT16 = new ImageIcon(imagePath+"print.GIF");
    public static final Icon SAVEAS16 = new ImageIcon(imagePath+"saveas.GIF");

    public static final Icon LINE16 = new ImageIcon(imagePath+"line.PNG");
    public static final Icon CURVE16 = new ImageIcon(imagePath+"curve.PNG");
    public static final Icon RECTANGLE16 = new ImageIcon(imagePath+"square.PNG");
    public static final Icon CIRCLE16 = new ImageIcon(imagePath+"circle.PNG");

    public static final Icon RED16= new ImageIcon(imagePath+"red.GIF");
    public static final Icon GREEN16= new ImageIcon(imagePath+"green.GIF");
    public static final Icon YELLOW16= new ImageIcon(imagePath+"yellow.GIF");
    public static final Icon BLUE16= new ImageIcon(imagePath+"blue.GIF");
}

and

class ColorAction extends AbstractAction {
        public ColorAction(String name,Color color){
            super(name);
            this.color = color;
        }
        public ColorAction(String name,Color color,char ch,int modifiers){
            this(name,color);
            putValue(ACCELERATOR_KEY,KeyStroke.getKeyStroke(ch,modifiers));
            int index = name.toUpperCase().indexOf(ch);
            if(index!=-1){
                putValue(DISPLAYED_MNEMONIC_INDEX_KEY,index);
            }
        }
        public void actionPerformed(ActionEvent e){
            elementColor = color;
            getContentPane().setBackground(color);
        }
        private Color color;
    }

If I remove the color buttons then the open, close, save buttons are added just fine. I have no idea why these cant be added.

Was it helpful?

Solution

First, please indicate the exact line in your code that triggered this exception. Looking at the stack trace, I'd assume that's SketcherFrame.java line 153. It'd be easier to debug.

But even without that, your problem seems to be that you are confusing AbstractAction for an Icon. Whatever threw the Exception was expecting an implementation of Icon and you gave it an implementation of AbstractAction.

I can suggest two things:

  1. Implement Icon in SketcherFrame$ColorAction as well. You can implement multiple interfaces anyway. But...
  2. ...in my opinion, creating a class that is both an AbstractAction and an Icon is a bad design decision. Since that you seem to be utilizing inner classes, just create an inner class implementing Icon and pass it to whatever triggers that exception.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top