I have a JTable that includes items from an ArrayList, however whenever I try to remove the contents of deleted row from the ArrayList I get an IndexOutOfBoundsException depending on the amount of rows I wanted to delete and their location. How would I go about solving this issue?
Runnable Code: http://pastebin.com/Nnrnxzdg
remove.addActionListener( e -> {
int k = 0;
int[] rows = table.getSelectedRows();
TableModel tm= table.getModel();
while(rows.length>0)
{
while(k<rows.length)
{
al.remove(table.getSelectedRow() + k);
k++;
}
((DefaultTableModel)tm).removeRow(table.convertRowIndexToModel(rows[0]));
rows = table.getSelectedRows();
}
table.clearSelection();
});
Basically, the moment you remove a row, all the indices change. So what you need to do, is make a copy of all the selected rows, but NOT the index, but the actual row value...
JTable table = getTable();
if (table.getSelectedRowCount() > 0) {
List<Vector> selectedRows = new ArrayList<>(25);
DefaultTableModel model = getModel();
Vector rowData = model.getDataVector();
for (int row : table.getSelectedRows()) {
int modelRow = table.convertRowIndexToModel(row);
Vector rowValue = (Vector) rowData.get(modelRow);
selectedRows.add(rowValue);
}
Now with this, you can calculate the indexOf any given object with the model and remove it...
for (Vector rowValue : selectedRows) {
int rowIndex = rowData.indexOf(rowValue);
model.removeRow(rowIndex);
}
}
without caring what the index of the value was.
The indexes change if you remove the rows from the start of the model.
One solution is to remove one row at a time, ten all the selected indexes are reset so you are always removing the proper index:
Here is an example showing how you might do this for a JList and a JTable:
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.*;
import javax.swing.table.*;
public class ItemDeletion extends JPanel
{
private JList<String> list;
private JTable table;
public ItemDeletion()
{
setLayout( new BorderLayout(5, 5) );
String[] items =
{
"One",
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten"
};
// Add the list
DefaultListModel<String> listModel = new DefaultListModel<String>();
for (String item: items)
listModel.addElement( item );
list = new JList<String>( listModel );
JButton listDelete = new JButton( "Delete From List" );
listDelete.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
DefaultListModel model = (DefaultListModel)list.getModel();
int row = list.getSelectedIndex();
while (row != -1)
{
model.removeElementAt( row );
row = list.getSelectedIndex();
}
}
});
JPanel listPanel = new JPanel( new BorderLayout(5, 5) );
listPanel.add(new JScrollPane( list ), BorderLayout.CENTER);
listPanel.add(listDelete, BorderLayout.PAGE_END);
// Add the table
DefaultTableModel tableModel = new DefaultTableModel(0, 1);
List<String> tableItems = Arrays.asList( items );
Collections.shuffle( tableItems );
for (String item: tableItems)
{
System.out.println( item );
tableModel.addRow( new String[]{item} );
}
table = new JTable( tableModel );
table.setAutoCreateRowSorter(true);
((DefaultRowSorter)table.getRowSorter()).toggleSortOrder(0);
JButton tableDelete = new JButton( "Delete From Table" );
tableDelete.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
DefaultTableModel model = (DefaultTableModel)table.getModel();
int row = table.getSelectedRow();
while (row != -1)
{
int modelRow = table.convertRowIndexToModel( row );
model.removeRow( modelRow );
row = table.getSelectedRow();
}
}
});
JPanel tablePanel = new JPanel( new BorderLayout(5, 5) );
tablePanel.add(new JScrollPane( table ), BorderLayout.CENTER);
tablePanel.add(tableDelete, BorderLayout.PAGE_END);
add(listPanel, BorderLayout.LINE_START);
add(tablePanel, BorderLayout.LINE_END);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Multiple Item Deletion");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ItemDeletion(), BorderLayout.NORTH);
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Related
I've created a custom combo box that displays possible changes in state for orders. I did it with the help of this post, using MadProgrammer's code as base line:
Changing Dropdown content in a JTable Column in Swing
It worked, partially.
Even though after clicking the combo box is activated and it shows the proper state options for the user, it has the following problem.
After the user selects the option, the combo box doesn't set the selected value in the table. However if the user changes the combo box of another order, the change does take place. It also works if you click other part of the selected row that isn't the combo box cell.
I suspect that this is because the cell only changes to be a combo box when is clicked, so it doesn't behave like a combo box does. Yet I'm a bit lost in how to fix it.
Any help is greatly appreciated.
Here are the relevant parts of my code:
EDIT: Following Andrew Thompson's advice, i replaced the code with a reproducible example. I'll be working on MadProgrammer's suggested solution and update it later.
package test;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractCellEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
public class TestCellEditor {
public static void main(String[] args) {
new TestCellEditor();
}
public TestCellEditor() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
List<String> values = new ArrayList<>(5);
values.add("B");
values.add("A");
values.add("O");
values.add("G");
values.add("P");
ComboBoxTableCellEditor editor = new ComboBoxTableCellEditor(values);
DefaultTableModel model = new DefaultTableModel(new Object[]{"Status"}, 5);
JTable table = new JTable(model);
table.getColumnModel().getColumn(0).setCellEditor(editor);
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 ComboBoxTableCellEditor extends AbstractCellEditor implements TableCellEditor {
private JComboBox editor;
private List<String> masterValues;
public ComboBoxTableCellEditor(List<String> masterValues) {
this.editor = new JComboBox();
this.masterValues = masterValues;
}
#Override
public Object getCellEditorValue() {
return editor.getSelectedItem();
}
#Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
DefaultComboBoxModel model = new DefaultComboBoxModel(masterValues.toArray(new String[masterValues.size()]));
for (int index = 0; index < table.getRowCount(); index++) {
}
editor.setModel(model);
editor.setSelectedItem(value);
return editor;
}
}
}
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();
}
});
}
}
Following the suggestion of #camickr i managed to implement an easier solution.
I put this on the method that populates the table:
table.getColumnModel().getColumn(5).setCellEditor(getCellEditor(status));
public List<TableCellEditor> TableComboBoxByRow(){
// Create the editors to be used for each row
List<TableCellEditor> editors = new ArrayList<TableCellEditor>(3);
String[] items1 = { "I", "C", "F" };
JComboBox comboBox1 = new JComboBox( items1 );
DefaultCellEditor dce1 = new DefaultCellEditor( comboBox1 );
editors.add( dce1 );
String[] items2 = { "E" };
JComboBox comboBox2 = new JComboBox( items2 );
DefaultCellEditor dce2 = new DefaultCellEditor( comboBox2 );
editors.add( dce2 );
String[] items3 = { "ET" };
JComboBox comboBox3 = new JComboBox( items3 );
DefaultCellEditor dce3 = new DefaultCellEditor( comboBox3 );
editors.add( dce3 );
String[] items4 = { "F" };
JComboBox comboBox4 = new JComboBox( items4 );
DefaultCellEditor dce4 = new DefaultCellEditor( comboBox4 );
editors.add( dce4 );
return editors;
}
public TableCellEditor getCellEditor(String status)
{
if(estado.equals("I") || estado.equals("C")){
return TableComboBoxByRow().get(0);
}
else if(estado.equals("E"))
{
return TableComboBoxByRow().get(1);}
else if(estado.equals("ET"))
{
return TableComboBoxByRow().get(2);
}else{
return TableComboBoxByRow().get(3);
}
}
Thank you so much!
It downloads data from ThingSpeak and show in jtable. I create a 'refresh' button which will download latest data and show in existing gui table.
get the latest data...work
store in List/arrays...work
update the jtable...Nop
I have tried fireTableDataChanged, setModel, revalidate, invalidate and repaint but still doesn't update the table. What am I missing?
public class Menu{
protected static List<String> list_name = new ArrayList<>();
// .....(10 more like above)
private JFrame frame = new JFrame("Temp");
private List<String[]> records_data = new ArrayList<String[]>();
private JTable table;
private DefaultTableModel model;
private String[][] data2 = new String[list_channel_ID.size()][11];
String[] columnNames_records = {"Location"}; // skip 10 more items
protected Menu(){
// Jframe > Jtabbedpane > jtable( I skip all these codes)
//- Table(Records)
for(int i = 0; i < list_channel_ID.size(); i++){
records_data.add(new String[]{ list_name.get(i) });} // Load data from List to jtable require format, skip 10 items
//table = new JTable(records_data.toArray(new Object[][] {}), columnNames_records); // when 'model' is not use
model = new DefaultTableModel(records_data.toArray(new Object[][] {}), columnNames_records);
//model = new DefaultTableModel(data2, columnNames);
table = new JTable(model);
JMenuItem process_refresh = new JMenuItem("Refresh");
process_refresh.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// Update the list
for(int i = 0; i < list_channel_ID.size(); i++){
records_data.add(new String[]{ list_name.get(i) }); // load from list again, skiped 10 item
}
model = new DefaultTableModel(records_data.toArray(new Object[][] {}), columnNames_records);
model.fireTableDataChanged();
//table.setModel(model);
table.revalidate();
//table.invalidate();
table.repaint();
}
});
}
}
Problem solve, I forgot to clear the list 'records_data' :|
I will leave it here if someone face the same problem and mind blown for 2 days like me
Working code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.lang.String;
import java.util.List;
import java.util.ArrayList;
public class Menu{
protected static List<String> list_name = List.of("AAA", "BBB", "CCC");
// .....(10 more like above)
private JFrame frame = new JFrame("Temp");
private List<String[]> records_data = new ArrayList<String[]>();
private List<String[]> result_data = new ArrayList<String[]>();
private JTable table, table2, table3;
private DefaultTableModel model;
private String[][] data2 = new String[3][11];
String[] columnNames_records = {"item A", "item B", "item C"}; // 10 more items
protected Menu(){
frame.setSize(1000, 600);
frame.setLayout(new GridLayout(2, 1));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//- Back Panel
JPanel panel = new JPanel(null);
frame.add(panel);
JPanel tab_panel = new JPanel(new GridLayout());
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.setBounds(5, 100, 975, 500);
tabbedPane.add("Records", tab_panel);
frame.add(tabbedPane);
//- Table(Records)
for(int i = 0; i < 3; i++){
records_data.add(new String[]{ list_name.get(i) });
} // Load data from List to jtable require format, skiped 10 item
//table = new JTable(records_data.toArray(new Object[][] {}), columnNames_records);
model = new DefaultTableModel(records_data.toArray(new Object[][] {}), columnNames_records);
//model = new DefaultTableModel(data2, columnNames);
table = new JTable(model);
table.setRowHeight(20);
//- ScrollPane, allow scrolling if table too long
JScrollPane scrollPane = new JScrollPane(table);
tab_panel.add(scrollPane);
// Menu bar
JMenu menu_process = new JMenu("Process");
JMenuItem process_refresh = new JMenuItem("Refresh");
process_refresh.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
records_data.clear();
list_name = List.of("DDD", "EEE", "FFF"); // Update the list, hardcode for now
//list_name.add("KKK");
for(int i = 0; i < 3; i++){
records_data.add(new String[]{ list_name.get(i) }); // load from list again, skiped 10 item
}
model = new DefaultTableModel(records_data.toArray(new Object[][] {}), columnNames_records);
//model.fireTableDataChanged();
table.setModel(model);
//table.revalidate();
//table.invalidate();
//table.repaint();
}
});
menu_process.add(process_refresh);
JMenuBar menu_bar = new JMenuBar();
menu_bar.add(menu_process);
frame.setJMenuBar(menu_bar);
frame.setVisible(true);
}
public static void main(String[ ] args) {
new Menu();
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I need to read the date from the .txt file put it into JTable in my GUI, then modify some records or delete some lines and save new data to the file.
I can do the reading and show JTable but how to edit the date or delete some lines in JTable using GUI then save it to the file?
but how to edit
You need to override the isCellEditable(...) method of the DefaultTableModel to return true.
delete some lines in JTable using GUI
You need to know which row(s) is selected and then use the removeRow(...) method of the DefaultTableModel to delete the row.
For example:
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.*;
import javax.swing.table.*;
public class ItemDeletion extends JPanel
{
private JList<String> list;
private JTable table;
public ItemDeletion()
{
setLayout( new BorderLayout(5, 5) );
String[] items =
{
"One",
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten"
};
// Add the list
DefaultListModel<String> listModel = new DefaultListModel<String>();
for (String item: items)
listModel.addElement( item );
list = new JList<String>( listModel );
JButton listDelete = new JButton( "Delete From List" );
listDelete.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
DefaultListModel model = (DefaultListModel)list.getModel();
int row = list.getSelectedIndex();
while (row != -1)
{
model.removeElementAt( row );
row = list.getSelectedIndex();
}
}
});
JPanel listPanel = new JPanel( new BorderLayout(5, 5) );
listPanel.add(new JScrollPane( list ), BorderLayout.CENTER);
listPanel.add(listDelete, BorderLayout.PAGE_END);
// Add the table
DefaultTableModel tableModel = new DefaultTableModel(0, 1);
List<String> tableItems = Arrays.asList( items );
Collections.shuffle( tableItems );
for (String item: tableItems)
{
System.out.println( item );
tableModel.addRow( new String[]{item} );
}
table = new JTable( tableModel );
table.setAutoCreateRowSorter(true);
((DefaultRowSorter)table.getRowSorter()).toggleSortOrder(0);
JButton tableDelete = new JButton( "Delete From Table" );
tableDelete.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
DefaultTableModel model = (DefaultTableModel)table.getModel();
int row = table.getSelectedRow();
while (row != -1)
{
int modelRow = table.convertRowIndexToModel( row );
model.removeRow( modelRow );
row = table.getSelectedRow();
}
}
});
JPanel tablePanel = new JPanel( new BorderLayout(5, 5) );
tablePanel.add(new JScrollPane( table ), BorderLayout.CENTER);
tablePanel.add(tableDelete, BorderLayout.PAGE_END);
add(listPanel, BorderLayout.LINE_START);
add(tablePanel, BorderLayout.LINE_END);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Multiple Item Deletion");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ItemDeletion(), BorderLayout.NORTH);
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
save it to the file?
You need to get the data from the DefaultTableModel. You can use the getValueAt(...) method to retrieve each value.
So you would need to create code something like:
for (each row);
{
StringBuilder sb = new StringBuilder();
for ( each column)
{
Object data = model.getValueAt(...);
sb.append( data.toString() );
}
write the sb.toString() to the file
}
I am new to Swing and seeking some help here. I need to show the data from an .xls file in a jTable. Below is my code which I followed from here :-
jbClick.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
jChooser.showOpenDialog(null);
File file = jChooser.getSelectedFile();
if(!file.getName().endsWith("xls")){
JOptionPane.showMessageDialog(null, "Please select only Excel file.", "Error",JOptionPane.ERROR_MESSAGE);
}
else {
fillData(file);
model = new DefaultTableModel(data, headers);
tableWidth = model.getColumnCount() * 150;
tableHeight = model.getRowCount() * 25;
table.setPreferredSize(new Dimension( tableWidth, tableHeight));
table.setModel(model);
jbClick.setVisible(false);
jbText.setVisible(true);
}
}
});
JPanel chooserPanel = new JPanel();
JPanel filterPanlel = new JPanel();
//filterPanlel.add(jbText,"OLa");
final Color alternate = new Color(186,246,244);
table = new JTable();
table.setAutoCreateRowSorter(true);
model = new DefaultTableModel(data, headers);
table.setModel(model);
table.setBackground(alternate);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setEnabled(false);
table.setRowHeight(25);
table.setRowMargin(4);
tableWidth = model.getColumnCount() * 200;
tableHeight = model.getRowCount() * 25;
table.setPreferredSize(new Dimension( tableWidth, tableHeight));
scroll = new JScrollPane(table);
scroll.setBackground(alternate);
scroll.setPreferredSize(new Dimension(500, 500));
scroll.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
getContentPane().add(buttonPanel, BorderLayout.NORTH);
getContentPane().add(scroll, BorderLayout.CENTER);
//setSize(600, 600);
setResizable(true);
setExtendedState(JFrame.MAXIMIZED_BOTH);
//setUndecorated(true);
setVisible(true);
}
/** * Fill JTable with Excel file data. * * #param file * file :contains xls file to display in jTable */
#SuppressWarnings({ "unchecked", "rawtypes" })
void fillData(File file) {
Workbook workbook = null;
try {
try {
workbook = Workbook.getWorkbook(file);
}
catch (IOException ex) {
Logger.getLogger( excelTojTable.class. getName()).log(Level.SEVERE, null, ex);
}
Sheet sheet = workbook.getSheet(0);
headers.clear();
for (int i = 0; i < sheet.getColumns(); i++)
{
Cell cell1 = sheet.getCell(i, 0);
headers.add(cell1.getContents());
}
data.clear();
for (int j = 1; j < sheet.getRows(); j++)
{
Vector d = new Vector();
for (int i = 0; i < sheet.getColumns(); i++)
{
Cell cell = sheet.getCell(i, j);
d.add(cell.getContents());
}
d.add("\n");
data.add(d);
}
}
catch (BiffException e) {
e.printStackTrace();
}
}
Problem :- Now I need to add a editable checkbox in-front of each row in the table.
Please help.
I need to add a editable checkbox in-front of each row in the table.
Before your loops that create the "header" and "d" Vectors, you need to add your Boolean information.
So for the header you might do:
headers.clear();
header.add("Select");
and for each row:
Vector d = new Vector();
d.add( Boolean.FALSE );.
i got a new column in my table but its not a checkbox
Then you would need to set the default renderer for the first column of the table by updating the TableColumn of the TableColumnModel using the default renderer for the Boolean class:
TableColumn tc = table.getColumnModel().getColumn(0);
tc.setCellRenderer( table.getDefaultRenderer( Boolean.class ) );
i am new to swing
Start with the Swing tutorial on [How to Use Table]
(http://docs.oracle.com/javase/tutorial/uiswing/components/table.html) for the basics of renderers.
Edit:
A simple SSCCE that demonstrate the solution:
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.table.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
Vector<String> header = new Vector<String>();
header.add("Select");
header.add("Column1");
header.add("Column2");
header.add("Column3");
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
for (int row = 0; row < 5; row++)
{
Vector<Object> d = new Vector<Object>();
d.add( Boolean.FALSE );
for (int column = 0; column < 3; column++)
{
d.add(row + " : " + column);
}
data.add(d);
}
DefaultTableModel model = new DefaultTableModel(data, header);
JTable table = new JTable( model );
table.setPreferredScrollableViewportSize(table.getPreferredSize());
TableColumn tc = table.getColumnModel().getColumn(0);
tc.setCellRenderer( table.getDefaultRenderer( Boolean.class ) );
tc.setCellEditor( table.getDefaultEditor( Boolean.class ) );
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new SSCCE() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
I have made a combobox as cell editor of a column. I want when i create a new row the cell in that column should not have the combobox as the cell editor and should retain JTextField as the cell editor. Here is what i have done so far.
addRow(mainWindow.salesTable);
final TableColumn items = mainWindow.salesTable.getColumnModel().getColumn(0);
final JTextField tfield = new JTextField();
DefaultCellEditor editorqty = new DefaultCellEditor(tfield);
items.setCellEditor(editorqty);
private static void addRow(JTable table) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
Vector row = new Vector();
row.add("");
row.add("");
row.add("");
row.add("");
row.add("");
row.add("");
row.add("");
row.add("");
model.addRow(row);
}
Overriding the getCellEditor(...) method of JTble is one approach:
import java.awt.*;
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<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 );
}
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();
}
});
}
}