【问题标题】:Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JTable线程“AWT-EventQueue-0”中的异常 java.lang.ClassCastException: javax.swing.JTable
【发布时间】:2011-10-28 20:45:25
【问题描述】:

我有一个code,它在运行时会生成一个摆动形式的表格,其中包含一组可以选中或取消选中的复选框

当我单击 Check All 选项卡时,我可以选择/取消选择下面的所有其他复选框,但是当我单独选择以下复选框之一时,我会收到此错误:

> 线程“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) 在 java.awt.AWTEventMulticaster.mouseClicked(未知来源) 在 java.awt.AWTEventMulticaster.mouseClicked(未知来源) 在 java.awt.AWTEventMulticaster.mouseClicked(未知来源) 在 java.awt.AWTEventMulticaster.mouseClicked(未知来源) 在 java.awt.AWTEventMulticaster.mouseClicked(Unknown Source) mousePressed...... 在 java.awt.AWTEventMulticaster.mouseClicked(未知来源) 在 java.awt.AWTEventMulticaster.mouseClicked(未知来源) 在 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(未知来源) 在 java.awt.EventDispatchThread.run(未知来源)

code:

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

【问题讨论】:

  • IMO,这个code 在模型视图索引和耦合方面存在重大缺陷。尝试移动一列以查看效果。
  • 另见Q&A

标签: swing exception jtable java


【解决方案1】:

您正在将事件源转换为 JTableHeader

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

当您单击一个单元格时,源是JTable。我将为标题和单元格选择设置两个不同的侦听器,或者您可以通过在鼠标单击侦听器中检查event.getSource() instanceof ... 来进行破解。

【讨论】:

    【解决方案2】:

    在第 152 行:JTableHeader header = (JTableHeader)(e.getSource()); 您假设事件在表头上。您需要检查事件源的类以查看它是在标题上还是在单个复选框上。

    【讨论】:

    • 尝试通过 e.getComponent().getName() 检查组件每次都会返回组件名称为 null。如何检查组件名称或类型?
    • 使用e.getSource().getClass().getName()e.getSource() instanceof JTableHeader
    • 是的,谢谢,现在我正在检查组件名称(JTable 或 JTableHeader),然后根据组件执行单独的鼠标按下操作方法。现在我需要检查所有单元格(复选框) 是否完全选中,并基于此需要选择/取消选择 JTableHeader (Check All checkBox)。我被困在这里。帮助表示赞赏...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    相关资源
    最近更新 更多