How to put different JComboBox in each row of JTable dinamically - java

I would like to create a JTable in my application.
The table will contain two coumns, the first is the name of a software module.
The second column needs to contain a JComboBox with the revision numbers of the software module in the first column.
Is it even possible or I need to find another way to do this? (For example: put a button to the cell and choose the revision from a popup window)
Thank you in advance!

Here is one possible implementation to use a DefaultComboBoxModel<Integer> as the table column's data type:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class EditableComboCellEditorTest {
private JComponent makeUI() {
String[] columnNames = {"version", "revision"};
Object[][] data = {
{"1.7.0", makeModel(76, 79, 80)},
{"1.8.0", makeModel(91, 92, 101, 102)},
};
TableModel model = new DefaultTableModel(data, columnNames) {
#Override public Class<?> getColumnClass(int column) {
return column == 1 ? DefaultComboBoxModel.class : String.class;
}
};
JTable table = new JTable(model);
table.setRowHeight(32);
table.setAutoCreateRowSorter(true);
TableColumn col = table.getColumnModel().getColumn(1);
col.setCellRenderer(new ComboCellRenderer());
col.setCellEditor(new ComboCellEditor());
return new JScrollPane(table);
}
private static DefaultComboBoxModel<Integer> makeModel(Integer... items) {
return new DefaultComboBoxModel<Integer>(items) {
#Override public String toString() {
return Objects.toString(getSelectedItem(), "");
}
};
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new EditableComboCellEditorTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class ComboCellRenderer implements TableCellRenderer {
private final JPanel p = new JPanel(new GridBagLayout());
private final JComboBox<Integer> cb = new JComboBox<>();
#Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
p.removeAll();
p.setOpaque(false);
p.add(cb);
cb.setEditable(true);
cb.removeAllItems();
if (value instanceof DefaultComboBoxModel) {
DefaultComboBoxModel m = (DefaultComboBoxModel) value;
Object o = m.getSelectedItem();
if (o instanceof Integer) {
cb.addItem((Integer) o);
}
}
return p;
}
}
//https://java-swing-tips.blogspot.jp/2016/08/use-editable-jcombobox-as.html
class ComboCellEditor extends AbstractCellEditor implements TableCellEditor {
private final JPanel p = new JPanel(new GridBagLayout());
private final JComboBox<Integer> cb = new JComboBox<>();
protected ComboCellEditor() {
super();
cb.setEditable(true);
cb.addActionListener(e -> fireEditingStopped());
p.add(cb);
p.setOpaque(false);
}
#Override public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
if (value instanceof ComboBoxModel) {
#SuppressWarnings("unchecked")
ComboBoxModel<Integer> m = (ComboBoxModel<Integer>) value;
cb.setModel(m);
}
return p;
}
#Override public Object getCellEditorValue() {
#SuppressWarnings("unchecked")
DefaultComboBoxModel<Integer> m = (DefaultComboBoxModel<Integer>) cb.getModel();
if (cb.isEditable()) {
Object o = cb.getEditor().getItem();
if (o instanceof Integer && m.getIndexOf((Integer) o) < 0) {
Integer value = (Integer) o;
int n = m.getSize();
Vector<Integer> list = new Vector<>(n + 1);
for (int i = 0; i < n; i++) {
list.add(m.getElementAt(i));
}
list.add(value);
Collections.sort(list);
m = new DefaultComboBoxModel<Integer>(list);
cb.setModel(m);
cb.setSelectedIndex(m.getIndexOf(value));
}
}
return m;
}
}

Override the getCellEditor(...) method to return the combo box:
import java.awt.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class TableComboBoxByRow extends JPanel
{
List<String[]> editorData = new ArrayList<String[]>(3);
public TableComboBoxByRow()
{
setLayout( new BorderLayout() );
// Create the editorData to be used for each row
editorData.add( new String[]{ "Red", "Blue", "Green" } );
editorData.add( new String[]{ "Circle", "Square", "Triangle" } );
editorData.add( new String[]{ "Apple", "Orange", "Banana" } );
// 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)
{
JComboBox<String> comboBox1 = new JComboBox<String>( editorData.get(row));
return new DefaultCellEditor( comboBox1 );
}
else
return super.getCellEditor(row, column);
}
};
JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
// table.getColumnModel().getColumn(1).setCellRenderer(new ComboBoxRenderer2() );
}
/*
class ComboBoxRenderer2 extends DefaultTableCellRenderer
{
#Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
label.setIcon(UIManager.getIcon("Table.descendingSortIcon"));
return label;
}
}
*/
private static void createAndShowUI()
{
JFrame frame = new JFrame("Table Combo Box by Row");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TableComboBoxByRow() );
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

How to make single cell from a given column as drop down in JTable

I have a drop down and simple text field in my JTable and based on the specific value selected in the drop down, I want to change the text field to drop down as well.
Below is the code which I am using for the same and I am able to convert the text field to drop down based on the selection but the problem is that it convert all the text fields in the column to drop down. I just want to change the selected row to drop down, rest should remain as text field.
comboBox2.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent arg0) {
String properties = (String) comboBox2.getSelectedItem();
try {
switch (properties) {
case "Choose Object":
dd_OR = table.getColumnModel().getColumn(3);
model1 = new DefaultComboBoxModel<String>();
model1.addElement("");
model1.addElement("Snowboarding");
model1.addElement("Rowing");
model1.addElement("Knitting");
JComboBox comboBox3 = new JComboBox<String>(model1);
AutoCompleteDecorator.decorate(comboBox3);
dd_OR.setCellEditor(new DefaultCellEditor(comboBox3));
break;
}
One way is to override the getCellEditor(...) method of the JTable so you can dynamically determine which editor to use.
Here is a simple example to get your started:
import java.awt.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.table.*;
public class TableComboBoxByRow extends JPanel
{
List<String[]> editorData = new ArrayList<String[]>(3);
public TableComboBoxByRow()
{
setLayout( new BorderLayout() );
// Create the editorData to be used for each row
editorData.add( new String[]{ "Red", "Blue", "Green" } );
editorData.add( new String[]{ "Circle", "Square", "Triangle" } );
editorData.add( new String[]{ "Apple", "Orange", "Banana" } );
// 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)
{
JComboBox<String> comboBox1 = new JComboBox<String>( editorData.get(row));
return new DefaultCellEditor( comboBox1 );
}
else
return super.getCellEditor(row, column);
}
};
JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
// table.getColumnModel().getColumn(1).setCellRenderer(new ComboBoxRenderer2() );
}
/*
class ComboBoxRenderer2 extends DefaultTableCellRenderer
{
#Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
label.setIcon(UIManager.getIcon("Table.descendingSortIcon"));
return label;
}
}
*/
private static void createAndShowUI()
{
JFrame frame = new JFrame("Table Combo Box by Row");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TableComboBoxByRow() );
frame.setSize(200, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Setting the cell Editor to DefaultCellEditor will apply to all the rows in the column 3. Please your above code like in given below
TableColumn column = table.getColumnModel().getColumn(3);
column.setCellEditor(new CustomTableCellEditor());
And the CustomTableEditor will be
import java.awt.Component;
import javax.swing.AbstractCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;
public class CustomTableCellEditor extends AbstractCellEditor implements TableCellEditor {
/**
*
*/
private static final long serialVersionUID = -6924557080981304281L;
private JComboBox<String> editor;
private String [] values = {"","Snowboarding", "Rowing", "Knitting"};
public CustomTableCellEditor() {
// Create a new Combobox with the array of values.
editor = new JComboBox<String>(values);
}
#Override
public Object getCellEditorValue() {
// TODO Auto-generated method stub
return editor.getSelectedItem();
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int rowIndex, int colIndex) {
// Set the model data of the table
if(isSelected)
{
// Do Whatever you want
}
return editor;
}
}
Hope it will help you
Thanks
Rajkumar

JTable with different JComboBox-es for each row

I created JTable that contains information about employees. In this JTable I added the column called "Qualifications". This column is represented by JComboBox (different content at each row). For instance:
Row 1 | JComboBox(){"Programmer","Web"}
Row 2 | JComboBox(){"Writer","Editor"}
The JComboBox content is taken from the List<String> employees[row].getQualification().
The problem is that the selected item in Row 1 and Row 2 is "Programmer", however "Programmer" should not appear in Row 2. Only when I click on JComboBox, the correct list appears, i.e. Row 2 - {"Writer","Editor"}.
TableColumn column = table.getColumnModel().getColumn(5);
column.setCellRenderer(getRenderer());
private TableCellRenderer getRenderer() {
return new TableCellRenderer() {
private JComboBox<String> box = new JComboBox<String>();
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
for (String q : employees[row].getQualification())
box.addItem(q);
box.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
box.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
return box;
}
};
}
Override the getCellEditor() method of the JTable. Something like:
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 JPanel
{
List<TableCellEditor> editors = new ArrayList<TableCellEditor>(3);
public TableComboBoxByRow()
{
setLayout( new BorderLayout() );
// Create the editors to be used for each row
String[] items1 = { "Red", "Blue", "Green" };
JComboBox<String> comboBox1 = new JComboBox<String>( items1 );
DefaultCellEditor dce1 = new DefaultCellEditor( comboBox1 );
editors.add( dce1 );
String[] items2 = { "Circle", "Square", "Triangle" };
JComboBox<String> comboBox2 = new JComboBox<String>( items2 );
DefaultCellEditor dce2 = new DefaultCellEditor( comboBox2 );
editors.add( dce2 );
String[] items3 = { "Apple", "Orange", "Banana" };
JComboBox<String> comboBox3 = new JComboBox<String>( 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 );
add( scrollPane );
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("Table Combo Box by Row");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TableComboBoxByRow() );
frame.setSize(200, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
JComboBox-es appear only on a click
because you use them as CellEditor, which apper only when you edit cells. If you want to display your column cells as JComboBox everytime, you need to use TableCellRenderer, read about that. Here is simple example of JComboBox as renderer :
import java.awt.Component;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class TestFrame extends JFrame{
public TestFrame(){
init();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
private void init() {
JTable t = new JTable(3,3);
TableColumn column = t.getColumnModel().getColumn(2);
column.setCellRenderer(getRenderer());
add(new JScrollPane(t));
}
private TableCellRenderer getRenderer() {
return new TableCellRenderer() {
private JComboBox<String> box = new JComboBox<String>(new String[]{"1","2"});
#Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
box.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
box.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
return box;
}
};
}
public static void main(String... s){
new TestFrame();
}
}
Thanks to #alex2410, I cleaned up the code and wrapped it into a ComboTable class which should do the job for you. instantiate ComboTable class with a hashmap of each row values (the demo assumes 2 columns, but you can add more). Note MyMap.of is just a wrapper for java 9 Map.of since I was using Java 8 at that time. same for MyList.of
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.EventObject;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import rs.code.utils.MyList;
import rs.code.utils.MyMap;
public class Test extends JFrame
{
private static final long serialVersionUID = 1L;
public ComboTable table = new ComboTable(MyMap.of("Gender", MyList.of("male", "female"), "City", MyList.of("london", "bedord"), "orientation", MyList.of("left", "right")));
public Test()
{
super("EachRow Editor Example");
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)
{
Test frame = new Test();
frame.addWindowListener(new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent e)
{
System.out.println(frame.table.getSelectedValues().toString());
System.exit(0);
}
});
}
}
class ComboTable extends JTable
{
private static final long serialVersionUID = 1L;
protected Map<Integer, ComboCellEditor> editors = new LinkedHashMap<>();
public ComboTable(Map<String, List<String>> rows)
{
setModel(new DefaultTableModel(new String[] {"Attribute", "Value"}, rows.size()));
setRowHeight(20);
EachRowEditor rowEditor = new EachRowEditor(this);
int i = 0;
for(String key : rows.keySet())
{
getModel().setValueAt(key, i, 0);
editors.put(i++, new ComboCellEditor(createComboBox(rows.get(key))));
}
getColumn("Value").setCellEditor(rowEditor);
getColumn("Value").setCellRenderer(getRenderer());
}
public Map<Integer, ComboCellEditor> getEditors()
{
return editors;
}
public Map<String, String> getSelectedValues()
{
Map<String, String> values = new LinkedHashMap<>();
for(int i=0;i<getModel().getRowCount();i++)
{
values.put(getModel().getValueAt(i, 0).toString(), editors.get(i).getComboBox().getSelectedItem().toString());
}
return values;
}
private JComboBox<String> createComboBox(List<String> elements)
{
JComboBox<String> comboBox = new JComboBox<>();
for (String element : elements)
{
comboBox.addItem(element);
}
comboBox.setSelectedIndex(0);
comboBox.addComponentListener(new ComponentAdapter()
{
#Override
public void componentShown(ComponentEvent e)
{
final JComponent c = (JComponent) e.getSource();
SwingUtilities.invokeLater(new Runnable()
{
#SuppressWarnings("rawtypes")
#Override
public void run()
{
c.requestFocus();
System.out.println(c);
if (c instanceof JComboBox)
{
System.out.println(((JComboBox) c).getSelectedItem());
}
}
});
}
});
return comboBox;
}
private TableCellRenderer getRenderer()
{
return new TableCellRenderer()
{
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
editors.get(row).getComboBox().setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
editors.get(row).getComboBox().setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
return editors.get(row).getComboBox();
}
};
}
}
class ComboCellEditor extends DefaultCellEditor
{
private static final long serialVersionUID = 1L;
private final JComboBox<String> comboBox;
public ComboCellEditor(JComboBox<String> comboBox)
{
super(comboBox);
this.comboBox = comboBox;
}
public JComboBox<String> getComboBox()
{
return comboBox;
}
}
class EachRowEditor implements TableCellEditor
{
private TableCellEditor editor;
private final TableCellEditor defaultEditor;
private final ComboTable table;
public EachRowEditor(ComboTable table)
{
this.table = table;
defaultEditor = new DefaultCellEditor(new JTextField());
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
return editor.getTableCellEditorComponent(table, value, isSelected, row, column);
}
public Object getCellEditorValue()
{
return editor.getCellEditorValue();
}
public boolean stopCellEditing()
{
return editor.stopCellEditing();
}
public void cancelCellEditing()
{
editor.cancelCellEditing();
}
public boolean isCellEditable(EventObject anEvent)
{
selectEditor((MouseEvent) anEvent);
return editor.isCellEditable(anEvent);
}
public void addCellEditorListener(CellEditorListener l)
{
editor.addCellEditorListener(l);
}
public void removeCellEditorListener(CellEditorListener l)
{
editor.removeCellEditorListener(l);
}
public boolean shouldSelectCell(EventObject anEvent)
{
selectEditor((MouseEvent) anEvent);
return editor.shouldSelectCell(anEvent);
}
protected void selectEditor(MouseEvent e)
{
int row;
if (e == null)
{
row = table.getSelectionModel().getAnchorSelectionIndex();
}
else
{
row = table.rowAtPoint(e.getPoint());
}
editor = table.getEditors().get(row);
if (editor == null)
{
editor = defaultEditor;
}
}
}

JTable Rendering with checkbox

Is there anyone know how I can add a checkbox in this code:
String data[][]={
{"Apple","Banana","Mango"}, {"Apple","Banana","Mango"}, {"Apple","Banana","Mango"}
};
String column[]={"Fruits","Fruits","Fruits"};
table=new JTable(new DefaultTableModel(data, column)){
private Border outside = new MatteBorder(1, 0, 1, 0, Color.RED);
private Border inside = new EmptyBorder(0, 1, 0, 1);
private Border highlight = new CompoundBorder(outside, inside);
public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
{
Component c = super.prepareRenderer(renderer, row, column);
JComponent jc = (JComponent)c;
// Add a border to the selected row
if (isRowSelected(row))
jc.setBorder( highlight );
return c;
}
};
jScrollPane1.setViewportView(table);
I just want to add checkboxes so that if I check a checkbox it will highlight and all checked checkboxes will be highlighted. Thank You in advance for helping me!
Here is pseudo code, I found somewhere in my repository. Use it according to your use.
import java.awt.Color;
import java.awt.Component;
import javax.swing.*;
import javax.swing.table.*;
public class TableCheckBoxHighLight extends JFrame {
private static final long serialVersionUID = 1L;
private JTable table;
public TableCheckBoxHighLight() {
Object[] columnNames = { "Col1", "Col2", "Select" };
Object[][] data = {
{ "Item1", "123", false },
{ "Item2", "345", false },
{ "Item3", "678", false },
{ "Item4", "901", false }
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table = new JTable(model) {
private static final long serialVersionUID = 1L;
#SuppressWarnings("unchecked")
#Override
public Class getColumnClass(int column) {
switch (column) {
case 0:
return String.class;
case 1:
return String.class;
default:
return Boolean.class;
}
}
#Override
public Component prepareRenderer(TableCellRenderer renderer,
int row, int col) {
Component c = super.prepareRenderer(renderer, row, col);
int[] selCols = table.getSelectedColumns();
table.setSelectionBackground(Color.GREEN);
for (int i : selCols)
c.setBackground(Color.RED);
return c;
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TableCheckBoxHighLight frame = new TableCheckBoxHighLight();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
});
}
}

Setting a tooltip for a value from JComboBox's Items as CellEditor in JTable

I would like to set a tooltip value for the values in a custom combo box. Basically, my combobox contains a list of initials of people - when they hover over i want it to display the fullname of the person. My combo box is basically a cell/column of a JTable that has its own TableCellRenderer and DefaultCellEditor. The list is a JList (inner class within the model) - iv tried setting the 'setToolTipText' method directly but that doesnt seem to work.
Here is the code:
*Code within the JTable: *
public void setupUserCombo(Container container){
TableColumn col = getColumnModel().getColumn(3);
Set<ComboUser> values = new LinkedHashSet<ComboUser>();
ComboUser comboUser = new ComboUser(new User("Test User"));
values.add(comboUser);
col.setCellEditor(new MyComboBoxEditor((ComboUser[])values.toArray(new ComboUser[0])));
col.setCellRenderer(new MyComboBoxRenderer((ComboUser[])values.toArray(new ComboUser[0])));
repaint();
}
public class MyComboBoxRenderer extends JComboBox implements TableCellRenderer {
private static final long serialVersionUID = 1L;
public MyComboBoxRenderer(ComboUser[] items) {
super(items);
repaint();
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (value != null){
System.out.println("Setting tooltip");
((ComboUser)value).setToolTipText("TESTING!!");
}
setSelectedItem(value);
return this;
}
}
public class MyComboBoxEditor extends DefaultCellEditor {
private static final long serialVersionUID = 1L;
public MyComboBoxEditor(ComboUser[] items) {
super(new JComboBox(items));
}
}
*Subclass within the model: *
public class ComboUser extends JLabel{
private User user;
public ComboUser(User user){
if (user != null){
this.user = user;
} else {
this.user = new User("");
}
}
#Override
public String toString() {
return user.getInitials();
}
If you want tooltips in the editing combobox, you'll have to so in a custom renderer of that combobox. Below is a short example:
// some data
User[] users = new User[] {
new User("Clara Zetkin", "CZ"),
new User("Rosa Luxemburg", "RL"),
new User("Susan Sontag", "SS"),
};
// the renderer for use in the editor
ListCellRenderer comboRenderer = new DefaultListCellRenderer() {
#Override
public Component getListCellRendererComponent(JList<?> list,
Object value, int index, boolean isSelected,
boolean cellHasFocus) {
if (value instanceof User) {
setToolTipText(((User) value).getName());
value = ((User) value).getInitials();
} else {
setToolTipText(null);
}
return super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
}
};
JComboBox editingCombo = new JComboBox(users);
editingCombo.setRenderer(comboRenderer);
JTable table = new JTable(3, 2);
// set up the editor for the first column
table.getColumnModel().getColumn(0).setCellEditor(new DefaultCellEditor(editingCombo));
// the renderer to use in the table
TableCellRenderer renderer = new DefaultTableCellRenderer() {
#Override
protected void setValue(Object value) {
if (value instanceof User) {
setToolTipText(((User) value).getInitials());
value = ((User) value).getName();
} else {
setToolTipText(null);
}
super.setValue(value);
}
};
table.getColumnModel().getColumn(0).setCellRenderer(renderer);
see JTable tutorial, test code examples, for example
import java.awt.BorderLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class TableRenderDemo extends JPanel {
private static final long serialVersionUID = 1L;
public TableRenderDemo() {
super(new BorderLayout(5, 5));
final JTable table = new JTable(new MyTableModel());
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setFillsViewportHeight(true);
table.setRowHeight(20);
JScrollPane scrollPane = new JScrollPane(table);
initColumnSizes(table);
setUpSportColumn(table, table.getColumnModel().getColumn(2));
add(scrollPane, BorderLayout.CENTER);
JButton resetButton = new JButton("Reset to default");
resetButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < table.getRowCount(); i++) {
table.getModel().setValueAt("None of the above", i, 2);
}
}
});
add(resetButton, BorderLayout.SOUTH);
}
private void initColumnSizes(JTable table) {
MyTableModel model = (MyTableModel) table.getModel();
TableColumn column = null;
Component comp = null;
int headerWidth = 0;
int cellWidth = 0;
Object[] longValues = model.longValues;
TableCellRenderer headerRenderer = table.getTableHeader().getDefaultRenderer();
for (int i = 0; i < 5; i++) {
column = table.getColumnModel().getColumn(i);
comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
headerWidth = comp.getPreferredSize().width;
comp = table.getDefaultRenderer(model.getColumnClass(i)).getTableCellRendererComponent(table, longValues[i], false, false, 0, i);
cellWidth = comp.getPreferredSize().width;
column.setPreferredWidth(Math.max(headerWidth, cellWidth));
}
}
private void setUpSportColumn(JTable table, TableColumn sportColumn) {
ArrayList<String> listSomeString = new ArrayList<String>();
listSomeString.add("Snowboarding");
listSomeString.add("Rowing");
listSomeString.add("Knitting");
listSomeString.add("Speed reading");
listSomeString.add("Pool");
listSomeString.add("None of the above");
JComboBox comboBox = new JComboBox();
comboBox.addItem(new Item(1, "-"));
comboBox.addItem(new Item(2, "Snowboarding"));
comboBox.addItem(new Item(3, "Rowing"));
comboBox.addItem(new Item(4, "Knitting"));
comboBox.addItem(new Item(5, "Speed reading"));
comboBox.addItem(new Item(6, "Pool"));
comboBox.addItem(new Item(7, "None of the above"));
comboBox.setMaximumRowCount(3);
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComboBox comboBox = (JComboBox) e.getSource();
Item item = (Item) comboBox.getSelectedItem();
System.out.println(item.getId() + " : " + item.getDescription());
}
});
//comboBox.setRenderer(new ItemRenderer());
sportColumn.setCellEditor(new DefaultCellEditor(comboBox));
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
renderer.setToolTipText("Click for combo box");
sportColumn.setCellRenderer(renderer);
}
class ItemRenderer extends BasicComboBoxRenderer {
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value != null) {
Item item = (Item) value;
setText(item.getDescription().toUpperCase());
}
if (index == -1) {
Item item = (Item) value;
setText("" + item.getId());
}
return this;
}
}
class Item {
private int id;
private String description;
public Item(int id, String description) {
this.id = id;
this.description = description;
}
public int getId() {
return id;
}
public String getDescription() {
return description;
}
#Override
public String toString() {
return description;
}
}
class MyTableModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
private Object[][] data = {{"Kathy", "Smith", "Snowboarding", new Integer(5), false},
{"John", "Doe", "Rowing", new Integer(3), true}, {"Sue", "Black", "Knitting", new Integer(2), false},
{"Jane", "White", "Speed reading", new Integer(20), true}, {"Joe", "Brown", "Pool", new Integer(10), false}};
public final Object[] longValues = {"Jane", "Kathy", "None of the above", new Integer(20), Boolean.TRUE};
#Override
public int getColumnCount() {
return columnNames.length;
}
#Override
public int getRowCount() {
return data.length;
}
#Override
public String getColumnName(int col) {
return columnNames[col];
}
#Override
public Object getValueAt(int row, int col) {
return data[row][col];
}
#Override
public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
#Override
public boolean isCellEditable(int row, int col) {
if (col < 2) {
return false;
} else {
return true;
}
}
#Override
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
System.out.println("New value of data: " + getValueAt(row, col));
}
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("TableRenderDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TableRenderDemo newContentPane = new TableRenderDemo();
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
}

Filling data in JTable in netbeans

I want to change default data in JTable at runtime. I am using netbeans. I tried solution given here adding data to JTable when working with netbeans
jTable1.getModel().setValueAt(row, column, value);
but it gives me this error:
If you want to change it at runtime you need to decide when you want it changed and add the code to the proper method/event. As it stands you have a method call in your class definition, which is not valid code.
For instance
public void setTableModel(){
displayTable.getModel().setValueAt(2,4,300);
}
And then call setTableModel() at an appropriate time.
because you wrote this code line out of current Class, you have to wrap these code line(s)
inside Class/void/constructor, for example
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class TableProcessing extends JFrame implements TableModelListener {
private static final long serialVersionUID = 1L;
private JTable table;
public TableProcessing() {
String[] columnNames = {"Item", "Quantity", "Price", "Cost"};
Object[][] data = {
{"Bread", new Integer(1), new Double(1.11), new Double(1.11)},
{"Milk", new Integer(1), new Double(2.22), new Double(2.22)},
{"Tea", new Integer(1), new Double(3.33), new Double(3.33)},
{"Cofee", new Integer(1), new Double(4.44), new Double(4.44)}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
model.addTableModelListener(this);
table = new JTable(model) {
private static final long serialVersionUID = 1L;
#Override
public Class getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
#Override
public boolean isCellEditable(int row, int column) {
int modelColumn = convertColumnIndexToModel(column);
return (modelColumn == 3) ? false : true;
}
};
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
getContentPane().add(scrollPane);
}
#Override
public void tableChanged(TableModelEvent e) {
if (e.getType() == TableModelEvent.UPDATE) {
int row = e.getFirstRow();
int column = e.getColumn();
System.out.println(row + " : " + column);
if (column == 1 || column == 2) {
int quantity = ((Integer) table.getModel().getValueAt(row, 1)).intValue();
double price = ((Double) table.getModel().getValueAt(row, 2)).doubleValue();
Double value = new Double(quantity * price);
table.getModel().setValueAt(value, row, 3);
}
}
}
public static void main(String[] args) {
TableProcessing frame = new TableProcessing();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}

Categories