5

I am trying to make a column in a JXTable to be a combo box. Its difficult to explain the problem I am facing. When you click on the drop down, at times the drop down does not stay open long enough for you to choose the value. It just closes and some value is chosen. At times it stays open for you to choose a value. Here's the SSCCE:

import java.awt.Color;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.table.DefaultTableModel;

import org.jdesktop.swingx.JXFrame;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.renderer.CellContext;
import org.jdesktop.swingx.renderer.ComponentProvider;
import org.jdesktop.swingx.renderer.DefaultTableRenderer;

public class Test {

    public static void main(String[] args) {
        JXFrame frame=new JXFrame();
        Object[][] rows = new Object[10][];

        for (int i = 0; i < rows.length; i++) {
        rows[i] = new Object[]{
        "Test data ","Yes"};
        }

        DefaultTableModel model = new DefaultTableModel(rows,
        new String[]{
        "Title 1", "Title 2"
        });

        final JXTable table = new JXTable(model);
        DefaultComboBoxModel cmodel = new DefaultComboBoxModel(new String[] {"Yes","No","Maybe"});
        table.getColumnExt(1).setCellRenderer(new DefaultTableRenderer(new ComboBoxProvider(cmodel)));
        table.getColumnExt(1).setCellEditor(new ComboBoxEditor(cmodel));
        table.setVisibleRowCount(10);
    frame.setContentPane(table);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
        frame.setVisible(true);
    }
}

class ComboBoxEditor extends DefaultCellEditor {
    public ComboBoxEditor(ComboBoxModel model) {
        super(new JComboBox(model));
    }
}

class ComboBoxProvider extends ComponentProvider<JComboBox> {
    private static final long serialVersionUID = 1L;
    private JComboBox box;
    public ComboBoxProvider(ComboBoxModel model){
        box.setModel(model);
    }
    @Override
    protected void configureState(CellContext context) {
        box.setForeground(Color.black);
    }
    @Override
    protected JComboBox createRendererComponent() {
        box = new JComboBox();
        box.setForeground(Color.black);
        return box;
    }
    @Override
    protected void format(CellContext context) {
        box.setForeground(Color.black);
        rendererComponent.setSelectedItem(context.getValue());
    }
}
michel.iamit
  • 5,788
  • 9
  • 55
  • 74
sethu
  • 8,181
  • 7
  • 39
  • 65
  • Can you replicate the problem with `JTable`? – Andrew Thompson Feb 03 '12 at 06:35
  • 3
    @AndrewThompson yeah, same issue. Not a solution, just a (unrelated) beware: don't use the same instance of the comboBoxModel in both the renderer and the editor - the editor is permanently listening to the model which may lead to weird effects, maybe even corrupting the data – kleopatra Feb 03 '12 at 07:10
  • Hmm ... looks like a variant of one of the oldest bugs in Swing (don't have the id, too lazy to search in the notoriously sluggish bug parade) which I thought was fixed: happens with the a core JTable, core default (label) renderer and core default comboEditor - on first click into the cell, the popup is sometimes shown and sometimes not shown (though table always in editing state, afaics) – kleopatra Feb 03 '12 at 07:28
  • Thanks kleopatra. After made the renderer and editor to have their own models, the problem was solved. – sethu Feb 03 '12 at 07:28
  • ahh .. so that was your main concern :-) You don't mind the not-opening-on-first-click-always? – kleopatra Feb 03 '12 at 07:44
  • I couldnt get 'not-opening-on-first-click-always' to occur on my code yet. Tried it about 20 times now. So i am hoping its fixed.. maybe? – sethu Feb 03 '12 at 07:53
  • Actually I see the 3 'greats' answering here.. Thought I'll just share. I am actually working on a swing framework. Its not yet done. But hope to complete it soon. Its hosted here: http://code.google.com/p/swingobjects/. Check the class test.CompTest for a small teaser on how to use it. As I said its still not complete, need to connect many dots yet. – sethu Feb 03 '12 at 07:57
  • @sethu please post an answer and mark it as valid – Yves Martin Mar 24 '12 at 02:10

1 Answers1

1

To solve this issues make sure you dont share the same instance of the DefaultComboxBoxModel for the editor and renderer.. So instead of this:

DefaultComboBoxModel cmodel = new DefaultComboBoxModel(new String[] {"Yes","No","Maybe"});
    table.getColumnExt(1).setCellRenderer(new DefaultTableRenderer(new ComboBoxProvider(cmodel)));
    table.getColumnExt(1).setCellEditor(new ComboBoxEditor(cmodel));

Do this:

    table.getColumnExt(1).setCellRenderer(new DefaultTableRenderer(new ComboBoxProvider(
             new DefaultComboBoxModel(new String[] {"Yes","No","Maybe"}))));
    table.getColumnExt(1).setCellEditor(new ComboBoxEditor(
            new DefaultComboBoxModel(new String[] {"Yes","No","Maybe"})));
sethu
  • 8,181
  • 7
  • 39
  • 65