Foro sobre Java SE > Cambiar de columna después de editar JTable
Sin pararme a pensar demasiado, creo que las dimensiones del JTextField deberían definirse según las dimensiones de la celda.
Dicho de otro modo, debe conocerse el tamaño de la celda a la que se va a saltar, y pasarle su dimensión como "preferred size" al JTextField que se va a crear.
ta bien. pero no hay necesidad de:
DefaultCellEditor de = new DefaultCellEditor(new JTextField());
creo...
por defecto el editor es un JTextField. saca eso y deberia andar creo...
sino, lo q dijo choces estaría bien se supone
El editor por defecto es un JCheckBox si los datos de la celda son de tipo Boolean. En ese único caso, no es necesario declarar explícitamente JCheckBox como editor.
http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#combobox
Le paso el JTextField porque cuando creo un nuevo DefaultCellEditor, siempre me pide como parámetro el componente que se usará como editor, en este cado un JTextField.
El asunto es cómo puedo saber el tamaño que le voy a pasar si las celdas pueden tener cualquier tamaño, y dónde haría eso?
Con un método como el que sigue, puedes obtener la anchura del componente renderizado para una fila y columna dadas.
private int getCellWidth(final int row, final int column) {
final TableColumn tableColumn = getColumnModel().getColumn(column);
final TableCellRenderer renderer = tableColumn.getCellRenderer();
final TableCellRenderer cellRenderer = renderer == null ? getDefaultRenderer(getColumnClass(column)) : renderer;
return cellRenderer.getTableCellRendererComponent(JTableExt.this, getModel().getValueAt(row, tableColumn.getModelIndex()), false, false, row, column).getPreferredSize().width;
}
El parámetro JTableExt.this se refiere a que normalmente un método de este tipo se incluye en una clase que extiende JTable; de ahí que se le pase la instancia de la clase JTable extendida.
Naturalmente puedes modificarlo para pasarle cualquier instancia de JTable, si lo incluyes en algún helper.
Para completar la cuestión, con diversas alternativas:
*** Dentro de una clase JTableExt extends JTable
public Component getCellComponent(final int row, final int column) {
final TableColumn tableColumn = getColumnModel().getColumn(column);
final TableCellRenderer renderer = tableColumn.getCellRenderer();
final TableCellRenderer cellRenderer = renderer == null ? getDefaultRenderer(getColumnClass(column)) : renderer;
return cellRenderer.getTableCellRendererComponent(JTableExt .this, getModel().getValueAt(row, tableColumn.getModelIndex()), false, false, row, column);
}
public Dimension getCellComponentSize(final int row, final int column) {
return getCellComponent(row, column).getPreferredSize();
}
*** Dentro de una clase helper
public Component getCellComponent(final JTable table, final int row, final int column) {
final TableColumn tableColumn = table.getColumnModel().getColumn(column);
final TableCellRenderer renderer = tableColumn.getCellRenderer();
final TableCellRenderer cellRenderer = renderer == null ? table.getDefaultRenderer(table.getColumnClass(column)) : renderer;
return cellRenderer.getTableCellRendererComponent(table, table.getModel().getValueAt(row, tableColumn.getModelIndex()), false, false, row, column);
}
public Dimension getCellComponentSize(final JTable table, final int row, final int column) {
return getCellComponent(table, row, column).getPreferredSize();
}
Otra alternativa, más compacta, que usa un método estándar de JTable:
*** Dentro de una clase JTableExt extends JTable
public Component getCellComponent(final int row, final int column) {
return getCellRenderer(row, column).getTableCellRendererComponent(JTableExt.this, getModel().getValueAt(row, getColumnModel().getColumn(column).getModelIndex()), false, false, row, column);
}
public Dimension getCellComponentSize(final int row, final int column) {
return getCellComponent(row, column).getPreferredSize();
}
*** Dentro de una clase helper
public Component getCellComponent(final JTable table, final int row, final int column) {
return table.getCellRenderer(row, column).getTableCellRendererComponent(table, table.getModel().getValueAt(row, table.getColumnModel().getColumn(column).getModelIndex()), false, false, row, column);
}
public Dimension getCellComponentSize(final JTable table, final int row, final int column) {
return getCellComponent(table, row, column).getPreferredSize();
}
En ambos casos, el resultado es el mismo; sin embargo, si se desea iterar por varias filas, con el objeto de obtener los componentes de una columna, estas segundas opciones son menos eficientes, puesto que getCellRenderer(row, column) ejecuta internamente
final TableColumn tableColumn = getColumnModel().getColumn(column);
final TableCellRenderer renderer = tableColumn.getCellRenderer();
final TableCellRenderer cellRenderer = renderer == null ? getDefaultRenderer(getColumnClass(column)) : renderer;
lo que se calcularía para cada fila de la tabla, de la columna en cuestión, sin necesidad.
Es un simple asunto de rendimiento. Se da en el caso de querer empaquetar una columna entera, en función del ancho máximo de entre todas las celdas de esa columna.
saludos a todos.
Ayuda por favor. Tengo un JTable y quiero que cuando estemos editando una celda, al presionar ENTER para finalizar la edición, el cursor pase a la siguiente columna.
Probé con el siguiente código y funciona, pero entonces el Cuadro de Texto donde se editan las celdas sale pequeño, es decir que no se ajusta a las dimensiones de la celda que se está editando:
DefaultCellEditor de = new DefaultCellEditor(new JTextField());
de.addCellEditorListener(new CellEditorListener() {
@Override
public void editingStopped(ChangeEvent e) {
int row = oGrid.getSelectedRow();
int col = oGrid.getSelectedColumn();
if (col<oGrid.getColumnCount()-1){
oGrid.setColumnSelectionInterval(row, col+1);
}
}
@Override
public void editingCanceled(ChangeEvent e) {
}
});
oGrid.setDefaultEditor(Object.class, de);
Alguna idea??
Gracias.