Исключение в потоке "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JTable

У меня есть код, который при запуске генерирует таблицу в форме свинга, которая содержит набор флажков, которые могут быть выбраны или не выбраны

Когда я нажимаю на вкладку "Проверить все", я могу установить / снять все остальные флажки ниже, но когда я выбираю один из следующих флажков по отдельности, я получаю эту ошибку:

> Исключение в потоке "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JTable
    в com.tps.charts.CheckBoxHeader.handleClickEvent(JTableHeaderCheckBox.java:152)
    на com.tps.charts.CheckBoxHeader.mouseClicked(JTableHeaderCheckBox.java:168)
    at java.awt.AWTEventMulticaster.mouseClicked(Неизвестный источник)
    at java.awt.AWTEventMulticaster.mouseClicked (Неизвестный источник)
    at java.awt.AWTEventMulticaster.mouseClicked (Неизвестный источник)
    at java.awt.AWTEventMulticaster.mouseClicked (Неизвестный источник)
    at java.awt.AWTEventMulticaster.mouseClicked (Неизвестный источник) mousePressed......
    at java.awt.AWTEventMulticaster.mouseClicked(Неизвестный источник)
    at java.awt.AWTEventMulticaster.mouseClicked (Неизвестный источник)
    at java.awt.AWTEventMulticaster.mouseClicked (Неизвестный источник)
    в java.awt.Component.processMouseEvent(Неизвестный источник)
    в javax.swing.JComponent.processMouseEvent(Неизвестный источник)
    в java.awt.Component.processEvent (Неизвестный источник)
    в java.awt.Container.processEvent (Неизвестный источник)
    в java.awt.Component.dispatchEventImpl(Неизвестный источник)
    в java.awt.Container.dispatchEventImpl(Неизвестный источник)
    в java.awt.Component.dispatchEvent (Неизвестный источник)
    в java.awt.LightweightDispatcher.retargetMouseEvent(Неизвестный источник)
    в java.awt.LightweightDispatcher.processMouseEvent(Неизвестный источник)
    в java.awt.LightweightDispatcher.dispatchEvent(Неизвестный источник)
    в java.awt.Container.dispatchEventImpl(Неизвестный источник)
    в java.awt.Window.dispatchEventImpl(неизвестный источник)
    в java.awt.Component.dispatchEvent (Неизвестный источник)
    в java.awt.EventQueue.dispatchEvent(Неизвестный источник)
    в java.awt.EventDispatchThread.pumpOneEventForHierarchy(Неизвестный источник)
    в java.awt.EventDispatchThread.pumpEventsForHierarchy(Неизвестный источник)
    в java.awt.EventDispatchThread.pumpEvents(Неизвестный источник)
    в java.awt.EventDispatchThread.pumpEvents(Неизвестный источник)
    at java.awt.EventDispatchThread.run(неизвестный источник)

Код:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class JTableHeaderCheckBox {

    private Object colNames[] = {"", "String", "String"};
    private Object[][] data = {};
    private DefaultTableModel dtm;
    private JTable table;
    private TableColumn tc;

    public void buildGUI() {
        dtm = new DefaultTableModel(data, colNames);
        table = new JTable(dtm);
        for (int x = 0; x < 5; x++) {
            dtm.addRow(new Object[]{false, "Row " + (x + 1) + " Col 2", "Row " + (x + 1) + " Col 3"});
        }
        JScrollPane sp = new JScrollPane(table);
        tc = table.getColumnModel().getColumn(0);
        tc.setCellEditor(table.getDefaultEditor(Boolean.class));
        tc.setCellRenderer(table.getDefaultRenderer(Boolean.class));
        tc.setHeaderRenderer(new CheckBoxHeader(new MyItemListener()));
        JFrame f = new JFrame();
        f.getContentPane().add(sp);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    private class MyItemListener implements ItemListener {

        @Override
        public void itemStateChanged(ItemEvent e) {
            System.out.println("ItemStateChanged");
            Object source = e.getSource();
            if (source instanceof AbstractButton == false) {
                return;
            }
            boolean checked = e.getStateChange() == ItemEvent.SELECTED;
            for (int x = 0, y = table.getRowCount(); x < y; x++) {
                table.setValueAt(checked, x, 0);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JTableHeaderCheckBox().buildGUI();
            }
        });
    }
}

class CheckBoxHeader extends JCheckBox implements TableCellRenderer, MouseListener {

    private static final long serialVersionUID = 1L;
    private CheckBoxHeader rendererComponent;
    private int column;
    private boolean mousePressed = false;

    public CheckBoxHeader(ItemListener itemListener) {
        rendererComponent = this;
        rendererComponent.addItemListener(itemListener);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        if (table != null) {
            JTableHeader header = table.getTableHeader();
            table.addMouseListener(rendererComponent);
            if (header != null) {
                rendererComponent.setForeground(header.getForeground());
                rendererComponent.setBackground(header.getBackground());
                rendererComponent.setFont(header.getFont());
                header.addMouseListener(rendererComponent);
            }
        }
        setColumn(column);
        rendererComponent.setText("Check All");
        setBorder(UIManager.getBorder("TableHeader.cellBorder"));
        return rendererComponent;
    }

    protected void setColumn(int column) {
        this.column = column;
    }

    public int getColumn() {
        return column;
    }

    protected void handleClickEvent(MouseEvent e) {
        if (mousePressed) {
            mousePressed = false;
            JTableHeader header = (JTableHeader) (e.getSource());
            JTable tableView = header.getTable();
            TableColumnModel columnModel = tableView.getColumnModel();
            int viewColumn = columnModel.getColumnIndexAtX(e.getX());
            column = tableView.convertColumnIndexToModel(viewColumn);
            if (viewColumn == this.column && e.getClickCount() == 1 && column != -1) {
                System.out.println(" doClick()......");
                doClick();
            }
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println(" mouseClicked()......");
        handleClickEvent(e);
        /* problem occurs from this line */
        ((JTableHeader) e.getSource()).repaint();
    }

    @Override
    public void mousePressed(MouseEvent e) {
        //System.out.println("mousePressed(MouseEvent e).......");
        mousePressed = true;
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        //System.out.println(" mouseReleased()......");
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        //System.out.println(" mouseEntered()......");
    }

    @Override
    public void mouseExited(MouseEvent e) {
        //System.out.println("mouseExited()......");
    }
}

с исключением

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: 
javax.swing.JTable cannot be cast to javax.swing.table.JTableHeader

2 ответа

Вы приводите источник события к JTableHeader:

JTableHeader header = (JTableHeader) (e.getSource());

и источник JTable когда вы нажимаете на ячейку. У меня будет два разных слушателя для заголовка и выбора ячейки, или вы можете сделать взлом, проверив event.getSource() instanceof ... в вашем слушателе щелчка мыши.

По строке 152: JTableHeader header = (JTableHeader)(e.getSource()); вы предполагаете, что событие находится в заголовке таблицы. Вам нужно проверить класс источника события, чтобы увидеть, находится ли он в заголовке или в отдельном флажке.

Другие вопросы по тегам