0

Here's the idea: Let's say I have a class extending TableModel, with something like a List<List<String>> collection field. On an event, I want to clear out a JTable and re-add rows where one specific column is a combo box; the items in combo box n are the items in the List<String> from collection.get(n) in my list. So I'm iterating over collection adding rows, and I'm iterating over each collection.get(n) adding combo box items.

There are no event listeners. When a separate button is clicked I can work out what needs to happen as long as I can getSelectedIndex on each combo box.

I have spent two and a half hours turning my GUI into code spaghetti where I've extended virtually everything and I have maximum coupling on practically everything. I think I might even have two disjoint collections of JComboBox instances. I say this to stress that it would do absolutely no good for me to post any code I currently have.

I have read the oracle tutorial on JTable, all of these that strangely don't have an explanation I can understand.

So basically I just need an idea of what I need, because I'm not getting anywhere with the resources I've found.

Community
  • 1
  • 1
Mr. Wallet
  • 17
  • 4
  • 1
    First of all, the TableModel is used to model the data that is meant to be viewed, so don't worry about trying to get the combo box or combos values into that. Instead, establish a TableCellEditor and pass it the List>. When ever a cell is edited, the table will want the editor component, it will pass the row and column indexes. Simple prepare ComboBoxModel, based on the values you need for the row, and seed that to the editor – MadProgrammer Oct 23 '13 at 08:16

1 Answers1

1

So, basically, you need a TableCelLEditor that is capable of seeding a JComboBox with the rows from the available list, for example...

enter image description here

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;

public class TableCellEditor {

    public static void main(String[] args) {
        new TableCellEditor();
    }

    public TableCellEditor() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                List<List<String>> values = new ArrayList<>(25);
                for (int row = 0; row < 10; row++) {

                    List<String> rowValues = new ArrayList<>(25);
                    for (int index = 0; index < 10; index++) {
                        rowValues.add("Value " + index + " for row " + row);
                    }
                    values.add(rowValues);

                }

                DefaultTableModel model = new DefaultTableModel(new Object[]{"Data"}, 10);
                JTable table = new JTable(model);
                table.setShowGrid(true);
                table.setGridColor(Color.GRAY);
                table.getColumnModel().getColumn(0).setCellEditor(new MyEditor(values));

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class MyEditor extends DefaultCellEditor {

        private List<List<String>> rowValues;

        public MyEditor(List<List<String>> rowValues) {
            super(new JComboBox());
            this.rowValues = rowValues;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {

            JComboBox cb = (JComboBox) getComponent();
            List<String> values = rowValues.get(row);
            DefaultComboBoxModel model = new DefaultComboBoxModel(values.toArray(new String[values.size()]));
            cb.setModel(model);

            return super.getTableCellEditorComponent(table, value, isSelected, row, column);

        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thanks for the quick and clear response! I don't have the rating to upvote, sadly. I don't have any more errors and deleted about 80% of the related code that wasn't actually doing anything, and now I'm stuck again: The column is just displaying the toString of each list, and doesn't respond to the mouse. I don't know if I need to do something with rendering or what. – Mr. Wallet Oct 23 '13 at 18:54
  • Take a look at [How to use tables](http://docs.oracle.com/javase/tutorial/uiswing/components/table.html), look for the custom rendering section. It's possible that the table model's `isCellEditable` is returning false, meaning that the cells are not editable. If you continue to have problems, the best choice is to post another question with what you have – MadProgrammer Oct 23 '13 at 19:28