3

I tried hard to find a better title for this ticket but that was the best I could come up with.

I am having an issue with a JComboBox inside of a JTable. The program is a very scaled down version of the original. It pulls data from a database and puts that info into a combobox. When the data is pulled from the db it will overwrite the field. When the data is entered from a varible the issue is not present. I thought maybe that the small ammount of delay from the db was the issue, so I added some delay. I went all the way up to 20 seconds but still did not get the same results. There is a variable named DB. Set that to true and it will pull data from the db and false will use the local variable.

With the DB true go down to the last record and click in it, then just click once in the above fields. They were all 2 but now they are 1. Do the same thing but set the last field to 100 and follow the above steps. Then all records will be 100. This is not the expected behavior. The field should stay the same unless the user changes the value. With DB false it will operate as expected. I have tried all sorts of things to isolate the issue. The fact the original data comes from a db should not matter, it is just a string. There is another issue that I think is related to this same problem. If a field is blank opening the combo will overwrite the fieled and not allow the field to be cleared again.

I have prepared a jar file here, it has all of the source code and the db file. I'm not sure if there is a better way to attach the jar file. You will need to extract the code from the jar file, it will not work otherwise.

Here is the source code:

import java.io.*;
import java.lang.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.swing.table.*;
import java.util.ArrayList;
import java.util.Iterator;

public class ErrorDemo {
    private String[][] comm = new String[3][6];
    private int index = 0;
    private JTable table;
    private DefaultTableModel myData;
    public String headers[] = new String[35];
    private boolean DB = true;
    // private boolean DB = false;

    public ErrorDemo () {
        Visual();
        StartQuery();
    }

    public void Visual () {
        final JFrame frame = new JFrame( "Automation" );
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setVisible( true );

        myData = new DefaultTableModel();
        table = new JTable(  );
        table.setModel( myData );
        table.setFillsViewportHeight(true);

        JScrollPane scroll1 = new JScrollPane(table);
        scroll1.setVisible( true );
        frame.add(scroll1);

        frame.repaint();
        frame.setVisible( true );
    }

    public void StartQuery () {
        // set the data to be placed into the fields
        index = 2;
        headers[1] = "Feild 1";
        headers[2] = "Feild 2";
        comm[1][1] = "aaaaaaaaaaaaaaaa2";
        comm[1][2] = "aaaaaaaaaaaaaaaa2";
        comm[1][3] = "aaaaaaaaaaaaaaaa2";
        comm[1][4] = "aaaaaaaaaaaaaaaa2";
        comm[1][5] = "aaaaaaaaaaaaaaaa2";
        comm[2][1] = "aaaaaaaaaaaaaaaa2";
        comm[2][2] = "aaaaaaaaaaaaaaaa2";
        comm[2][3] = "aaaaaaaaaaaaaaaa2";
        comm[2][4] = "aaaaaaaaaaaaaaaa2";
        comm[2][5] = "aaaaaaaaaaaaaaaa2";

        //set the name of the headers
        for ( int i = 1 ; i <= index ; i++ ) 
            myData.addColumn( headers[i] );
        //place the data into the table
        Vector v = new Vector();
        for ( int i = 1; i <= 5; i++ ) {
            v = new Vector();
            v.addElement( comm[1][i] );
            v.addElement( comm[2][i] );
            myData.addRow( v );
        }

        //place the data into the combo box then place the combo box into the table
        TableColumn Column1 = table.getColumnModel().getColumn( 0 );
        JComboBox comboBox = new JComboBox();
        String[] output = new String[61];
        // if DB is true it pulls the data from the the database else it will use a static string.
        if ( DB ) {
            String comm1 = "SELECT data FROM Table1 ORDER BY data; ";
            // change the following path to where ever to put it.
            DBDemo dbl1 = new DBDemo( "U:/Users/Goff/java/rcc automation/GreatBeyond/db1.accdb" );
            dbl1.GetQuery( comm1, 1, comboBox );
        } else {
            // gofflib STL = new gofflib();
            // STL.sleeper( 20000 ); //a test to see if adding delay would produce the issue, it did not.
            output = new String [] { "", "aaaaaaaaaaaaaaaa1", "aaaaaaaaaaaaaaaa2", "aaaaaaaaaaaaaaaa3", "aaaaaaaaaaaaaaaa4", "aaaaaaaaaaaaaaaa5", "aaaaaaaaaaaaaaaa6", "aaaaaaaaaaaaaaaa7", "aaaaaaaaaaaaaaaa8", "aaaaaaaaaaaaaaaa9", "aaaaaaaaaaaaaaaa10", "aaaaaaaaaaaaaaaa11", "aaaaaaaaaaaaaaaa12", "aaaaaaaaaaaaaaaa13", "aaaaaaaaaaaaaaaa14", "aaaaaaaaaaaaaaaa15", "aaaaaaaaaaaaaaaa16", "aaaaaaaaaaaaaaaa17", "aaaaaaaaaaaaaaaa18", "aaaaaaaaaaaaaaaa19", "aaaaaaaaaaaaaaaa20", "aaaaaaaaaaaaaaaa21", "aaaaaaaaaaaaaaaa22", "aaaaaaaaaaaaaaaa23", "aaaaaaaaaaaaaaaa24", "aaaaaaaaaaaaaaaa25", "aaaaaaaaaaaaaaaa26", "aaaaaaaaaaaaaaaa27", "aaaaaaaaaaaaaaaa28", "aaaaaaaaaaaaaaaa29", "aaaaaaaaaaaaaaaa30", "aaaaaaaaaaaaaaaa31", "aaaaaaaaaaaaaaaa32", "aaaaaaaaaaaaaaaa33", "aaaaaaaaaaaaaaaa34", "aaaaaaaaaaaaaaaa35", "aaaaaaaaaaaaaaaa36", "aaaaaaaaaaaaaaaa37", "aaaaaaaaaaaaaaaa38", "aaaaaaaaaaaaaaaa39", "aaaaaaaaaaaaaaaa40", "aaaaaaaaaaaaaaaa41", "aaaaaaaaaaaaaaaa42", "aaaaaaaaaaaaaaaa43", "aaaaaaaaaaaaaaaa44", "aaaaaaaaaaaaaaaa45", "aaaaaaaaaaaaaaaa46", "aaaaaaaaaaaaaaaa47", "aaaaaaaaaaaaaaaa48", "aaaaaaaaaaaaaaaa49", "aaaaaaaaaaaaaaaa50", "aaaaaaaaaaaaaaaa51", "aaaaaaaaaaaaaaaa52", "aaaaaaaaaaaaaaaa53", "aaaaaaaaaaaaaaaa54", "aaaaaaaaaaaaaaaa55", "aaaaaaaaaaaaaaaa56", "aaaaaaaaaaaaaaaa57", "aaaaaaaaaaaaaaaa58", "aaaaaaaaaaaaaaaa59", "aaaaaaaaaaaaaaaa60", "aaaaaaaaaaaaaaaa61", "aaaaaaaaaaaaaaaa62", "aaaaaaaaaaaaaaaa63", "aaaaaaaaaaaaaaaa64", "aaaaaaaaaaaaaaaa65", "aaaaaaaaaaaaaaaa66", "aaaaaaaaaaaaaaaa67", "aaaaaaaaaaaaaaaa68", "aaaaaaaaaaaaaaaa69", "aaaaaaaaaaaaaaaa70", "aaaaaaaaaaaaaaaa71", "aaaaaaaaaaaaaaaa72", "aaaaaaaaaaaaaaaa73", "aaaaaaaaaaaaaaaa74", "aaaaaaaaaaaaaaaa75", "aaaaaaaaaaaaaaaa76", "aaaaaaaaaaaaaaaa77", "aaaaaaaaaaaaaaaa78", "aaaaaaaaaaaaaaaa79", "aaaaaaaaaaaaaaaa80", "aaaaaaaaaaaaaaaa81", "aaaaaaaaaaaaaaaa82", "aaaaaaaaaaaaaaaa83", "aaaaaaaaaaaaaaaa84", "aaaaaaaaaaaaaaaa85", "aaaaaaaaaaaaaaaa86", "aaaaaaaaaaaaaaaa87", "aaaaaaaaaaaaaaaa88", "aaaaaaaaaaaaaaaa89", "aaaaaaaaaaaaaaaa90", "aaaaaaaaaaaaaaaa91", "aaaaaaaaaaaaaaaa92", "aaaaaaaaaaaaaaaa93", "aaaaaaaaaaaaaaaa94", "aaaaaaaaaaaaaaaa95", "aaaaaaaaaaaaaaaa96", "aaaaaaaaaaaaaaaa97", "aaaaaaaaaaaaaaaa98", "aaaaaaaaaaaaaaaa99", "aaaaaaaaaaaaaaaa100" };
            for ( int i = 1; i <= 100; i++ ) {
                comboBox.addItem( output[i] );
            }
        }
        Column1.setCellEditor(new DefaultCellEditor(comboBox));

        table.repaint();
        table.revalidate();
    }

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

Here is DBDemo

import java.sql.*;
import net.ucanaccess.jdbc.JackcessOpenerInterface;
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
import net.ucanaccess.converters.TypesMap.AccessType;
import net.ucanaccess.ext.FunctionType;
import net.ucanaccess.jdbc.UcanaccessConnection;
import net.ucanaccess.jdbc.UcanaccessDriver;
import org.apache.commons.lang.builder.*;
import org.apache.commons.logging.*;
import org.hsqldb.jdbc.*;
import java.util.*;
import javax.swing.table.*;
import javax.swing.*;

public class DBDemo {
    private Connection con;
    private Statement st;
    private ResultSet rs;
    private String db;
    private String comm = "";
    private int index = 0;
    private String Path = "";

    public DBDemo ( String arg1 ) {
        Path = arg1;
    }

    public void GetQuery ( String comm, int index, JComboBox comb ) {
        try {
            String output = "";
            String path = new java.io.File(Path).getAbsolutePath();
            db = "jdbc:ucanaccess://" + path;
            Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
            con = DriverManager.getConnection(db);
            st = con.createStatement();
            output = "";
            rs = st.executeQuery( comm );
            while (rs.next()) {
                for ( int i = 1; i <= index; i++ ) {
                    Object o = rs.getObject(i);
                    String t;
                    t = ( o == null ? "" : o.toString() );
                    output += t + " ";
                }
                comb.addItem( output );
                output = "";
            }
            rs.close();
            st.close();
            con.close();
        } catch( NullPointerException | SQLException | ClassNotFoundException ex ){
            ex.printStackTrace();
        }
    }
}

I have tried to make the code as concise as possible.

With DB = true or DB = false, either processes the same data into a string and then puts it into the combo box. How could this elicit different behavior?

UPDATE: here is the new code that uses a custom cell renderer.

import java.io.*;
import java.lang.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import javax.swing.table.*;
import java.util.ArrayList;
import java.util.Iterator;

public class ErrorDemo {
    private String[][] comm = new String[3][6];
    private int index = 0;
    private JTable table;
    private DefaultTableModel myData;
    public String headers[] = new String[35];
    private boolean DB = true;
    // private boolean DB = false;

    public ErrorDemo () {
        Visual();
        StartQuery();
    }

    public void Visual () {
        final JFrame frame = new JFrame( "Automation" );
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setVisible( true );

        myData = new DefaultTableModel();
        table = new JTable(  );
        table.setModel( myData );
        table.setFillsViewportHeight(true);

        JScrollPane scroll1 = new JScrollPane(table);
        scroll1.setVisible( true );
        frame.add(scroll1);

        frame.repaint();
        frame.setVisible( true );
    }

    public void StartQuery () {
        // set the data to be placed into the fields
        index = 2;
        headers[1] = "Feild 1";
        headers[2] = "Feild 2";
        comm[1][1] = "aaaaaaaaaaaaaaaa2";
        comm[1][2] = "aaaaaaaaaaaaaaaa2";
        comm[1][3] = "aaaaaaaaaaaaaaaa2";
        comm[1][4] = "aaaaaaaaaaaaaaaa2";
        comm[1][5] = "aaaaaaaaaaaaaaaa2";
        comm[2][1] = "aaaaaaaaaaaaaaaa2";
        comm[2][2] = "aaaaaaaaaaaaaaaa2";
        comm[2][3] = "aaaaaaaaaaaaaaaa2";
        comm[2][4] = "aaaaaaaaaaaaaaaa2";
        comm[2][5] = "aaaaaaaaaaaaaaaa2";

        //set the name of the headers
        for ( int i = 1 ; i <= index ; i++ ) 
            myData.addColumn( headers[i] );
        //place the data into the table
        Vector v = new Vector();
        for ( int i = 1; i <= 5; i++ ) {
            v = new Vector();
            v.addElement( comm[1][i] );
            v.addElement( comm[2][i] );
            myData.addRow( v );
        }

        //place the data into the combo box then place the combo box into the table
        TableColumn Column1 = table.getColumnModel().getColumn( 0 );
        // JComboBox comboBox = new JComboBox();
        MyComboBoxRenderer comboBox = new MyComboBoxRenderer();
        String[] output = new String[61];
        // if DB is true it pulls the data from the the database else it will use a static string.
        if ( DB ) {
            String comm1 = "SELECT data FROM Table1 ORDER BY data; ";
            // change the following path to where ever to put it.
            DBDemo dbl1 = new DBDemo( "U:/Users/Goff/java/rcc automation/GreatBeyond/db1.accdb" );
            dbl1.GetQuery( comm1, 1, comboBox );
        } else {
            gofflib STL = new gofflib();
            // STL.sleeper( 20000 ); //a test to see if adding delay would produce the issue, it did not.
            output = new String [] { "", "aaaaaaaaaaaaaaaa1", "aaaaaaaaaaaaaaaa2", "aaaaaaaaaaaaaaaa3", "aaaaaaaaaaaaaaaa4", "aaaaaaaaaaaaaaaa5", "aaaaaaaaaaaaaaaa6", "aaaaaaaaaaaaaaaa7", "aaaaaaaaaaaaaaaa8", "aaaaaaaaaaaaaaaa9", "aaaaaaaaaaaaaaaa10", "aaaaaaaaaaaaaaaa11", "aaaaaaaaaaaaaaaa12", "aaaaaaaaaaaaaaaa13", "aaaaaaaaaaaaaaaa14", "aaaaaaaaaaaaaaaa15", "aaaaaaaaaaaaaaaa16", "aaaaaaaaaaaaaaaa17", "aaaaaaaaaaaaaaaa18", "aaaaaaaaaaaaaaaa19", "aaaaaaaaaaaaaaaa20", "aaaaaaaaaaaaaaaa21", "aaaaaaaaaaaaaaaa22", "aaaaaaaaaaaaaaaa23", "aaaaaaaaaaaaaaaa24", "aaaaaaaaaaaaaaaa25", "aaaaaaaaaaaaaaaa26", "aaaaaaaaaaaaaaaa27", "aaaaaaaaaaaaaaaa28", "aaaaaaaaaaaaaaaa29", "aaaaaaaaaaaaaaaa30", "aaaaaaaaaaaaaaaa31", "aaaaaaaaaaaaaaaa32", "aaaaaaaaaaaaaaaa33", "aaaaaaaaaaaaaaaa34", "aaaaaaaaaaaaaaaa35", "aaaaaaaaaaaaaaaa36", "aaaaaaaaaaaaaaaa37", "aaaaaaaaaaaaaaaa38", "aaaaaaaaaaaaaaaa39", "aaaaaaaaaaaaaaaa40", "aaaaaaaaaaaaaaaa41", "aaaaaaaaaaaaaaaa42", "aaaaaaaaaaaaaaaa43", "aaaaaaaaaaaaaaaa44", "aaaaaaaaaaaaaaaa45", "aaaaaaaaaaaaaaaa46", "aaaaaaaaaaaaaaaa47", "aaaaaaaaaaaaaaaa48", "aaaaaaaaaaaaaaaa49", "aaaaaaaaaaaaaaaa50", "aaaaaaaaaaaaaaaa51", "aaaaaaaaaaaaaaaa52", "aaaaaaaaaaaaaaaa53", "aaaaaaaaaaaaaaaa54", "aaaaaaaaaaaaaaaa55", "aaaaaaaaaaaaaaaa56", "aaaaaaaaaaaaaaaa57", "aaaaaaaaaaaaaaaa58", "aaaaaaaaaaaaaaaa59", "aaaaaaaaaaaaaaaa60", "aaaaaaaaaaaaaaaa61", "aaaaaaaaaaaaaaaa62", "aaaaaaaaaaaaaaaa63", "aaaaaaaaaaaaaaaa64", "aaaaaaaaaaaaaaaa65", "aaaaaaaaaaaaaaaa66", "aaaaaaaaaaaaaaaa67", "aaaaaaaaaaaaaaaa68", "aaaaaaaaaaaaaaaa69", "aaaaaaaaaaaaaaaa70", "aaaaaaaaaaaaaaaa71", "aaaaaaaaaaaaaaaa72", "aaaaaaaaaaaaaaaa73", "aaaaaaaaaaaaaaaa74", "aaaaaaaaaaaaaaaa75", "aaaaaaaaaaaaaaaa76", "aaaaaaaaaaaaaaaa77", "aaaaaaaaaaaaaaaa78", "aaaaaaaaaaaaaaaa79", "aaaaaaaaaaaaaaaa80", "aaaaaaaaaaaaaaaa81", "aaaaaaaaaaaaaaaa82", "aaaaaaaaaaaaaaaa83", "aaaaaaaaaaaaaaaa84", "aaaaaaaaaaaaaaaa85", "aaaaaaaaaaaaaaaa86", "aaaaaaaaaaaaaaaa87", "aaaaaaaaaaaaaaaa88", "aaaaaaaaaaaaaaaa89", "aaaaaaaaaaaaaaaa90", "aaaaaaaaaaaaaaaa91", "aaaaaaaaaaaaaaaa92", "aaaaaaaaaaaaaaaa93", "aaaaaaaaaaaaaaaa94", "aaaaaaaaaaaaaaaa95", "aaaaaaaaaaaaaaaa96", "aaaaaaaaaaaaaaaa97", "aaaaaaaaaaaaaaaa98", "aaaaaaaaaaaaaaaa99", "aaaaaaaaaaaaaaaa100" };
            for ( int i = 1; i <= 100; i++ ) {
                comboBox.addItem( output[i] );
            }
        }
        // Column1.setCellEditor(new DefaultCellEditor(comboBox));
        Column1.setCellEditor( new MyComboBoxEditor(comboBox) );
        // Column1.setCellRenderer(new DefaultTableCellRenderer());
        Column1.setCellRenderer( comboBox );

        table.repaint();
        table.revalidate();
    }

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

class MyComboBoxRenderer extends JComboBox implements TableCellRenderer {
  // public MyComboBoxRenderer(String[] items) {
  public MyComboBoxRenderer() {
    // super(items);
  }

  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    if (isSelected) {
      setForeground(table.getSelectionForeground());
      super.setBackground(table.getSelectionBackground());
    } else {
      setForeground(table.getForeground());
      setBackground(table.getBackground());
    }
    setSelectedItem(value);
    return this;
  }
}

class MyComboBoxEditor extends DefaultCellEditor {
    // public MyComboBoxEditor(String[] items) {
    public MyComboBoxEditor( JComboBox items ) {
    // public MyComboBoxEditor( MyComboBoxRenderer items ) {
        // super(new JComboBox(items));
        super( items );
    }
}

With the new code and DB = true, the field is overwritten when it is finished loading. I can see it start off as "aaaaaaaaaaaaaaaa2" then when the drop down button appears it changes to "aaaaaaaaaaaaaaaa1". If I change the value of one and then click in another box and another then those boxes are now the same as the first.

With the new code and DB = false, the initail value stays the same but when I change one field and click into another it is overwritten.

Goff
  • 173
  • 1
  • 2
  • 12
  • I copied your code into my Eclipse. DBDemo & gofflib are missing. Java class names should start with a capital letter. JComboBoxes and Vector should have a declared parameter type. – Gilbert Le Blanc Sep 26 '16 at 20:07
  • The DBDemo was in the source jar file, I have added it to this post. I meant to comment out the gofflib line. Sorry about that. – Goff Sep 26 '16 at 20:28
  • I copied your code into my Eclipse. I did get a GUI to come up this time. When I click on each of the JComboBoxes, there are no selections in the combo box. When I select nothing, nothing replaces the text in the table field. I don't see the problem with the GUI. The idea is that you create code for your question that I can copy into my Eclipse and run, without having to create a Java project or any other modifications./ – Gilbert Le Blanc Sep 28 '16 at 19:50
  • did you make DB true or false? Did you have the DB file in the same directory? did you change the path to the DB file to represent you file structure? – Goff Sep 28 '16 at 20:34
  • I downloaded, compiled and ran your code (with adaptation to use my own MySQL database). Yes, I actually used a DB since without one I couldn't reproduce the problem. Turns out I still can't, even with a DB. From looking at the code, I strongly suspect that the issue is not really the DB, but something you do differently between the two test cases. I would expect the described behaviour from a table model where each cell references the same object. Could it be that what you describe is based on a slightly different version? e.g. where input to the table model is handled differently? – Markus Fischer Sep 28 '16 at 21:06
  • @MarkusFischer I can only agree with you that the DB and type of DB should be irrelivant but when I change the boolean to false it works properly. You used a MySQL DB and I have a MS Access DB but that should also not make any problems due to the fact that we are just passing the combo box a string. Sorry for the long reply, the enterprise has been pushing updates and my computer barely works. – Goff Sep 29 '16 at 19:21
  • Possible duplicate of [JComboBox as a Custom TableCellEditor](http://stackoverflow.com/questions/7601436/jcombobox-as-a-custom-tablecelleditor) – roeygol Sep 30 '16 at 10:03
  • @RoeyGolzarpoor I don't think this is the problem, I may be wrong of course. I think the problem is more related to the initialization of the JComboBox. I think the reason it over writes the existing data is because A) the combo box is not set to the current value B) the combo box may be treated as a static object and that is why it is it sets the current field to the last value. Do you think I am close to that? I tried to implement that code but it still overwrites the field. – Goff Sep 30 '16 at 20:07

1 Answers1

0

Try looking at this example:

import java.awt.Component;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    DefaultTableModel model = (DefaultTableModel) table.getModel();

    model.addColumn("A", new Object[] { "item1" });
    model.addColumn("B", new Object[] { "item2" });

    String[] values = new String[] { "1", "2", "3" };

    TableColumn col = table.getColumnModel().getColumn(0);
    col.setCellEditor(new MyComboBoxEditor(values));
    col.setCellRenderer(new MyComboBoxRenderer(values));
  }
}

class MyComboBoxRenderer extends JComboBox implements TableCellRenderer {
  public MyComboBoxRenderer(String[] items) {
    super(items);
  }

  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    if (isSelected) {
      setForeground(table.getSelectionForeground());
      super.setBackground(table.getSelectionBackground());
    } else {
      setForeground(table.getForeground());
      setBackground(table.getBackground());
    }
    setSelectedItem(value);
    return this;
  }
}

class MyComboBoxEditor extends DefaultCellEditor {
  public MyComboBoxEditor(String[] items) {
    super(new JComboBox(items));
  }
}

What you really need is to use TableCellRenderer as which uses the JComboBox inside the JTable.

roeygol
  • 6,664
  • 6
  • 43
  • 75
  • I have implemented the code as you suggested, with a couple of minor chages to fit into my existing code. What we see now is the value of the field is immediately changed to some other value, and it still overwrites the value when the bottom row is changed then clicking on the above rows. I'm afraid this has not fixed the problem. I will update the code in the post to reflect the changes. – Goff Sep 29 '16 at 19:23
  • I think that I found what you need at: http://stackoverflow.com/questions/7601436/jcombobox-as-a-custom-tablecelleditor – roeygol Sep 30 '16 at 10:03
  • Column1.setCellRenderer( new MyComboBoxRenderer () ); broke the functionality of the combobox. Only the last combo box gets the drop down. none of the other boxes get a drop down. =( – Goff Sep 30 '16 at 20:58