Hello good day. Thank you for trying to help.

My problem is as follows. A few columns in my table, use a JComboBox as the editor for their cells. Each cell, in a row (via JComboBox) presents the same choices to the user. The user is allowed to choose from the options, just not the same option more than once for that row.

That being said what I wish to accopmlish is this: Whenever selections are made from any JComboBox the next cells should present as options the remaining unselected choices.

So basically whenever a particular choice is made, I want that option to disappear from the other JComboBox editors.

(I have thought about checking what the value is in the JComboBox, creating another JComboBox using the remaining choices, then setting that JComboBox as the new table cell editor; but there's got to be a simpler solution).

May I please ask, how do I go about doing this please?

Recommended Answers

All 23 Replies

Sounds tricky, but here's my first thought. Add a listener to the combo boxes. When a value is selected from one of them, retrieve a list of the other combo boxes from that row. A custom table model can help with that. You don't need to create a new JComboBox, only update their list of data. You can remove the selected item from the other boxes. Do all the rows contain the same items in the JComboBox? Because then it would be easy to keep a master list to help with the updates.

There's probably a better way but that's my idea.

@Phaelax JTable (standard way) doesn't contains any JComboBox, this is painting illusion made by XxxTableCellRenderer/Editor, in the XxxTableModel is stored initial value for Renderer/Editor

@CoilFyzx

  • use MutableComboBoxModel (is designated for any changes at runtime), could be possible with DefaultComboBox,

  • there no issue to set separate XxxComboBoxModel for each of JComboBoxes used as XxxTableCellEditor,

  • override setValueAt, after fireTableCellUpdated to remove selected Item in temporary array used for concrete row (only one array for one row), then rest of cells have got prepared XxxComboBoxModel (last question was about AbstractTableModel, if is possible to use DefaultTableModel, every notifiers are implemented and correctly)

  • note your logics must calculating with option to reset value (add Item back to underlaying array) to switch between various Items for all of JComboBoxes (used as XxxTableCellEditor) in concrete row

  • wrap editor.setModel(XxxComboBoxModel) into invokeLater (moving this event to the end of EDT)

EDIT

  • I'm sure that this logics is very good descibed in blogs/posts (active on severals forums) by aterai, kleopatra or camickr, they are very active, with excelent skills about JTable, and described in English language :-) ...

thank you very much for your suggestions: the trouble I am having is this. How do I go about accessing the Model for each cell's JComboBox? The reason I ask this, is because I used the same JComboBox to create the DefaultCellEditor for each row. So is there a way to get the cell editor then get the model for that editor and then remove the item please?

  • there could be only one XxxTableCellEditor for JComboBox, I think, quite sure that for whole JTables view, current JVM, almost every Swing JComponets are based on models, they have got own model, then everything is about how to manage, set, get data from/to model

  • with access to underlaing array for XxxComboBoxModel e.g by @camickr, see answer by @trashgod too, this is code for forum, without good practicies

  • arrays for every row to put to the Map, HashMap (note those two arrays haven't indexing, you must to create this index), then better is to use util.List

I believe that we're not communicating clearly.

Here is where I am:

public String[] tableColumns={"Name","Class","Gender","Shift","Total Choices","A","B","C","D","E","F1","F2","G"};
public Object[][]nullData={{"","","","",0,"","","","","","","",""}};
DefaultTableModel tableModel=new DefaultTableModel(nullData,tableColumns);
TableDWModel tModel=new TableDWModel();
JTable table=new JTable(tModel);



public String[] theSubs={"Biology","Additional Mathematics","Geography",
"History","Spanish","Information Technology","Technical Drawing",
"French","Physics","Chemistry","Principles of Accounts",
"Principles of Business","Art","Economics"};

MutableComboBoxModel subCBXmod=new DefaultComboBoxModel(theSubs);
JComboBox studentComboBox=new JComboBox(subCBXmod);

//In my constructor. I have this step.

public SpreadsheetProgram() throws SQLException
{
    for(int i=5;i<13;i++)
    {
        TableColumn aCol=table.getColumnModel().getColumn(i);
        aCol.setCellEditor(new DefaultCellEditor(studentComboBox));   
    }
}

This code obviously makes all the cells from fifth column onwards editable using JcomboBox's. Now what I want to do is this: when a cell in a particular row is filled with a choice from the JComboBox editor, I wish for that option to be removed from all the other cell's JComboBox editors for that row while all the other cells not in that row maintain all their choices. How do I accomplish this please? Please ask for clarification if my question is not clear. Thank you.

The "How to use JTables" Oracle tutorial shows how yto set a different renderer for any cell of the table (briefly: subclass JTable and override public getCellRenderer(int row, int column).
http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#renderer

Now each cell has its own renderer and each renderer can have its own underlying data. Updating the data is going to be a bit tedious to code, but nothing specially difficult.

OR (just to confuse things even more)

Go with Oracle's published strategy and implement your new GUI in JavaFX instead of Swing. The JavaFX table is far better at custyomising cells.
http://www.oracle.com/technetwork/java/javafx/overview/faq-1446554.html#6

How would this help me to change the contents of the JComboBox's?
Because isn't it true that I need to change the Model if I am to change the data?

Each cell has its own renderer, which is a JComboBox, which has its own list of data to populate its values. It's those lists of data you need to update for your stated requirement. The TableModel isn't going to help when each cell has a list of values associated with it.

Okay thank you. However let me please ask: How do I access this data within the cellRenderer based on my current setup?

Can I get a guide of thought please?

Based on your current setup? I don't know. I would start with something simple like adding each renderer to a 2D array at the same time that I add it to the Table. That allows me to access (eg) all the renderers (and their associated data) in the same row etc.
I have to admit that I'm just making this up as I go. I simply don't have time to think it right through and build a test example. If I were doing this myself I'd start with something (see above), hack some skeleton code together and see how it works out. I wouldn't hesitate tp scrap it and start again if it turns out not work well.

No no. I don't expect you to give me code.

Maybe I'm not understanding something again.

What I did was create one JComboBox as shown in my code, then used it to set DefaultCellEditor's for my table. That is my setup.

So it was with this setup in mind that I asked you the essence of the following: With what I just coded are you saying that each cell now possesses it's data?

Data which be can be accessed via the cellrenderer? i.e. the TableCellRenderer?

It's a combo box. It must have access to its list of values!

I'm sorry if I'm annoying you, but I can't understand how to do this, or where to put this code.

All I have is a table with JComboBoxes as DefaultCellEditors, nothing else. No Renderers or anything like that. That is all I have.

The JComboBoxes do not have renderers. My table though does have one-to change the color of the cells. That is all.

Where should I go from here please. Do I create renderers for the JComboBoxes? I am not sure where to start from and what to do.

I don't desire code, just insight.

Sorry.my mistake, I meant editors, not renderers.

Are you referring to what you said here?

Based on your current setup? I don't know. I would start with something simple like adding each renderer to a 2D array at the same time that I add it to the Table. That allows me to access (eg) all the renderers (and their associated data) in the same row etc.I have to admit that I'm just making this up as I go. I simply don't have time to think it right through and build a test example. If I were doing this myself I'd start with something (see above), hack some skeleton code together and see how it works out. I wouldn't hesitate tp scrap it and start again if it turns out not work well.

And since you mean editor, aren't editors column specific instead of cell specific?

No no. I don't expect you to give me code. ---> I don't want to comment this sentence somehow, we are volunteers ...

Maybe I'm not understanding something again. ---> yes (you have to understand how it works and its lifecycle, notifiers and events) JTable, XxxTableModel and underlaying array (if model isn't defined then change to the underlaying array isn't possible, programatically accesible), search for AbstractTableModel based on util.List (forgot about HashMap, road to hell in your case), again one XxxCellEditor with JComboBox as local variable (don't wrote extends JComboBox, because this.whatever can be misspeled so easilly) and list of arrays for Default/MutableComboModel added in XxxCellEditor to JComboBox used as TableCellEditor

@JamesCherrill Sorry.my mistake, I meant editors, not renderers. ---> doesn't matter your direction is correct, logics is very similair and both are only painting illusion, not real JComponent

aren't editors column specific instead of cell specific?

It comes down to JTable's getCellEditor(int row, int column). Subclass JTable, override that method, and you have cell-specific editors

Thank you sir.

It comes down to JTable's getCellEditor(int row, int column). Subclass JTable, override that method, and you have cell-specific editors

  • disagree, wrong, never to subclass JTable for Renderer/Editor, but true is that required in the case there if is used prepareRenderer/prepareEditor,

  • it doesn't works in the (most of) case(s) that RowFilter/Sorter is applied for (btw by default everytime for harcoded coordinates, meaning row&column index) JTables view,

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.