usar tablas setvalueat setmodel personalizado metodo manejo getrowcount funciona datos como agregar java swing jtable tablemodel

tablas - metodo setmodel java



Preserve la selección de JTable en el cambio de TableModel (7)

Debe conservar la selección y luego volver a aplicarla.

En primer lugar, deberá obtener una lista de todas las celdas seleccionadas.

Luego, cuando vuelva a cargar JTable con los datos nuevos, deberá volver a aplicar las mismas selecciones mediante programación.

El otro punto que quiero hacer es, si el número o filas o columnas en su tabla aumentan o disminuyen después de cada recarga de modelo de tabla, entonces no se preocupe por conservar la selección.

El usuario podría haber seleccionado la columna 2 de la fila 2 con un valor que diga "Pato", antes de la actualización del modelo. Pero después de la actualización del modelo, ahora los mismos datos pueden aparecer en la fila 4, columna 1, y la columna original de la fila 2, columna 1, podría tener datos nuevos, como "Cerdo". Ahora bien, si ajusta por la fuerza la selección a lo que era antes de la actualización del modelo, es posible que esto no sea lo que el usuario quería.

Por lo tanto, la selección programática de celdas podría ser una espada de doble filo. No lo hagas, si no estás seguro.

Vemos que la selección de JTable se borra cuando hacemos fireTableDataChanged() o fireTableRowsUpdated() desde TableModel .

¿Se espera esto, o estamos haciendo algo mal? No vi ninguna propiedad en JTable (u otras clases relacionadas) sobre la selección de limpieza / preservación en las actualizaciones del modelo.

Si este es el comportamiento predeterminado, ¿hay una buena manera de evitar esto? ¿Tal vez alguna forma de "bloquear" la selección antes de la actualización y desbloquearla después?

El desarrollador ha estado experimentando con guardar la selección antes de la actualización y volver a aplicarla. Es un poco lento.

Esto es Java 1.4.2 en Windows XP, si eso importa. Estamos limitados a esa versión basada en algún código de proveedor que usemos.


Estaba enfrentando el mismo problema y cuando intenté buscar el motivo, recibí esta pregunta, pero parece un error en Java SDK. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4276786

TRABAJA ALREDEDOR

Un trabajo temporal temporal está disponible. Se debe eliminar una vez que se solucione este error, ya que su idoneidad NO se ha probado en versiones fijas.

Use esta subclase de JTable.

Nota: Esto es para el MetalLookAndFeel. Si usa otro aspecto, la subclase interna FixedTableUI tendrá que extender la subclase TableUI para esa apariencia.

import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.event.*; import javax.swing.plaf.basic.*; public class FixedTable extends JTable { private boolean isControlDownInDrag; public FixedTable(TableModel model) { super(model); setUI(new FixedTableUI()); } private class FixedTableUI extends BasicTableUI { private MouseInputHandler handler = new MouseInputHandler() { public void mouseDragged(MouseEvent e) { if (e.isControlDown()) { isControlDownInDrag = true; } super.mouseDragged(e); } public void mousePressed(MouseEvent e) { isControlDownInDrag = false; super.mousePressed(e); } public void mouseReleased(MouseEvent e) { isControlDownInDrag = false; super.mouseReleased(e); } }; protected MouseInputListener createMouseInputListener() { return handler; } } public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) { if (isControlDownInDrag) { ListSelectionModel rsm = getSelectionModel(); ListSelectionModel csm = getColumnModel().getSelectionModel(); int anchorRow = rsm.getAnchorSelectionIndex(); int anchorCol = csm.getAnchorSelectionIndex(); boolean anchorSelected = isCellSelected(anchorRow, anchorCol); if (anchorSelected) { rsm.addSelectionInterval(anchorRow, rowIndex); csm.addSelectionInterval(anchorCol, columnIndex); } else { rsm.removeSelectionInterval(anchorRow, rowIndex); csm.removeSelectionInterval(anchorCol, columnIndex); } if (getAutoscrolls()) { Rectangle cellRect = getCellRect(rowIndex, columnIndex, false); if (cellRect != null) { scrollRectToVisible(cellRect); } } } else { super.changeSelection(rowIndex, columnIndex, toggle, extend); } } }

Tenga en cuenta Curtsey a http://bugs.sun.com


Este es el comportamiento predeterminado. Si llama a fireTableDataChanged() toda la tabla se reconstruye desde cero al establecer un modelo completamente nuevo. En este caso, la selección, naturalmente, se pierde. Si llama a fireTableRowsUpdated() la selección también se borrará en casos generales. La única forma es recordar la selección y luego configurar esto. Lamentablemente, no hay garantía de que la selección sea válida. Tenga cuidado si restaura la selección.


Puede conservar automáticamente la selección de una tabla si la ESTRUCTURA de esa tabla no ha cambiado (es decir, si no ha agregado / eliminado ninguna columna / fila) de la siguiente manera.

Si ha escrito su propia implementación de TableModel, puede simplemente anular el método fireTableDataChanged ():

@Override public void fireTableDataChanged() { fireTableChanged(new TableModelEvent(this, //tableModel 0, //firstRow getRowCount() - 1, //lastRow TableModelEvent.ALL_COLUMNS, //column TableModelEvent.UPDATE)); //changeType }

y esto debería garantizar que su selección se mantenga siempre que solo hayan cambiado los datos y no la estructura de la tabla. La única diferencia entre esto y lo que se llamaría si este método no se reemplazara es que getRowCount () - 1 se pasa para el argumento lastRow en lugar de Integer.MAX_VALUE, el último de los cuales actúa como un significante que no solo tiene todos los los datos en la tabla cambiaron pero también el número de filas.


Si recuerdo correctamente, guardar la selección y volver a aplicarla es lo que hemos hecho también ...


Tuve el mismo problema en una aplicación. En mi caso, el modelo en la tabla era una lista de objetos, donde las propiedades del objeto estaban mapeadas en columnas. En ese caso, cuando se modificó la lista, recuperé el índice seleccionado y almacené el objeto que se seleccionó antes de actualizar la lista. Después de que se modifique la lista y antes de que se actualice la tabla, calcularía la posición del objeto seleccionado. Si todavía estaba presente después de la modificación, entonces establecería la selección en el nuevo índice.

Solo establecer el índice seleccionado en la tabla después de la modificación no funcionará, porque el objeto puede cambiar de posición en la lista.

Como nota al margen, encontré que trabajar con GlazedLists hace la vida mucho más fácil cuando se trata de tablas.


para referencia, como @Swapnonil Mukherjee declaró, esto hizo el truco con una tabla con filas seleccionables:

// preserve selection calling fireTableDataChanged() final int[] sel = table.getSelectedRows(); fireTableDataChanged(); for (int i=0; i<sel.length; i++) table.getSelectionModel().addSelectionInterval(sel[i], sel[i]);