Ошибка при создании JToolBar

Все кнопки добавляются отлично, кроме цветных кнопок
Я получаю эту ошибку при добавлении кнопок на панель инструментов
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: Sketcher.SketcherFrame$ColorAction cannot be cast to javax.swing.Icon

ColorAction - это класс для создания кнопок панели инструментов, которые изменяют цвет фона JFrame. Расширяется javax.swing.AbstractAction,
Кнопки типа ColorAction хранятся в ColorActions[] массив и есть их SMALL_ICON свойство установлено в соответствующие значения.

Трассировка стека:

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)

Выделенные Методы

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

а также

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);
            }
        }
    }

а также

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);
    }

а также

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);
        }
    }

Файл констант, содержащий пути к изображениям

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");
}

а также

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;
    }

Если я удаляю цветные кнопки, то кнопки открытия, закрытия, сохранения добавляются просто отлично. Я понятия не имею, почему они не могут быть добавлены.

1 ответ

Решение

Сначала укажите точную строку в вашем коде, которая вызвала это исключение. Глядя на трассировку стека, я бы предположил, что это строка 153. SketcherFrame.java. Было бы проще отлаживать.

Но даже без этого ваша проблема в том, что вы путаете AbstractAction для Icon, Все, что бросило исключение, ожидало реализации Icon и вы дали ему реализацию AbstractAction,

Я могу предложить две вещи:

  1. Воплощать в жизнь Icon в SketcherFrame$ColorAction также. Вы можете реализовать несколько интерфейсов в любом случае. Но...
  2. ... на мой взгляд, создание класса, который является одновременно AbstractAction и Icon плохое дизайнерское решение. Поскольку вы, похоже, используете внутренние классы, просто создайте внутренний класс, реализующий Icon и передать его тому, что вызывает это исключение.
Другие вопросы по тегам