I'm doing step by step...
Changing LookAndFeel of JTable of Custom Component
Note: I have more custom Columns, this code it's for demonstration porpoise.
Now, I want to implement add Row and Delete Row using a class extended from DefaultTableModel
, for JTable
populated with custom Objects.
Here my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class LAF_TableCustom_AddDelRow {
static JFrame frame = new JFrame();
public JComponent makeUI() {
String[] hdrsObjects = {"PanelSpinnerRadioButton Class Column"};
Object[][] objectMatrix = new Object[3][1];
objectMatrix[0][0] = new PanelSpinnerRadioButtonData(false, 10, 40);
objectMatrix[1][0] = new PanelSpinnerRadioButtonData(true, 20, 40);
objectMatrix[2][0] = new PanelSpinnerRadioButtonData(false, 30, 40);
// JTable table = new JTable(new DefaultTableModel(objectMatrix, hdrsObjects)) {
JTable table = new JTable(new PSRBTableModel(objectMatrix, hdrsObjects)) {
@Override public void updateUI() {
super.updateUI();
setRowHeight(30);
TableColumn tc = getColumn("PanelSpinnerRadioButton Class Column");
tc.setCellRenderer(new PSRBTableCellRenderer());
tc.setCellEditor(new PSRBTableCellEditor());
}
};
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
JPanel pV = new JPanel();
pV.setLayout(new BoxLayout(pV, BoxLayout.PAGE_AXIS));
JButton bAddRow = new JButton("Add Row");
bAddRow.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent evt) {
((PSRBTableModel)table.getModel()).addRow(
new Object[] { new PanelSpinnerRadioButtonData(false, 10, 40) }
);
// ((DefaultTableModel)table.getModel()).addRow(
// new Object[] { new PanelSpinnerRadioButtonData(false, 10, 40) }
// );
}
});
pV.add(bAddRow);
pV.add(scrollPane);
return pV;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
frame.getContentPane().add(new LAF_TableCustom_AddDelRow().makeUI());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(320, 240);
frame.setVisible(true);
});
}
}
class PanelSpinnerRadioButtonData {
private boolean opt02 = false;
private Integer from = 0;
private Integer size = 1;
PanelSpinnerRadioButtonData() {
this(false, 5, 10);
}
PanelSpinnerRadioButtonData(boolean opt02, Integer from, Integer size) {
this.opt02 = opt02;
this.from = from;
this.size = size;
}
public boolean getOption() {
return opt02;
}
public Integer getFrom() {
return from;
}
public Integer getSize() {
return size;
}
}
class PanelSpinnerRadioButton extends JPanel {
public final JRadioButton jrbOption01 = new JRadioButton("01");
public final JRadioButton jrbOption02 = new JRadioButton("12");
public final JSpinner jspnValues = new JSpinner(new SpinnerNumberModel(5, 0, 10, 1));
public final JButton jbRemoveRow = new JButton("Del Row");
private final JPanel panel = new JPanel();
PanelSpinnerRadioButton() {
this(new PanelSpinnerRadioButtonData(false, 20, 40));
}
PanelSpinnerRadioButton(PanelSpinnerRadioButtonData data) {
super();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(jrbOption01);
panel.add(jrbOption02);
panel.add(jspnValues);
panel.add(jbRemoveRow);
jbRemoveRow.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
JTable table = (JTable)SwingUtilities.getAncestorOfClass(
JTable.class, (Component) e.getSource());
int row = table.getEditingRow();
table.getCellEditor().stopCellEditing();
// ((DefaultTableModel) table.getModel()).removeRow(row);
((PSRBTableModel) table.getModel()).removeRow(row);
}
});
ButtonGroup bg = new ButtonGroup();
bg.add(jrbOption01);
bg.add(jrbOption02);
((SpinnerNumberModel) jspnValues.getModel()).setMaximum(data.getSize());
setData(data);
init();
}
private void init() {
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
setBackground(new Color(0, 0, 0, 0));
add(panel);
}
public void setData(PanelSpinnerRadioButtonData data) {
if (data.getOption()) {
jrbOption02.setSelected(true);
} else {
jrbOption01.setSelected(true);
}
((SpinnerNumberModel) jspnValues.getModel()).setValue(data.getFrom());
}
public PanelSpinnerRadioButtonData getData() {
return new PanelSpinnerRadioButtonData(
jrbOption02.isSelected(),
(Integer) ((SpinnerNumberModel) jspnValues.getModel()).getValue(),
(Integer) ((SpinnerNumberModel) jspnValues.getModel()).getMaximum());
}
}
class PSRBTableCellRenderer implements TableCellRenderer {
private final PanelSpinnerRadioButton renderer = new PanelSpinnerRadioButton();
@Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof PanelSpinnerRadioButtonData) {
renderer.setData((PanelSpinnerRadioButtonData) value);
}
return renderer;
}
}
class PSRBTableCellEditor extends AbstractCellEditor implements TableCellEditor {
private final PanelSpinnerRadioButton editor = new PanelSpinnerRadioButton();
@Override public Object getCellEditorValue() {
return editor.getData();
}
@Override public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
if (value instanceof PanelSpinnerRadioButtonData) {
editor.setData((PanelSpinnerRadioButtonData) value);
}
return editor;
}
}
//class PSRBTableModel extends AbstractTableModel {
class PSRBTableModel extends DefaultTableModel {
private final Object[][] data;
private final Object[] columns;
public PSRBTableModel(Object[][] data, Object[] columns) {
this.data = data;
this.columns = columns;
}
@Override public Object getValueAt(int rowIndex, int columnIndex) {
if (data != null) {
if (data.length > 0) {
return data[rowIndex][columnIndex];
}
}
return null;
}
@Override public int getColumnCount() {
return ((columns == null) ? 0: columns.length);
}
@Override public int getRowCount() {
return ((data == null) ? 0: data.length);
}
@Override public Class getColumnClass(int columnIndex) {
if (data != null) {
if (data.length > 0) {
if (data[0][columnIndex] instanceof PanelSpinnerRadioButton) {
return PanelSpinnerRadioButton.class;
}
return data[0][columnIndex].getClass();
}
}
return Object.class;
}
@Override public boolean isCellEditable(int rowIndex, int columnIndex) {
if (data != null) {
if (data.length > 0) {
if (data[0][columnIndex] instanceof PanelSpinnerRadioButton) {
return true;
}
}
}
return true;
}
@Override public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
@Override public String getColumnName(int columnIndex) {
return (String)columns[columnIndex];
}
@Override public void removeRow(int row) {
fireTableRowsDeleted(row, row);
System.out.println("fireTableRowsDeleted(" + row + ", " + row + ");");
}
@Override public void addRow(Object[] rowData) {
super.addRow(rowData);
}
}
The problem!!!
When I pressed the Del Row
Button, the row wasn't deleted!
I got the print message related with the Row: fireTableRowsDeleted(ROW, ROW);
I
When I pressed the Add Row
I got this Exception...
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 3 > 0
at java.util.Vector.insertElementAt(Vector.java:598)
at javax.swing.table.DefaultTableModel.insertRow(DefaultTableModel.java:374)
at javax.swing.table.DefaultTableModel.addRow(DefaultTableModel.java:350)
at javax.swing.table.DefaultTableModel.addRow(DefaultTableModel.java:361)
at PSRBTableModel.addRow(LAF_TableCustom_AddDelRow.java:248)
at LAF_TableCustom_AddDelRow$2.actionPerformed(LAF_TableCustom_AddDelRow.java:45)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
How Can I to do these operations (removeRow, addRow), overriding respective methods with my Custom DefaultTableModel
?
This answer, is not working
EDIT
//Doesn't Work
@Override public void removeRow(int row) {
super.removeRow(row);
}
//Doesn't Work
@Override public void removeRow(int row) {
getDataVector().removeElementAt(row);
fireTableRowsDeleted(row, row);
}
//Doesn't Work (Not overriding the Method)
// @Override public void removeRow(int row) {
// getDataVector().removeElementAt(row);
// }