简体   繁体   中英

JTable, JLabel, and its Icon (JLabel can't be customized with Icon)?

This summer is not a real summer, i thought. A cup of coffee make me feel it as a summer, tough (lol).

I have a little bit naughty JTable. OMG. Below is my JTable that use my own customized TableModel. You could see it on its method of getColumnClass (), there... it was made for returning as JLabel only. ANd then, I also customize the 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);
    }
});

And Where is the JTableRenderer ? Here... this is my Custom Renderer below...

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

    }
}

And then, I need to pu JLabel inside each of the Cell. I start to add some JLabel(s) inside the Object of Array over the Cells of the JTable using this code; (which is no problem).

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

Everything works fine, I guess. But because of My purpose is that ---> To put an Icon or to make it Invisible once the user Click on JTable Cells , thus II tried to do my MouseEvent once pressed and calling these lines of code;

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

And seems to me that the Marked (below the commented ) code above are not working. Yeah, the JLabel casted couldn't be changed its Icon (image), and nor its visibility as well. Is it the Model cause all of this ? NB: My Cells data added later after the Model created differently.

It seems to me that what you want to do is to just leave all table cells empty, except the ones clicked by the user, where some mark icon should appear, right?

If so, your table model should not contain JLabel instances. A JLabel is a visual component, used to render some data graphically. The data itself is not a JLabel. In your case, I think it should thus be a Boolean (true when clicked by the user, false otherwise).

Now you could use a custom renderer (although the default one for booleans could also be OK) to display your booleans. This renderer would be a subclass of DefaultTableCellRenderer , which is itself a subclass of JLabel. The renderer (the same instance for all the cells configured to use this renderer) would just display a marked icon if the Boolean value to render is true, and a not marked icon (or no icon at all) when the Boolean value to render is false.

Then, your click handler would just have one mission: make the clicked cell contain true rather than false. To do that, it would just have to change the appropriate value in the table model.

To recap: a table model is used to hold data. Think of it as the data you would find in a database. Would you hold a JLabel in the database? No, you would hold a boolean, a string or an integer. The table can render this data as you want, and this is the mission of the renderer.

Side note: stop with the hungarian notation: it doesn't make sense in Java. It makes code hard to read. Everything except primitive types is an object, and you can't assign a meaningful prefix to every possible type. Rather, use readable and meaningful english names : tableModel rather than o_dtb , correctAnswer rather than s_questAns , userAnswer rather than s_userAns .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM