Uso un TableCellRenderer
personalizado con JFormattedTextField
múltiple en las celdas de la tabla. Uso el mismo componente que TableCellEditor
. Ahora necesito saber en qué JFormattedTextField
hizo clic el usuario, y también dónde en este campo (se puede hacer con viewToModel
).¿Cómo puedo obtener el componente en la posición de clic del mouse, cuando uso un TableCellEditor?
Cuando se utiliza una costumbre TableCellEditor
, la única manera de conseguir el Point
desde el clic del ratón es el método isCellEditable(EventObject e)
en CellEditor
. El Point
dado está en el sistema de coordenadas de los padres.
anEvent está en el sistema de coordenadas del componente que invoca.
Pero, ¿cómo puedo obtener el componente en la coordenada cliqueada? Lo he intentado con findComponentAt(Point p)
pero devuelve null
para mí.
Aquí hay un código He probado con:
@Override
public boolean isCellEditable(EventObject e) {
if(e instanceof MouseEvent) {
MouseEvent ev = (MouseEvent)e;
Point p = ev.getPoint();
// gives strange values
Point p3 = editor.getLocation();
// x: 0 y: 0
Point tp = ((JTable)e.getSource()).getLocation();
// these returns null
Component c1 = renderer.findComponentAt(p);
Component c2 = editor.findComponentAt(p);
System.out.println("Click at " + p + " editor at: " + p3);
}
return true;
}
Los valores para la ubicación del componente editor.getLocation();
da valores casi aleatorios para la coordenada (por ejemplo, cuando se utiliza 5 filas de la tabla).
¿Cómo puedo obtener el componente que el usuario hizo clic cuando usa un TableCellEditor
y un TableCellRenderer
?
Aquí es un ejemplo completo:
public class FormattedTableEditDemo extends JFrame {
public FormattedTableEditDemo() {
MyTableModel model = new MyTableModel();
MyTableCellEditorAndRenderer cellEditorAndRenderer =
new MyTableCellEditorAndRenderer();
JTable table = new JTable(model);
table.setDefaultRenderer(BigDecimal.class, cellEditorAndRenderer);
table.setDefaultEditor(BigDecimal.class, cellEditorAndRenderer);
table.setRowHeight(40);
add(new JScrollPane(table));
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
class MyTableCellEditorAndRenderer extends AbstractCellEditor
implements TableCellEditor, TableCellRenderer {
MyCellPanel editor = new MyCellPanel();
MyCellPanel renderer = new MyCellPanel();
@Override
public Object getCellEditorValue() {
return editor.getValue();
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
renderer.setValue(value);
return renderer;
}
@Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
editor.setValue(value);
return editor;
}
@Override
public boolean shouldSelectCell(EventObject e) {
return false;
}
@Override
public boolean isCellEditable(EventObject e) {
if(e instanceof MouseEvent) {
MouseEvent ev = (MouseEvent)e;
Point p = ev.getPoint();
// gives strange values
Point p3 = editor.getLocation();
// x: 0 y: 0
Point tp = ((JTable)e.getSource()).getLocation();
// these returns null
Component c1 = renderer.findComponentAt(p);
Component c2 = editor.findComponentAt(p);
System.out.println("Click at " + p + " editor at: " + p3);
}
return true;
}
}
class MyCellPanel extends JPanel {
JFormattedTextField field1 = new JFormattedTextField();
JFormattedTextField field2 = new JFormattedTextField();
public MyCellPanel() {
field1.setColumns(8);
field2.setColumns(8);
field2.setValue(new BigDecimal("0.00"));
setLayout(new BorderLayout());
add(field1, BorderLayout.WEST);
add(Box.createHorizontalStrut(30));
add(field2, BorderLayout.EAST);
}
public Object getValue() {
return field1.getValue();
}
public void setValue(Object value) {
field1.setValue(value);
}
}
class MyTableModel extends AbstractTableModel {
List<BigDecimal> values = new ArrayList<BigDecimal>();
public MyTableModel() {
// test values
values.add(new BigDecimal("37.00"));
values.add(new BigDecimal("4305.90"));
values.add(new BigDecimal("386.04"));
values.add(new BigDecimal("3486.58"));
values.add(new BigDecimal("6546.45"));
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public int getRowCount() {
return values.size();
}
@Override
public Object getValueAt(int row, int column) {
return values.get(row);
}
@Override
public boolean isCellEditable(int row, int column) {
return true;
}
@Override
public Class<?> getColumnClass(int column) {
return BigDecimal.class;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new FormattedTableEditDemo();
}
});
}
}
+1 para sscce, pero ¿por qué no escuchar el campo deseado? – trashgod
@trashgod: No recibe 'MouseEvent' cuando se usa en' TableCellEditor' a menos que la celda ya tenga foco. 'isCellEditable' es la única forma en que puedo recibir el' MouseEvent' al hacer clic en una fila que no tiene foco. – Jonas
No, me refiero a omitir el 'MouseEvent' por completo y agregar un oyente adecuado (acción, propiedad, etc.) a cada' JFormattedTextField'. – trashgod