I have got question about adding JComboBox, to Column in Custom table model which extends ObjectTableModel (Table is OmniJTable). I work on it 2 days and cannot solve this problem.
One thing I solved is displaying JComboBox in Column, but right now I have got problem with selecting anything from it (seems it's not editable, and anything like "setEditable()" not working).
Here is code which one I add jComboBox to my OmniJTable with ObjectTableModel.
class CheckBoxCellRenderer extends JComboBox implements TableCellRenderer {
JComboBox combo;
public CheckBoxCellRenderer(JComboBox comboBox) {
this.combo = new JComboBox();
for (int i=0; i<comboBox.getItemCount(); i++){
combo.addItem(comboBox.getItemAt(i));
}
}
#Override
public Component getTableCellRendererComponent(JTable jtable, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
combo.setSelectedItem(value);
return combo;
}
}
private void addComboBoxToStatusColumn(JTable table)
{
final int statusColumnIndex = bazaTelefonowOmniJTable.getColumnModel().getColumnIndex("Status");
TableColumn tmpColum = bazaTelefonowOmniJTable.getColumnModel().getColumn(statusColumnIndex);
final JComboBox comboBox = new JComboBox();
comboBox.setEditable(true);
comboBox.setEnabled(true);
loadRecordStatusFromDictionary(comboBox);
DefaultCellEditor defaultCellEditor=new DefaultCellEditor(comboBox);
tmpColum.setCellEditor(defaultCellEditor);
tmpColum.setCellRenderer(new CheckBoxCellRenderer(comboBox));
bazaTelefonowOmniJTable.setEditable(true);
//table.repaint();
}
As i said, this one adding jComboBox to Column, but i don't know how to make this one to allow me to choose items in jComboBox.
PS: Sry for my english, it's not my primary language.
The simplest thing is not to add a CellRenderer. In that case, the Table renders it as a Label and when clicked the combo box is shown. Here is an example:
package snippet;
import java.awt.Component;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class JTableTest extends JFrame {
public JTableTest() {
super(JTableTest.class.getName());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initComponents();
}
private void initComponents() {
JTable table = new JTable(new Object[][] { { "1", "One" }, { "2", "Two" } }, new Object[] { "Column One", "Status" });
addComboBoxToStatusColumn(table);
add(new JScrollPane(table));
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override public void run() {
new JTableTest().setVisible(true);
}
});
}
private void addComboBoxToStatusColumn(JTable table) {
final int statusColumnIndex = table.getColumnModel().getColumnIndex("Status");
TableColumn tmpColum = table.getColumnModel().getColumn(statusColumnIndex);
final JComboBox comboBox = new JComboBox();
loadRecordStatusFromDictionary(comboBox);
DefaultCellEditor defaultCellEditor = new DefaultCellEditor(comboBox);
tmpColum.setCellEditor(defaultCellEditor);
}
private void loadRecordStatusFromDictionary(JComboBox comboBox) {
comboBox.addItem("Two");
comboBox.addItem("Four");
comboBox.addItem("Six");
}
}
You also need to override the isCellEditable method from your model.
model = DaneTableModel(some arg) {
public boolean isCellEditable(int row, int col) {
if(col == STATUS_COLUMN) return true ;
return false;
}
}
Related
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;
}
}
}
Probably a noob question, but im new to java. I have a need for a checkbox list which I found is not supported in swing, but I found this custom control here
http://www.devx.com/tips/Tip/5342
So I created a class file named CheckBoxList, and copied the code from the link into it:
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
public class CheckBoxList extends JList
{
protected static Border noFocusBorder =
new EmptyBorder(1, 1, 1, 1);
public CheckBoxList()
{
setCellRenderer(new CellRenderer());
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
int index = locationToIndex(e.getPoint());
if (index != -1) {
JCheckBox checkbox = (JCheckBox)
getModel().getElementAt(index);
checkbox.setSelected(
!checkbox.isSelected());
repaint();
}
}
}
);
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
protected class CellRenderer implements ListCellRenderer
{
public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus)
{
JCheckBox checkbox = (JCheckBox) value;
checkbox.setBackground(isSelected ?
getSelectionBackground() : getBackground());
checkbox.setForeground(isSelected ?
getSelectionForeground() : getForeground());
checkbox.setEnabled(isEnabled());
checkbox.setFont(getFont());
checkbox.setFocusPainted(false);
checkbox.setBorderPainted(true);
checkbox.setBorder(isSelected ?
UIManager.getBorder(
"List.focusCellHighlightBorder") : noFocusBorder);
return checkbox;
}
}
}
The problem is I don't know how to implement it in my GUI file. I tried a lot of code, but they never showed an example. Just
To use the class, simply instantiate it, then pass it an array of
JCheckBox objects (or subclasses of JCheckBox objects) by calling
setListData
So does that mean that I will not see the control in the Graphical Design view? My client wants to be able to edit it himself and add stuff so I want it to be easy and graphical if possible. If someone could show an example of instantiating it or give a good hint I would appreciate it. Thanks!
Can you just tell me how?
Use a one column JTable and an appropriate renderer and editor. Based on this example, the code below relies on the default renderer for a data value of type Boolean.Class. A more general example is cited here.
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
/** #see https://stackoverflow.com/a/13919878/230513 */
public class CheckTable {
private static final CheckModel model = new CheckModel(5000);
private static final JTable table = new JTable(model) {
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(150, 300);
}
#Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
JCheckBox jcb = (JCheckBox) super.prepareRenderer(renderer, row, column);
jcb.setHorizontalTextPosition(JCheckBox.LEADING);
jcb.setText(String.valueOf(row));
return jcb;
}
};
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame("CheckTable");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridLayout(1, 0));
f.add(new JScrollPane(table));
f.add(new DisplayPanel(model));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
private static class DisplayPanel extends JPanel {
private DefaultListModel dlm = new DefaultListModel();
private JList list = new JList(dlm);
public DisplayPanel(final CheckModel model) {
super(new GridLayout());
this.setBorder(BorderFactory.createTitledBorder("Checked"));
this.add(new JScrollPane(list));
model.addTableModelListener(new TableModelListener() {
#Override
public void tableChanged(TableModelEvent e) {
dlm.removeAllElements();
for (Integer integer : model.checked) {
dlm.addElement(integer);
}
}
});
}
}
private static class CheckModel extends AbstractTableModel {
private final int rows;
private List<Boolean> rowList;
private Set<Integer> checked = new TreeSet<Integer>();
public CheckModel(int rows) {
this.rows = rows;
rowList = new ArrayList<Boolean>(rows);
for (int i = 0; i < rows; i++) {
rowList.add(Boolean.FALSE);
}
}
#Override
public int getRowCount() {
return rows;
}
#Override
public int getColumnCount() {
return 1;
}
#Override
public String getColumnName(int col) {
return "Column " + col;
}
#Override
public Object getValueAt(int row, int col) {
return rowList.get(row);
}
#Override
public void setValueAt(Object aValue, int row, int col) {
boolean b = (Boolean) aValue;
rowList.set(row, b);
if (b) {
checked.add(row);
} else {
checked.remove(row);
}
fireTableRowsUpdated(row, row);
}
#Override
public Class<?> getColumnClass(int col) {
return getValueAt(0, col).getClass();
}
#Override
public boolean isCellEditable(int row, int col) {
return true;
}
}
}
The code is expecting a list of JCheckBox objects - so this works
CheckBoxList cbList = new CheckBoxList(); // the class you have
JCheckBox check1 = new JCheckBox("One");
JCheckBox check2 = new JCheckBox("two");
JCheckBox[] myList = { check1, check2}; list of checkbox object
cbList.setListData(myList); // set the list data for the object
Small Swing program using your class below
util;
import javax.swing.*;
public class HelloWorldSwing {
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("HelloWorldSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CheckBoxList cbList = new CheckBoxList();
JCheckBox check1 = new JCheckBox("One");
JCheckBox check2 = new JCheckBox("two");
JCheckBox[] myList = { check1, check2};
cbList.setListData(myList);
frame.getContentPane().add(cbList);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
I am trying to create a Jtable with two combobox in each row. I have checked for tutorials on that and found that I can add static data inside combobox. But how come I can have dynamic data loaded into a combobox.
Even, whenever the user selects the combobox 1 from the row, then based on that, the combobox 2 will be updated.
Can anybody help me on this?
If I do removeAllItems() from the combobox, then the combobox 2 will updated, but I am unable to add new entries.
Thanks in advance.
Table has two columns both are rendered as JComboBox. Now, selection of Column-2 items are dependent on the Column-1 selection.
import java.awt.Component;
import java.awt.EventQueue;
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.JScrollPane;
import javax.swing.JTable;
public class ComboBoxExample {
private void createUI() {
JFrame frame = new JFrame();
Object[] columNames = {"Combo-1", "Combo-2"};
Object[][] data = {{"", ""}, {"", ""}, {"", ""}, {"", ""}};
JTable table = new JTable(data, columNames);
table.getColumnModel().getColumn(0).setCellEditor(new CustomComboBoxEditor());
table.getColumnModel().getColumn(1).setCellEditor(new CustomComboBoxEditor());
frame.add(new JScrollPane(table));
frame.setTitle("Column -2 based on Column - 1 ComboBox Selection.");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new ComboBoxExample().createUI();
}
};
EventQueue.invokeLater(r);
}
}
class CustomComboBoxEditor extends DefaultCellEditor {
// Declare a model that is used for adding the elements to the `ComboBox`
private DefaultComboBoxModel model;
private List<String> obtainedList;
public CustomComboBoxEditor() {
super(new JComboBox());
this.model = (DefaultComboBoxModel)((JComboBox)getComponent()).getModel();
obtainedList = new ArrayList<String>();
obtainedList.add("One");
obtainedList.add("Two");
obtainedList.add("Three");
obtainedList.add("Four");
obtainedList.add("Five");
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
if(column == 0) {
model.removeAllElements();
for(int i = 0; i < obtainedList.size(); i++) {
model.addElement(obtainedList.get(i));
}
} else {
model.removeAllElements();
String selectedItem = (String) table.getValueAt(row, 0);
for(int i = 0; i < obtainedList.size(); i++) {
if(!selectedItem.equals(obtainedList.get(i)))
model.addElement(obtainedList.get(i));
}
} // Close else
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
}
Try something like this, you can change DATA in this example, and repaint and do the Renderer of the cell:
public void example(){
TableColumn tmpColum =table.getColumnModel().getColumn(1);
String[] DATA = { "Data 1", "Data 2", "Data 3", "Data 4" };
JComboBox comboBox = new JComboBox(DATA);
DefaultCellEditor defaultCellEditor=new DefaultCellEditor(comboBox);
tmpColum.setCellEditor(defaultCellEditor);
tmpColum.setCellRenderer(new CheckBoxCellRenderer(comboBox));
table.repaint();
}
/**
Custom class for adding elements in the JComboBox.
*/
class CheckBoxCellRenderer implements TableCellRenderer {
JComboBox combo;
public CheckBoxCellRenderer(JComboBox comboBox) {
this.combo = new JComboBox();
for (int i=0; i<comboBox.getItemCount(); i++){
combo.addItem(comboBox.getItemAt(i));
}
}
public Component getTableCellRendererComponent(JTable jtable, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
combo.setSelectedItem(value);
return combo;
}
}
After removeAllItems() call, add items in combobox as
combobox.addItem("one");
combobox.addItem("two");
I have got a problem with JTable and JButton.
After pressing the button, is suspended in its last position in the table.
Try to run the code below.
Firs I open row "Open 4" and Close by button "Close 4".
After that if I Open row "Open 3" the button "4" is still there...
How to fix this?
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventObject;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.*;
import javax.swing.table.*;
class MyRenderer implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasValue, int row, int column) {
DefaultTableModel model =((DefaultTableModel)table.getModel());
if (model.getValueAt(row,0)!=null && column==0) {
String DATA= "Close "+(model.getValueAt(row,0)).toString();
JButton b = new JButton(DATA);
return b;
}
else return null;
}
}
class MyEditor implements TableCellEditor {
public Component getTableCellEditorComponent(final JTable table, Object value,
boolean isSelected, final int row, int column){
final DefaultTableModel model =((DefaultTableModel)table.getModel());
if (model.getValueAt(row,0)!=null && column==0 ){
String text =model.getValueAt(row,0).toString();
final JButton b = new JButton(text);
ActionListener AKCJA = new ActionListener(){
public void actionPerformed(ActionEvent e) {
if(model.getValueAt(row+1,0)==null)
while(model.getValueAt(row+1,0)==null)
((DefaultTableModel)table.getModel()).removeRow(row+1);
}
};
b.addActionListener(AKCJA);
return b;
}
else return null;
}
public void removeCellEditorListener(CellEditorListener cl) { }
public void addCellEditorListener(CellEditorListener cl) { }
public boolean shouldSelectCell(EventObject ev) { return true; }
public boolean isCellEditable(EventObject ev) {return true;}
public Object getCellEditorValue() { return null;}
public boolean stopCellEditing() { return true;}
public void cancelCellEditing() { }
}
#SuppressWarnings("serial")
class MyJpanel extends JPanel{
public MyJpanel(){
super(new GridLayout(1,0));
final DefaultTableModel model = new DefaultTableModel();
model.addColumn("Col1");
model.addColumn("Col2");
for(int kk=0;kk<8;kk++)
model.addRow(new Object[]{kk, "Open "+kk});
final JTable table = new JTable(model);
TableColumn td = table.getColumnModel().getColumn(0);
MyRenderer mojRenderer = new MyRenderer();
td.setCellRenderer(mojRenderer);
MyEditor mojEditor = new MyEditor();
td.setCellEditor(mojEditor);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
int viewRow = table.getSelectedRow();
if(event.getValueIsAdjusting())
if((model.getValueAt(viewRow,0))!=null)
for(int i=0;i<2;i++)
model.insertRow(viewRow+i+1,new Object[]{null, "b"});
}
}
);
add(table );
}
}
public class Test{
public static void main(String[] args)
{
final JFrame ramka=new JFrame("xxx");
ramka.getContentPane().add(new MyJpanel());
ramka.setSize(500,200);
ramka.setVisible(true);
ramka.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
The solution is remove button in Jtable container by using for example table.removeAll(); before button ActionListener().
Very usefull to find problem was:
Component[] Komponenty = table.getComponents();
You can print Array Komponenty and found components which you forgot to delete or hide;
I have a JTable with a column containing a JComboBox.
I have an ItemListener attached to the JComboBox which acts upon any changes.
However, ItemListener does not have a method for obtaining the Row that the changed ComboBox is within.
I need to Row number in order to act upon another column in the same row when the ComboBox has a change.
Any help would be appreciated.
This is my Short and Concise code. What I am trying to accomplish, is obtaining the Table Row of the ComboBox when a the itemlistener picks up a change.
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class Example extends JFrame {
private static final long serialVersionUID = 1L;
public static int maxX, maxY;
public static final String[] columnHeads = {"Col 1", "Col 2", "Col 3"};
public static void main(String args[]) throws IOException {
Example example = new Example();
}
public Example() {
//Create Table Model
DefaultTableModel model = new DefaultTableModel();
for (int index = 0; index < columnHeads.length; index++) {
model.addColumn(columnHeads[index]);
}
//Create Table
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
//List for ComboBox
String[] list = {"Item1", "Item2", "Item3"};
//Create ComboBox
JComboBox itemTypes = attachComboBoxRenderer(table, 2, list);
//Attach Item Listener
itemTypes.addItemListener(new ComboBoxListener());
((DefaultTableModel) table.getModel()).insertRow(
table.getRowCount(), new Object[]{"C1", "C2", ""});
this.setTitle("Example");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container container = getContentPane();
//MAIN Panel
final JPanel main = new JPanel();
main.setLayout(new GridBagLayout());
main.add(scrollPane);
container.add(main);
this.pack();
this.setVisible(true);
}
public static JComboBox attachComboBoxRenderer(
JTable table, int column, Object[] values) {
JComboBox combo = new JComboBox(values);
TableColumn col = table.getColumnModel().getColumn(column);
col.setCellRenderer(new ComboBoxRenderer(values));
col.setCellEditor(new DefaultCellEditor(combo));
return combo;
}
}
class ComboBoxListener implements ItemListener {
private static final int SELECTED = 1;
#Override
public void itemStateChanged(ItemEvent e) {
// Get the affected item
Object item = e.getItem();
if (item.toString() != null
&& !"".equals(item.toString())
&& e.getStateChange() == SELECTED) {
System.out.println(item.toString() + " selected");
//How do I get Row in the Table of the ComboBox that was changed?
}
}
}
class ComboBoxRenderer extends JComboBox implements TableCellRenderer {
private static final long serialVersionUID = 1L;
public ComboBoxRenderer(Object[] items) {
super(items);
}
#Override
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());
}
// Select the current value
setSelectedItem(value);
return this;
}
}
It sounds like you are Using a Combo Box as an Editor. If so, the TableCellEditor method, getTableCellEditorComponent(), includes the row as a parameter. There's a related example here.
Addendum: To change a value in the same row you've edited, just have the model return the correct value for the "other column" based on the related values in that row. Alternatively, update the related value in your model's setValueAt() method before firing the update, as shown in the example.
Addendum: Based on your example, the code below overrides the model's getValueAt() method to keep the dependent column synchronized with the item column.
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
/** #see http://stackoverflow.com/questions/7350445 */
public class DependentColumn extends JFrame {
private static final int DEPENDENT_COL = 1;
private static final int ITEM_COL = 2;
private static final String[] columnNames = {"Col 1", "Col 2", "Col 3"};
public static void main(String args[]) throws IOException {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
DependentColumn dc = new DependentColumn();
}
});
}
public DependentColumn() {
this.setTitle("Example");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create Model & Table
DefaultTableModel model = new DefaultTableModel(columnNames, 0) {
#Override
public Object getValueAt(int row, int col) {
if (col == DEPENDENT_COL) {
return "C2:" + this.getValueAt(row, ITEM_COL);
} else {
return super.getValueAt(row, col);
}
}
};
for (int i = 0; i < 16; i++) {
model.addRow(new Object[]{"C1", "C2", "Item1"});
}
JTable table = new JTable(model);
table.setPreferredScrollableViewportSize(new Dimension(320, 120));
//Create ComboBox
String[] items = {"Item1", "Item2", "Item3"};
JComboBox combo = new JComboBox(items);
TableColumn col = table.getColumnModel().getColumn(ITEM_COL);
col.setCellEditor(new DefaultCellEditor(combo));
combo.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
System.out.println(e.getItem() + " selected");
}
}
});
this.add(new JScrollPane(table));
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
}