Uso un numero personalizzato TableCellRenderer
con più JFormattedTextField
nelle celle della tabella. Io uso lo stesso componente di TableCellEditor
. Ora ho bisogno di sapere in cosa JFormattedTextField
l'utente ha fatto clic, e anche dove in questo campo (può essere fatto con viewToModel
).Come posso ottenere il componente nella posizione di clic del mouse, quando si utilizza un TableCellEditor?
Quando si utilizza un personalizzato TableCellEditor
, l'unico modo per ottenere il Point
dal clic del mouse è il metodo isCellEditable(EventObject e)
in CellEditor
. Il dato Point
è nel sistema di coordinate dei genitori.
anEvent è nel sistema di coordinate del componente di richiamo.
Ma come posso ottenere il componente sulla coordinata cliccata? Ho provato con findComponentAt(Point p)
ma restituisce null
per me.
Ecco del codice Ho testato 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;
}
I valori per la posizione del componente editor.getLocation();
dà valori quasi casuali per la coordinata y (ad esempio quando si utilizzano 5 righe della tabella).
Come posso ottenere il componente su cui l'utente ha fatto clic quando si utilizza uno TableCellEditor
e uno TableCellRenderer
?
Ecco un esempio 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 per sscce, ma perché non ascoltare il campo desiderato stesso? – trashgod
@trashgod: non riceve un 'MouseEvent' quando viene utilizzato in un' TableCellEditor' a meno che la cella non abbia già il focus. 'isCellEditable' è l'unico modo in cui posso ricevere' MouseEvent' quando clicco su una riga che non ha lo stato attivo. – Jonas
No, voglio dire saltare il 'MouseEvent' del tutto e aggiungere un listener adatto (azione, proprietà, ecc.) A ciascun' JFormattedTextField'. – trashgod