tags:

views:

393

answers:

3

I have a JTable with two columns and both are JComboBox, for this purpose I implemented my own Model and overrode methods. One of the method which I overrode is:

public Class getColumnClass(int index) {
  return JComboBox.class;
}

Also created my own ComboBoxEditor and ComboBoxRender classes, and set cellEditor and cellRenderer:

column.setCellEditor(new ComboBoxEditor());
column.setCellRenderer(new ComboBoxRenderer());

Now I want to make changes, so that for column one some cells are JComboBox and some cells are standard textual data.

How can I achieve this ?

Any helpful suggestions would be welcome

+3  A: 

You need to implement your own javax.swing.table.TableCellRenderer, where return different renderers at getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) according to your business logic. The same for TableCellEditor Interface.

St.Shadow
I think the important point is that the "default" renderers use inappropriate inheritance.
Tom Hawtin - tackline
Yes, no sense in inheritance. Should be used pure composition of two renderers and return appropriate one whet it is needed.
St.Shadow
+2  A: 

I usually override the table.getCellEditor(...) method to return the appropriate editor.

Maybe something like this:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableComboBoxByRow extends JFrame
{
    ArrayList editors = new ArrayList(3);

    public TableComboBoxByRow()
    {
     // Create the editors to be used for each row

     String[] items1 = { "Red", "Blue", "Green" };
     JComboBox comboBox1 = new JComboBox( items1 );
     DefaultCellEditor dce1 = new DefaultCellEditor( comboBox1 );
     editors.add( dce1 );

     String[] items2 = { "Circle", "Square", "Triangle" };
     JComboBox comboBox2 = new JComboBox( items2 );
     DefaultCellEditor dce2 = new DefaultCellEditor( comboBox2 );
     editors.add( dce2 );

     String[] items3 = { "Apple", "Orange", "Banana" };
     JComboBox comboBox3 = new JComboBox( items3 );
     DefaultCellEditor dce3 = new DefaultCellEditor( comboBox3 );
     editors.add( dce3 );

     //  Create the table with default data

     Object[][] data =
     {
      {"Color", "Red"},
      {"Shape", "Square"},
      {"Fruit", "Banana"},
      {"Plain", "Text"}
     };
     String[] columnNames = {"Type","Value"};
     DefaultTableModel model = new DefaultTableModel(data, columnNames);
     JTable table = new JTable(model)
     {
      //  Determine editor to be used by row
      public TableCellEditor getCellEditor(int row, int column)
      {
       int modelColumn = convertColumnIndexToModel( column );

       if (modelColumn == 1 && row < 3)
        return (TableCellEditor)editors.get(row);
       else
        return super.getCellEditor(row, column);
      }
     };
     System.out.println(table.getCellEditor());

     JScrollPane scrollPane = new JScrollPane( table );
     getContentPane().add( scrollPane );
    }

    public static void main(String[] args)
    {
     TableComboBoxByRow frame = new TableComboBoxByRow();
     frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
     frame.pack();
     frame.setVisible(true);
    }
}
camickr
This was very helpful.
Milhous
A: 

You can use instanceof. Usage:

Object o = new String("Test");
if (o instanceof String)
{
   String s = (String) o;
   // Do something with the string
}

So, make the data-matrix for your JTable like this Object[][] data = new Object[...][...].
Ent then can you use instanceof in your DefaultTableCellRenderer to check if the Object is a String or a JComboBox. Depending on that result, render like a String or a JComboBox.

Martijn Courteaux