Thursday, January 28, 2010

Table and actions.

If you have been developing client software you certainly already ran into the following situation:
You have a table full of data, each line corresponding to an object you can interact with. Where and how should I put buttons for this purpose?

I will explore several implementations in order to handle this situation.

Cell editors/renderers


This way is often seen to handle this situation, you have to add one column per action, and then the button will appear on each line thanks to a cell renderer/editor.
I don’t find it really appealing visually, because repeating the same button over and over again on each line seems wrong to me, but at least it’s easy to see that the action on the button will be applied to the selected row.
Adding columns + most likely increasing the row height (to display properly an icon) are a waste of space if you don’t have so much of it at first.

I know by experience that developers that do not understand swing correctly (well, that’s a nice 99% of the people I worked with) tend to fail miserably at writing cell renderer/editor, is why I tried not to advice people to use custom cell editor/renderer.



Buttons outside the table

It’s possible to add buttons somewhere on the screen that will do something related to the selected row in the table, that’s the easiest solution. The main problem of this implementation is that buttons are actually outside the table and hence that the buttons are not yet directly linked to the selected row, it might confuse the user.



Popup menu

Right click on the table to show a popup menu
This one is also an easy solution.
The main drawback of this solution is that at first the user has no idea there is actions available on the selected row via a popup menu



Overlay buttons

So far the main drawbacks of the above solutions are: buttons not directly linked to the selected row, popup not visible at first, repeating the same button again and again.
So why not try to come with a solution that will meet the following requirement:
Only one button per action visible at the same time, linked to the selected row.
Let’s have a look at the outside button way. What was is main problem? The buttons are not linked to the selected row. So how would it be possible to link it?

The solution I came up with is to use a JLayeredPane to position the buttons next to the selected row: here




Mixed approach

What happen now if there are more than 2 actions, so 2+ buttons.
The cell renderer approach will need more even more column, so even more space wasted.
The button overlay approach will also need some space to show the button, and the furthest button will not seems so much connected to the selected row

Only the popup approach is behaving well in this case, but at the same time it’s not user friendly as the possibility to see the popup is not explicit.

(I am not talking about the buttons outside the table way because I consider it not user friendly, because of how unrelated are the buttons with the table)


So why not mixed the popup approach with the 2 others?

Popup + cell renderer/editor / Popup + overlay button
The principle is the same in both approach, that is, to show a button that say “click me to see the popup” and put it either as a cell renderer or as an overlay button.









You can find all the above implementations here

web start demo:


8 comments:

  1. Did you ever think about toolbar with actions, related to a table. It can be on the side or on top of the table. Actions for toolbar and context menu can be generated at the same time.

    ReplyDelete
  2. Or multiple icons (buttons) in one cell...

    ReplyDelete
  3. eryzhikov, i indeed didn't think about it, but for me it's a bit like the outside buttons i talked about, it's actually buttons that are outisde, they may be in a toolbar but still they are not directly link to the jtable, or did i get your idea wrong ?



    tbee, it can be done indeed with multiple buttons in on cell, i hesitated to talk about it but as it is really close to the cell renderer approach i discribed( you will still have icons in every row) i didn't

    ReplyDelete
  4. Basically your preferred solution has multiple buttons in a row, only you need to click on the one to show them.

    And about the renderer approach; I have an extended JTable that simply has a default renderer installed for Actions. I can easily be extended to render a list-of-actions.

    The actions normally are provided to the table by the TableModel, which is debatable from a MVC standpoint, but it is quite simple to extend the JTable a bit more to include a special row-actions property and automatically add that as the last column.

    This is where I would go.

    ReplyDelete
  5. Kleopatra (Jeanette) really would like to comment, but for some reason she can't (devine intervention? ;-), but IF she were able to, she would say:

    [Kleopatra]
    naturally, I wanted to throw SwingX' JXTable into the ring - add custom actions to the ColumnControl menu in the upper trailing corner
    [/Kleopatra]

    ReplyDelete
  6. By the way, the advantage of having the buttons outside the table is that one action can apply to multiple rows. Especially for delete this can be very practical.

    ReplyDelete
  7. @tbee: that is exactly what I meant to say :)

    ReplyDelete
  8. there is no best solution , it depends on the applcation and what you need to do. At work i didn't need to perform an action on multiple row like delete, so i used the overlay buttons that was fitting the need pretty well

    @tbee adding action to the model is an option i didn't thought about, but it make sense if done correctly, i even find it really interresting, it's something i will investigate one day i guess

    ReplyDelete