I have a JTable that has four columns. In the second column I have assigned a JComboBox to be the cell editor of my column.The problem that I encountered is that I cannot handle the combobox the way I want.
What I want is that after a user select an item in the combobox, the program should add a new row to the table model and shift the focus to this new row in the first cell. It should then not worry about the remaining columns, I will not allow them to be editable.
Please assist, I will post all the classes below. Thanks for help
Classs 1:
public class Product {
Integer quantity;
String decsription;
Double price;
Double tprice;
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public String getDecsription() {
return decsription;
}
public void setDecsription(String decsription) {
this.decsription = decsription;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Double getTprice() {
return tprice;
}
public void setTprice(Double tprice) {
this.tprice = tprice;
}
public Product() {
this.quantity = 0;
this.decsription = "";
this.price = 0.0;
this.tprice = 0.0;
}}
class 2:
public class Model extends AbstractTableModel {
static final int qi = 0;
static final int di = 1;
static final int ui = 2;
static final int ti = 3;
static final int hi=4;
protected String[] colNames;
protected Vector data;
Model(String[] col) {
this.colNames = col;
this.data = new Vector();
}
@Override
public int getRowCount() {
return this.data.size();
}
@Override
public String getColumnName(int col) {
return this.colNames[col];
}
@Override
public int getColumnCount() {
return this.colNames.length;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Product record = (Product) data.get(rowIndex);
switch (columnIndex) {
case qi:
return record.getQuantity();
case di:
return record.getDecsription();
case ui:
return record.getPrice();
case ti:
return record.getTprice();
default:
return new Object();
}
}
@Override
public boolean isCellEditable(int row, int col) {
return col<=3;
}
@Override
public void setValueAt(Object value, int row, int column) {
Product record = (Product) data.get(row);
switch (column) {
case qi:
record.setQuantity((Integer) value);
break;
case di:
record.setDecsription((String) value);
break;
case ui:
record.setPrice((Double) value);
break;
case ti:
record.setTprice((Double) value);
break;
default:
System.out.println("invalid index");
}
fireTableCellUpdated(row, column);//this is for updating the cell
}
@Override
public Class getColumnClass(int column) {// returns a class representing the datatype of the data stored in that column
switch (column) {
case qi:
return Integer.class;
case di:
return String.class;
case ui:
case ti:
return Double.class;
default:
return Object.class;
}
}
public void addEmptyRow() {
data.add(new Product());
fireTableRowsInserted(
data.size() - 1,
data.size() - 1);
}
public boolean hasEmptyRow() {
if (data.isEmpty()) {
return false;
}
Product productRecord = (Product) data.get(data.size() - 1);
if (productRecord.getDecsription().trim().equals("")
&& productRecord.getPrice() == 0.0
&& productRecord.getQuantity() == 0
&& productRecord.getTprice() == 0) {
return true;
} else {
return false;
}}
class 3:
public final class Table {
JTable table;
JScrollPane sp;
static final String[] columNames = {"Quantity", "Description", "Unity Price", "Total Price", ""};
Model model = new Model(columNames);
String[] values = {"1", "2", "3"};
public Table() {
createTable();
}
public void createTable() {
JFrame f = new JFrame();
f.setSize(300, 300);
f.setVisible(true);
//information regarding the table here
table = new JTable();
table.setModel(model);
table.setSurrendersFocusOnKeystroke(true);
table.setPreferredScrollableViewportSize(new java.awt.Dimension(300, 300));
TableColumn col = table.getColumnModel().getColumn(1);
col.setCellEditor(new myComboBoxEditor(values));
col.setCellRenderer(new MyComboBoxRenderer(values));
sp = new javax.swing.JScrollPane(table);
//information on table model
model.addTableModelListener(new Table.InteractiveTableModelListener());
if (!model.hasEmptyRow()) {
model.addEmptyRow();
}
//
f.add(sp);
TableColumn hidden = table.getColumnModel().getColumn(Model.hi);
hidden.setMinWidth(2);
hidden.setPreferredWidth(2);
hidden.setMaxWidth(2);
hidden.setCellRenderer(new InteractiveRenderer(Model.hi));
}
public void highlightLastRow(int row) {
int lastrow = model.getRowCount();//return the number of rows - last row
if (row == lastrow - 1) {
table.setRowSelectionInterval(lastrow - 1, lastrow - 1);
} else {
table.setRowSelectionInterval(row + 1, row + 1);
}
table.setColumnSelectionInterval(0, 0);//setting it to the first column
}
class InteractiveRenderer extends DefaultTableCellRenderer {
protected int interactiveColumn;
public InteractiveRenderer(int interactiveColumn) {
this.interactiveColumn = interactiveColumn;
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (column == interactiveColumn && hasFocus) {
if ((Table.this.model.getRowCount() - 1) == row
&& !Table.this.model.hasEmptyRow()) {
Table.this.model.addEmptyRow();//this is where we append a new row
}
highlightLastRow(row);//making it get focus and highlighted
}
return c;//returning the component
}
}
public class InteractiveTableModelListener implements TableModelListener {
@Override
public void tableChanged(TableModelEvent evt) {
if (evt.getType() == TableModelEvent.UPDATE) {
int column = evt.getColumn();
int row = evt.getFirstRow();
System.out.println("row: " + row + " column: " + column);
table.setColumnSelectionInterval(column + 1, column + 1);
table.setRowSelectionInterval(row, row);
}
}
}
private class myComboBoxEditor extends DefaultCellEditor {
myComboBoxEditor(String[] items) {
super(new JComboBox(items));
}
}
private class MyComboBoxRenderer extends JComboBox implements TableCellRenderer {
public MyComboBoxRenderer(String[] 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());
}
setSelectedItem(value);
return this;
}
}
public static void main(String[] args) {
Table tab = new Table();
}}