una tabla modificar eliminar datos crear como botones boton borrar agregar java swing jtable jbutton tablecellrenderer

tabla - crear boton modificar en java



¿Cómo hacer que un JButton en una celda JTable se pueda hacer clic? (3)

Tengo un JTable con un procesador de celdas personalizado. La celda es un JPanel que contiene un JTextField y un JButton. El JTextField contiene un entero, y cuando el usuario hace clic en el JButton, el entero debe incrementarse.

El problema es que no se puede hacer clic en JButton cuando lo tengo en una celda JTable. ¿Cómo puedo hacer que se pueda hacer clic?

Aquí está mi código de prueba:

public class ActiveTable extends JFrame { public ActiveTable() { RecordModel model = new RecordModel(); model.addRecord(new Record()); JTable table = new JTable(model); EditorAndRenderer editorAndRenderer = new EditorAndRenderer(); table.setDefaultRenderer(Object.class, editorAndRenderer); table.setDefaultEditor(Object.class, editorAndRenderer); table.setRowHeight(38); add(new JScrollPane(table)); setPreferredSize(new Dimension(600, 400)); pack(); setDefaultCloseOperation(EXIT_ON_CLOSE); setTitle("Active Table"); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new ActiveTable(); } }); } class RecordModel extends AbstractTableModel { private final List<Record> records = new ArrayList<Record>(); @Override public int getColumnCount() { return 1; } @Override public int getRowCount() { return records.size(); } @Override public Object getValueAt(int rowIndex, int columnIndex) { return records.get(rowIndex); } public void addRecord(Record r) { records.add(r); fireTableRowsInserted(records.size()-1, records.size()-1); } } class Record { private int count = 1; public int getCount() { return count; } public void increase() { count = count + 1; } } class CellPanel extends JPanel { private Record record; private final JTextField field = new JTextField(8); private final Action increaseAction = new AbstractAction("+") { public void actionPerformed(ActionEvent e) { record.increase(); field.setText(record.getCount()+""); JTable table = (JTable) SwingUtilities.getAncestorOfClass(JTable.class, (Component) e.getSource()); table.getCellEditor().stopCellEditing(); } }; private final JButton button = new JButton(increaseAction); public CellPanel() { add(field); add(button); } public void setRecord(Record r) { record = r; field.setText(record.getCount()+""); } public Record getRecord() { return record; } } class EditorAndRenderer extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { private final CellPanel renderer = new CellPanel(); private final CellPanel editor = new CellPanel(); @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { renderer.setRecord((Record) value); return renderer; } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { editor.setRecord((Record) value); return editor; } @Override public Object getCellEditorValue() { return editor.getRecord(); } @Override public boolean isCellEditable(EventObject ev) { return true; } @Override public boolean shouldSelectCell(EventObject ev) { return false; } } }


Aquí hay una forma de usar ButtonColumn .

public class TableTest extends JFrame { public TableTest() { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JTable table = new JTable(new TestModel()); table.getColumnModel().getColumn(1).setPreferredWidth(3); table.getColumnModel().getColumn(2).setPreferredWidth(3); this.add(new JScrollPane(table)); Action increase = new AbstractAction("+") { @Override public void actionPerformed(ActionEvent e) { JTable table = (JTable) e.getSource(); int row = Integer.valueOf(e.getActionCommand()); TestModel model = (TestModel) table.getModel(); model.increment(row, 0); } }; ButtonColumn inc = new ButtonColumn(table, increase, 1); Action decrease = new AbstractAction("-") { @Override public void actionPerformed(ActionEvent e) { JTable table = (JTable) e.getSource(); int row = Integer.valueOf(e.getActionCommand()); TestModel model = (TestModel) table.getModel(); model.decrement(row, 0); } }; ButtonColumn dec = new ButtonColumn(table, decrease, 2); pack(); } public static void main(String[] args) { new TableTest().setVisible(true); } } class TestModel extends AbstractTableModel { List<TestRecord> records = new LinkedList<TestRecord>(); private static class TestRecord { private int val = 0; } public void increment(int row, int col) { records.get(row).val++; fireTableCellUpdated(row, 0); } public void decrement(int row, int col) { records.get(row).val--; fireTableCellUpdated(row, 0); } public TestModel() { records.add(new TestRecord()); records.add(new TestRecord()); } @Override public Class<?> getColumnClass(int col) { if (col == 0) { return Integer.class; } else { return ButtonColumn.class; } } @Override public boolean isCellEditable(int row, int col) { return true; } @Override public int getColumnCount() { return 3; } @Override public int getRowCount() { return records.size(); } @Override public Object getValueAt(int row, int col) { if (col == 0) { return records.get(row).val; } else if (col == 1) { return "+"; } else { return "-"; } } }


Basé mi último ejemplo en el código proporcionado por la respuesta de mKrobels a Cómo implementar la GUI dinámica en swing

La principal diferencia entre su ejemplo y el mío en la pregunta es que él usa DefaultTableModel y yo uso AbstractTableModel . Su ejemplo sí funciona, pero no el mío.

La solución que encontré fue que tuve que implementar isCellEditable() en el TableModel, así que con este método agregado, mi ejemplo funciona:

@Override public boolean isCellEditable(int rowIndex, int columnIndex) { return true; }