JTable,JLabel及其Icon(JLabel不能用Icon定制)?

时间:2011-08-21 07:59:53

标签: java swing icons jtable jlabel

今年夏天不是真正的夏天,我想。 一杯咖啡让我觉得这是一个夏天,坚韧(笑)。

我有点顽皮的JTable。我的天啊。 下面是我的JTable使用我自己的自定义TableModel。您可以在 getColumnClass ()的方法中看到它,那里......它仅用于返回 JLabel 。 然后,我还自定义 DefaultRenderer

jtbl_inGameEasy = new javax.swing.JTable();
jtbl_inGameEasy.setFont(new java.awt.Font("squeaky chalk sound", 0, 14)); // NOI18N
jtbl_inGameEasy.setForeground(new java.awt.Color(255, 255, 255));
jtbl_inGameEasy.setModel(new javax.swing.table.DefaultTableModel(
    new Object [][] {

    },
    new String [] {
        "null", "null", "null", "null", "null"
    }
) {
    boolean[] canEdit = new boolean [] {
        false, false, false, false, false
    };

    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return canEdit [columnIndex];
    }
    public Class getColumnClass(int columnIndex) {
        return JLabel.class;
    }
});
jtbl_inGameEasy.setDefaultRenderer(JLabel.class, new JLabelTableRenderer());
jtbl_inGameEasy.setFocusable(false);
jtbl_inGameEasy.setOpaque(false);
jtbl_inGameEasy.setRowHeight(55);
jtbl_inGameEasy.setShowHorizontalLines(false);
jtbl_inGameEasy.setShowVerticalLines(false);
jtbl_inGameEasy.setTableHeader(null);
jtbl_inGameEasy.addMouseListener(new java.awt.event.MouseAdapter() {
    public void mousePressed(java.awt.event.MouseEvent evt) {
        jtbl_inGameEasyMousePressed(evt);
    }
});

JTableRenderer 在哪里?这里... 这是我的自定义渲染器......

public class JLabelTableRenderer extends DefaultTableCellRenderer {

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {

        if (value instanceof JLabel) {
            //This time return only the JLabel without icon
            return (JLabel) value;
        } else {
            return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        }

    }
}

然后,我需要在每个Cell内部使用JLabel。 我开始使用此代码在 JTable 的单元格内添加一些JLabel内部的数组; (这没问题)。

DefaultTableModel o_dtb = jtbl_inGameEasy.getModel();
o_dtb.addRow(myArrayCustomizedObjectofJLabel);

我猜,一切正常。但是因为我的目的是--->要在用户单击上JTable 单元格时放置图标或使其不可见,因此II尝试执行 MouseEvent 一旦按下并调用这些代码行;

private void jtbl_inGameEasyMousePressed(java.awt.event.MouseEvent evt) {                                             
        // Checking inGameEasy Table Ans
        javax.swing.JTable source = (javax.swing.JTable) evt.getSource();
        int row = source.rowAtPoint(evt.getPoint());
        int column = source.columnAtPoint(evt.getPoint());

        DefaultTableModel o_dtb = (DefaultTableModel) jtbl_inGameEasy.getModel();
        String s_questAns = "" + Game.getCurrentQuestion().getResult();
        String s_userAns = "" + o_dtb.getValueAt(row, column);

// These two lines below are not Working, why yaa??    

    ((JLabel) o_dtb.getValueAt(row, column)).setVisible(false);
((JLabel) o_dtb.getValueAt(row, column)).setIcon(myIcon);

        if (s_questAns.equals(s_userAns)) {
            Game.correct();
            System.err.println("nice ans!");
        } else {
            jll_txtMiss.setText("Miss : " + Game.wrong());
            System.err.println("nope!");
        }

        nextQuestion();
    }               

在我看来,上面的标记(在评论下方)代码无效。 是的,JLabel铸造不能改变它的Icon(图像),也不能改变它的可见性。它是模型导致所有这些吗? 注意:在模型创建方式不同之后,我的单元格数据会被添加。

1 个答案:

答案 0 :(得分:4)

在我看来,您想要做的只是将所有表格单元格留空,除了用户点击的单元格,其中应该出现一些标记图标,对吧?

如果是这样,您的表模型不应包含JLabel个实例。 JLabel是一个可视组件,用于以图形方式呈现一些数据。数据本身不是JLabel。在你的情况下,我认为它应该是一个布尔值(当用户点击时为true,否则为false)。

现在你可以使用自定义渲染器(虽然布尔值的默认渲染器也可以),以显示你的布尔值。此渲染器将是DefaultTableCellRenderer的子类,它本身是JLabel的子类。渲染器(配置为使用此渲染器的所有单元格的相同实例)只显示标记图标(如果要渲染的布尔值为true),并且未标记图标(当渲染的布尔值为false时,(或根本没有图标)。

然后,您的点击处理程序将只有一个任务:使单击的单元格包含true而不是false。为此,只需更改表模型中的适当值即可。

回顾一下:表模型用于保存数据。可以将其视为数据库中的数据。你会在数据库中持有JLabel吗?不,你会持有布尔值,字符串或整数。该表可以根据需要呈现此数据,这是渲染器的任务。

旁注:用匈牙利语表示法停止:在Java中没有意义。它使代码难以阅读。除基本类型之外的所有内容都是对象,并且您不能为每个可能的类型分配有意义的前缀。相反,使用可读且有意义的英文名称:tableModel而不是o_dtbcorrectAnswer而不是s_questAnsuserAnswer而不是s_userAns