0

I'm making a custom TableModel usingAbstractTableModelfor a project, and I need to figure out a way to have a checkbox show up on some rows, but not others. I have already implemented a getColumn method, but I want to be able to have a checkbox not show up unless a certain condition in another column is reached (for example, if the object represented by a particular row is a lightbulb rather than, say, a toaster, give the user a checkbox to turn the light on or off).

I've tried using getValueAt and passing null or a string instead of a Boolean object in the hopes that maybe Swing wouldn't render the checkbox. And it doesn't, but it also throws a nasty set of ClassCastExceptions for trying to cast a String to a Boolean.

Does anyone have any ideas on how I could do something like this?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
nameless912
  • 367
  • 1
  • 12

1 Answers1

1

Columns in a Swing JTable are displayed using cell renderers. You should read How to Use Tables in the Java tutorials which has a section that describes how the mechanism works. This is how the core method of a custom cell renderer looks like:

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

The task of this method is to select and prepare a Component (by setting desired colors, fonts, images...) for a specific row and column that the framework will use paint on to its Graphics context. There is a DefaultTableCellRenderer that might do the trick without too much custom code (see the tutorial). Note that this rendering mechanism is an optimization chosen by the Swing developers.

You can also learn a lot about customizing Swing components in Swing Hacks. The examples are not especially well-designed code but just show how to make creative use of the Swing API.

Good luck!

Example (see comments):

    final JTable orderTable = new JTable(dataModel);
    // All columns with class Boolean are renderered with MyFancyItemRenderer
    orderTable.setDefaultRenderer(Boolean.class, new MyFancyItemRenderer());

    // Setting the cell renderers explicitly for each column
    final TableColumnModel columnModel = orderTable.getColumnModel();

    final TableColumn itemCountColumn = columnModel.getColumn(ITEM_COUNT);
    itemCountColumn.setCellRenderer(new MyFancyItemRenderer());

    // ...

    final TableColumn sumColumn = columnModel.getColumn(SUM);
    sumColumn.setCellRenderer(new MyFancyPriceRenderer());
  • Alright, this makes sense I think. So I can use this method in my table model to specify what individual cells are going to look like, and I can return, for example, a checkbox or a null component and get what I'm looking for? – nameless912 Jun 05 '13 at 18:04
  • In your custom cell renderer you would would check if the current cell index is the one you want to do something about, i.e. provide a `JCheckBox` as the cells render `Component` or an empty JLabel. I tend to write a install a simple but seperate cell render for each customized column. A little background: The table model only provides the data and manages modifications of that data (insert, update, delete). It is obviously :-) the "M" in MVC (Model-View-Controller). The JTable and the support classes are the View and Controller (V and C) which determine HOW the data should look like. – Jens Birger Hahn Jun 05 '13 at 18:26
  • Feel free to ask if you're done with the tutorial - I love Swing :-) – Jens Birger Hahn Jun 05 '13 at 18:27
  • Ah. So what I really should be doing now then is trying to take my `TableModel` and dump it into an extension of JTable where I can then override the `getTableCellRendererComponent` method and pass it components based on the location in the table. Does that sound right? As for loving Swing, mad props. I cannot stand it, I'm only using it because I have to for this project haha – nameless912 Jun 05 '13 at 18:33
  • Hi, you rarely need to extend JTable. JTable has a lot of customization options. I'm gonna add a little code example to my answer. – Jens Birger Hahn Jun 06 '13 at 08:25