6

In Swing is possible to create a JComboBox in a JTable, as seen by this guide from Oracle. They have a lovely picture that shows this in action:

enter image description here

However, what the fail to show is that if you haven't clicked on the cell, the dropdown arrows are not visible and it just looks like a normal text label, as seen below:

enter image description here

You can see that knitting has dropdown arrows because I just clicked on it, but the other ones don't. This is sadly less than ideal because there are no visual cues that the cell can be clicked on to show a list of options. In other words, the "Sport" column looks identical to the "Last Name" column. One of them is a dropdown, the other is not, but they visually look the same unless you happen to click on one of them.

Is there any way that this can be done in Swing?

EDIT: To clarify, what I want is for ALL the cells in the "Sport" column to have arrows indicating a dropdown menu, even if they were not the least one clicked. Basically, I want it to look like a combo box whether I've clicked on it or not.

Thunderforge
  • 19,637
  • 18
  • 83
  • 130
  • This is default behaviour of a `JTable`, the rendering and editing are two different states. Personally, you really don't want to clutter the UI with things that don't need to be there...but that's me... – MadProgrammer Jun 29 '14 at 05:56
  • 1
    @MadProgrammer, there are certainly use cases where a dropdown on a JTable might be useful, as the example from Oracle above shows. The problem is that you don't know that the option is there because there are no visual clues until you click on it. – Thunderforge Jun 29 '14 at 05:57
  • You're missing the point. Each cell in the `Sport` column IS backed by a combo box when in edit mode. When rendered, they simply appears as "text" – MadProgrammer Jun 29 '14 at 06:00
  • @MadProgrammer, I'm aware that it simply appears as "text" when not in edit mode and a combo box when in edit mode. What I want is for it to appear as a combo box in both. – Thunderforge Jun 29 '14 at 06:03
  • IMHO, I think you're asking for trouble, but what do I know ;) – MadProgrammer Jun 29 '14 at 06:10
  • See also the custom renderers shown in this possible [duplicate](http://stackoverflow.com/q/17342917/230513). – trashgod Jun 29 '14 at 11:55

2 Answers2

6

I'm not sure you understand the distintion between "renderer" and "edit" modes in the JTable. All the cells in the Sport column in your example are backed by a combobox, when in edit mode.

What I believe you're trying to do is something like...

Example

Which will clutter the UI (IMHO)

So based on the example from here, I modified the code to change the default cell renderer for the Sport column

public void setUpSportColumn(JTable table,
                TableColumn sportColumn) {
    //Set up the editor for the sport cells.
    JComboBox comboBox = new JComboBox();
    DefaultComboBoxModel model = new DefaultComboBoxModel();
    model.addElement("Snowboarding");
    model.addElement("Rowing");
    model.addElement("Knitting");
    model.addElement("Speed reading");
    model.addElement("Pool");
    model.addElement("None of the above");
    comboBox.setModel(model);
    sportColumn.setCellEditor(new DefaultCellEditor(comboBox));

    model = new DefaultComboBoxModel();
    model.addElement("Snowboarding");
    model.addElement("Rowing");
    model.addElement("Knitting");
    model.addElement("Speed reading");
    model.addElement("Pool");
    model.addElement("None of the above");
    //Set up tool tips for the sport cells.
    ComboBoxTableCellRenderer renderer
                    = new ComboBoxTableCellRenderer();
    renderer.setModel(model);
    sportColumn.setCellRenderer(renderer);
}

And added this...

public class ComboBoxTableCellRenderer extends JComboBox implements TableCellRenderer {

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        setSelectedItem(value);
        return this;
    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 3
    Do you think the GUI would still look cluttered if the row height was increased? – Jake Chasan Jun 29 '14 at 06:11
  • This is just my personal opinion, so you'll need to make your own decisions, but yes...What might make it better is removing the border from the combobox to "open" it up a little. I'll have a play and see what I can accomplish – MadProgrammer Jun 29 '14 at 06:14
  • Thanks for your opinion about ui. If it were not displayed like this, how would they a user edit it? I am thinking: a button that says "edit" on the right of a read-only table, and if it is clicked, then an editor opens only for that row. Do you agree that the ui would be simpler? (in theory) – Jake Chasan Jun 29 '14 at 06:17
  • Editing happens automatically. A combination of the `Table#isCellEditable` and `TableCellEditor#isCellEditable` work together, when they both return `true`, the cell becomes editable...The other consideration (with row height) is the difference between platforms, you would need to devise some means by which you could calculate a suitable height for these rows at run time – MadProgrammer Jun 29 '14 at 06:25
  • Thanks! Once I figured out that the last two lines of your example got cut off of the code block, I was able to get it to work. Fixing the indent didn't hit the character limit for an edit, so I couldn't fix it. Perhaps in order to reach the character limit, you could add some comments to point out which lines you added? Also, is there a reason that the model was recreated a second time? – Thunderforge Jun 29 '14 at 06:32
  • Sorry, didn't notice, fixed now – MadProgrammer Jun 29 '14 at 06:54
  • The model was created twice because it maintains information about the selected item so it was messing up the editor and renderer, I would have preferred to keep as one, but that was the limitaiton – MadProgrammer Jun 29 '14 at 06:55
-1

First of all, you may want to check this out: how to add checkbox and combobox in table cell?

In your example, I am thinking that this may be due to the fact that there is not enough height to display the GUI. What I mean is that the Swing components automatically resize to fill their container, and if the container height is too small, then it may not display the GUI correctly.

Here are images to illustrate my example (I used Windows XP):

Initial Launch: enter image description here

Click on Cell:

enter image description here

After Cell Click:

enter image description here

Community
  • 1
  • 1
Jake Chasan
  • 6,290
  • 9
  • 44
  • 90
  • I have updated my answer with images to illustrate my point about the resizable Swing Components. – Jake Chasan Jun 29 '14 at 05:41
  • Thanks for your answer. Unfortunately, it seems I wasn't as clear in what I was looking for. The problem I'm having is that Rowing, Knitting, Speed reading, etc. don't have a dropdown arrow visible; just Snowboarding in your last two pictures. I've edited my question to clarify this. – Thunderforge Jun 29 '14 at 05:50
  • The arrows only appear next to the last drop-down item that the user selected. I think this is a way of Swing trying to show the user a "history" of their last action. Is there any way you can increase the height of the rows and test it again? (the reason I ask, is because the word "Snowboarding" is cut off at the bottom leading me to think the ComboBox does not have enough room to display properly) – Jake Chasan Jun 29 '14 at 05:53
  • `JComboBox` uses a basic `Window` as the popup, so it shouldn't care about the size of the frame, as the popup should be able to extend beyond the the scope of the window – MadProgrammer Jun 29 '14 at 05:55
  • @MadProgrammer: I don't think the question is talking about the contents of the drop-down, I think it is talking about the UI of the combo box displaying before the user clicks it, letting the user know that it is a combo box. – Jake Chasan Jun 29 '14 at 05:56
  • I've confirmed that changing the height of the rows does not make arrows appear on cells that the user has not yet clicked. Only on the one that they have last clicked. – Thunderforge Jun 29 '14 at 05:56
  • I have 2 ideas: You could append an image of an up Arrow and a Down arrow next to the right side of the column? (that way you can be sure that the arrows appear) You could create a new JPanel within the table cell, and place the ComboBox within the new panel (making sure it has plenty of height above and below it). Do any of these options work? – Jake Chasan Jun 29 '14 at 06:00
  • Ok: I have just come to the conclusion that with the DefaultCellEditor, this is the way the ComboBoxes are displayed, as it has a special constructor for combo boxes, text fields, and check boxes. Your best bet may be to create a custom cell editor and renderer. Check this out for more info: http://stackoverflow.com/questions/11858286/how-to-use-custom-jtable-cell-editor-and-cell-renderer Does this help? – Jake Chasan Jun 29 '14 at 06:08
  • There was another answer posted which adds a custom renderer to your application. – Jake Chasan Jun 29 '14 at 06:10