How to Add Unique Jcomboboxes to a Column in a Jtable (Java)

How to add unique JComboBoxes to a column in a JTable (Java)

Override the getCellEditor(...) method. For example;

import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;

public class TableComboBoxByRow extends JFrame
{
List<TableCellEditor> editors = new ArrayList<TableCellEditor>(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 editors.get(row);
else
return super.getCellEditor(row, column);
}
};

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);
}
}

For one column of a JTable, how do I put a unique combo box editor in each row?

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

Sample Image

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);

}

}

}

how to add different JComboBox items in a Column of a JTable in Swing

example on java2s.com looks like as works and correctly, then for example (I harcoded JComboBoxes for quick example, and add/change for todays Swing)

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.table.*;

public class EachRowEditorExample extends JFrame {

private static final long serialVersionUID = 1L;

public EachRowEditorExample() {
super("EachRow Editor Example");
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
System.out.println(info.getName());
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (UnsupportedLookAndFeelException e) {
// handle exception
} catch (ClassNotFoundException e) {
// handle exception
} catch (InstantiationException e) {
// handle exception
} catch (IllegalAccessException e) {
// handle exception
}
DefaultTableModel dm = new DefaultTableModel();
dm.setDataVector(new Object[][]{{"Name", "MyName"}, {"Gender", "Male"}, {"Color", "Fruit"}}, new Object[]{"Column1", "Column2"});
JTable table = new JTable(dm);
table.setRowHeight(20);
JComboBox comboBox = new JComboBox();
comboBox.addItem("Male");
comboBox.addItem("Female");
comboBox.addComponentListener(new ComponentAdapter() {

@Override
public void componentShown(ComponentEvent e) {
final JComponent c = (JComponent) e.getSource();
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
c.requestFocus();
System.out.println(c);
if (c instanceof JComboBox) {
System.out.println("a");
}
}
});
}
});

JComboBox comboBox1 = new JComboBox();
comboBox1.addItem("Name");
comboBox1.addItem("MyName");
comboBox1.addComponentListener(new ComponentAdapter() {

@Override
public void componentShown(ComponentEvent e) {
final JComponent c = (JComponent) e.getSource();
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
c.requestFocus();
System.out.println(c);
if (c instanceof JComboBox) {
System.out.println("a");
}
}
});
}
});

JComboBox comboBox2 = new JComboBox();
comboBox2.addItem("Banana");
comboBox2.addItem("Apple");
comboBox2.addComponentListener(new ComponentAdapter() {

@Override
public void componentShown(ComponentEvent e) {
final JComponent c = (JComponent) e.getSource();
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
c.requestFocus();
System.out.println(c);
if (c instanceof JComboBox) {
System.out.println("a");
}
}
});
}
});
EachRowEditor rowEditor = new EachRowEditor(table);
rowEditor.setEditorAt(0, new DefaultCellEditor(comboBox1));
rowEditor.setEditorAt(1, new DefaultCellEditor(comboBox));
rowEditor.setEditorAt(2, new DefaultCellEditor(comboBox2));
table.getColumn("Column2").setCellEditor(rowEditor);
JScrollPane scroll = new JScrollPane(table);
getContentPane().add(scroll, BorderLayout.CENTER);
setPreferredSize(new Dimension(400, 120));
setLocation(150, 100);
pack();
setVisible(true);
}

public static void main(String[] args) {
EachRowEditorExample frame = new EachRowEditorExample();
frame.addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}

just add EachRowEditor Class

JTable - Different ComboBox for each cell in column

Main part of this sample program is the use of custom cell editor EpisodeEditor. It dynamically decides the "episodes" based on the "series" selected in first column.

(I have used a mock data source for this demonstration.)

import javax.swing.*;
import javax.swing.table.TableCellEditor;
import java.util.*;

public class ComboBoxTable
{
public static void main(String[] args)
{
// Mock data source
DataSource dataSource = new DataSource();

JComboBox<String> seriesComboBox = new JComboBox<>();
for (String s : dataSource.getSeries())
{
seriesComboBox.addItem(s);
}

JTable table = new JTable(
new String[][] {{"", ""}, {"", ""}, {"", ""}},
new String[] {"Series", "Episode"});
table.getColumn("Series").setCellEditor(new DefaultCellEditor(seriesComboBox));
table.getColumn("Episode").setCellEditor(new EpisodeEditor(dataSource));

JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JScrollPane(table));
f.setBounds(300, 200, 400, 300);
f.setVisible(true);
}
}

class EpisodeEditor extends AbstractCellEditor implements TableCellEditor
{
private DataSource dataSource;
private JComboBox<String> episodesComboBox = new JComboBox<>();

EpisodeEditor(DataSource dataSource)
{
this.dataSource = dataSource;
}

@Override
public java.awt.Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
int row, int column)
{
String series = (String) table.getModel().getValueAt(row, 0);

List<String> episodes = dataSource.getEpisodes(series);
episodesComboBox.removeAllItems();
for (String ep : episodes)
{
episodesComboBox.addItem(ep);
}
episodesComboBox.setSelectedItem(value);
return episodesComboBox;
}

@Override
public Object getCellEditorValue()
{
return episodesComboBox.getSelectedItem();
}
}

class DataSource
{
List<String> getSeries()
{
return Arrays.asList("Prison Break", "Breaking Bad", "Pokemon");
}

List<String> getEpisodes(String series)
{
switch (series)
{
case "Prison Break":
return Arrays.asList("Break 1", "Break 2", "Break 3");
case "Breaking Bad":
return Arrays.asList("Bad 1", "Bad 2", "Bad 3");
case "Pokemon":
return Arrays.asList("P1", "P2", "P3");
default:
throw new IllegalArgumentException("Invalid series: " + series);
}
}
}

Add different combobox for each row of a column in a jtable

Render both the columns.

TableColumn comboCol1 = table.getColumnModel().getColumn(0);
TableColumn comboCol2 = table.getColumnModel().getColumn(1);
comboCol1.setCellEditor(new CustomComboBoxEditor());
comboCol2.setCellEditor(new CustomComboBoxEditor());

// This is for 2nd Column which depends on the first column selection.

public class CustomComboBoxEditor extends DefaultCellEditor {

// Declare a model that is used for adding the elements to the `ComboBox`
private DefaultComboBoxModel model;

public CustomComboBoxEditor() {
super(new JComboBox());
this.model = (DefaultComboBoxModel)((JComboBox)getComponent()).getModel();
}

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

if(column == 0) {
// Just show the elements in the JComboBox.
} else {

// Remove previous elements every time.
// So that we can populate the elements based on the selection.
model.removeAllElements();

// getValueAt(..) method will give you the selection that is set for column one.
String selectedItem = table.getValueAt(row, 0);

// Using the obtained selected item from the first column JComboBox
// selection make a call ans get the list of elements.

// Say we have list of data from the call we made.
// So loop through the list and add them to the model like the following.
for(int i = 0; i < obtainedList.size(); i++) {
model.addElement(obtainedList.get(i));
}
} // Close else

// finally return the component.
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
}

Custom Combo box in JTable wont set the selected option

This approach will only override the getTableCellEditorComponent(...) method of the DefaultCellEditor to reset the model of the combo box based on a value in the current row that is being edited.

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

public class StateCellEditor extends DefaultCellEditor
{
private int lookupColumn;
private HashMap<Object, DefaultComboBoxModel<?>> map;

public StateCellEditor(JComboBox<?> comboBox, int lookColumn, HashMap<Object, DefaultComboBoxModel<?>> map)
{
super(comboBox);
this.lookupColumn = lookupColumn;
this.map = map;
}

@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
Component c = super.getTableCellEditorComponent(table, value, isSelected, row, column);

JComboBox<?> comboBox = (JComboBox<?>)c;

Object lookup = table.getModel().getValueAt(row, lookupColumn);
DefaultComboBoxModel model = map.get( lookup );
comboBox.setModel( model );

return comboBox;
}

private static void createAndShowUI()
{
HashMap<Object, DefaultComboBoxModel<?>> map = new HashMap<>();
map.put("Color", new DefaultComboBoxModel<Object>( new String[]{ "Red", "Blue", "Green" } ));
map.put("Shape", new DefaultComboBoxModel<Object>( new String[]{ "Circle", "Square", "Triangle" } ));
map.put("Fruit", new DefaultComboBoxModel<Object>( new String[]{ "Apple", "Orange", "Banana" } ));

JPanel panel = new JPanel( new BorderLayout() );
panel.setLayout( new BorderLayout() );

// Create the table with default data

Object[][] data =
{
{"Color", "Red"},
{"Shape", "Square"},
{"Fruit", "Banana"}
};
String[] columnNames = {"Type","Value"};

DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable(model);
DefaultCellEditor dce = new StateCellEditor(new JComboBox<Object>(), 0, map);
table.getColumnModel().getColumn(1).setCellEditor(dce);

JScrollPane scrollPane = new JScrollPane( table );
panel.add( scrollPane );

JFrame frame = new JFrame("Table Combo Box by Row");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel, BorderLayout.CENTER);
frame.setSize(200, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}

public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}


Related Topics



Leave a reply



Submit