Newsgroup: it.comp.java
Titolo: MyListener non mi funziona

public class MyListener implements ActionListener,TableModelListener{
            @Override
  public void tableChanged( TableModelEvent e ) {
 
	int row = e.getFirstRow();
 
 
String cellValue = String.valueOf( GridClienti.getValueAt(row, 1) );
txtMostra.setText(cellValue);
@Override
public void actionPerformed( ActionEvent evt ) {
int row = GridClienti.getSelectedRow();
String nvalue = String.valueOf( GridClienti.getValueAt(row,1) );
txtMostra.setText(nvalue)			
}
}
 
La chiamata:
GridClienti.getModel().addTableModelListener(new MyListener());
 
La prima colonna è COGNOME.
 
 
-- 
Gulp®
(forse mi sono perso qualcosa :))


Visto cosi' direi che manchi una parentesi graffa a chiusura del metodo 
tableChanged. Inoltre, txtMostra e GridClienti dove sono definiti?
 
Comunque, l'uso che fai del TableModelEvent non e' mica tanto sicuro, ad 
esempio se fosse un evento generato a fronte di una cancellazione, il 
metodo getFirstRow potrebbe restituire un indice di riga non più 
esistente. Dovresti controllare il tipo di evento tramite 
TableModelEvent.getType() che puo' restituire uno dei valori 
TableModelEvent.INSERT, TableModelEvent.UPDATE o TableModelEvent.DELETE.
 
Inoltre getFirstRow potrebbe restituire TableModelEvent.HEADER_ROW nel 
qual caso l'evento non e' relativo ad una modifica alle righe della 
tabella ma ai suoi metadati.
 
Inoltre, visto che sei interessato solo alla seconda colonna (quella con 
indice 1), dovresti intervenire solo se getColumn restituisce 1 oppure 
TableModelEvent.ALL_COLUMNS.
 
Ti segnalo che GridClienti.getValueAt(row, 1) prevede che tu utilizzi 
gli indici di riga/colonna della JTable, non del model, per cui, visto 
che l'evento ti dice riga e colonna relativi al model e non alla view 
(la JTable), dovresti utilizzare i metodi di JTable 
convertColumnIndexToView, convertRowIndexToView, 
convertColumnIndexToModel e convertRowIndexToModel per passare dal 
sistema righe/colonne del model a quello della view e viceversa. Questo 
perche' il model non e' al corrente di cosa faccia la view delle sue 
righe e colonne, potrebbe essere che l'utente abbia scambiato due 
colonne o magari abbia ordinato le righe. Quindi  i due sistemi non 
coincidono piu'.
 
 
Anche nel metodo actionPerformed fai un uso improprio di getSelectedRow, 
in quanto dovresti controllare che almeno una riga sia selezionata, 
ovvero che getSelectedRow restituisca un valore non negativo.
 

Grazie.
Mamma mia, quante cose.... e ancora tante da imparare.
 
Il mio obiettivo era, allo scroll di riga tramite tastiera o alla 
selezione di una riga tramite click del mouse rilevare il valore di u na 
determinata cella corrispondente alla riga che ha il focus e ad una data 
colonna.
Devo approfondire il discorso relativo al model e a quello che vedo.
Pausa.


 Pausa.
Si', e' fondamentale. Il TableModel conserva i dati e notifica i 
listener quando i dati vengono aggiornati.
La JTable è la view che interagisce con l'utente e notifica il model 
circa le operazioni dell'utente sui dati.
Di per sè, una riga non può essere il focus owner, eventualmente lo puo' 
essere una cella, in quanto renderizzata mediante un JComponent, che può 
essere appunto il focus owner.
In generale, per sapere quale sia la riga che l'utente ha clikkato, 
basta interrogare la tabella mediante il metodo getSelectedRow().
Per sapere quando almeno una riga e' stata selezionata conviene farselo 
dire dal ListSelectionModel mediante un listener.
Ad esempio:
JTable table = new JTable();
ListSelectionModel selectionModel= table.getListSelectionModel();
selectionModel.addListSelectionListener(new ListSelectionListener() {
   public void valueChanged(ListSelectionEvent e) {
     if (!e.getValueIsAdjusting() && e.getFirstIndex() >= 0)
      doTableRowSelected(e.getFirstIndex());
	// oppure, nel caso si voglia gestire la selezione multipla
      doTableRowSelected(new int[] {e.getFirstIndex(),e.getLastIndex()});
 
   }
});
 
nel metodo doTableRowSelected fai quello che devi fare, ma fallo in 
fretta che altrimenti inchiodi la gui, oppure utilizza 
SwingUtilities.invpkeLater per posporre la tua azione alla fine della 
catena degli eventi.

Allora con questo:
  ListSelectionModel selectionModel = GridClienti.getSelectionModel();
         selectionModel.addListSelectionListener(new 
ListSelectionListener() {
             public void valueChanged(ListSelectionEvent e) {
                 handleSelectionEvent(e);
             }
         });
 
e con questo:
 
  protected void handleSelectionEvent(ListSelectionEvent e) {
           if (e.getValueIsAdjusting())
                 return;
 
           int row = GridClienti.getSelectedRow();
 
           String cellValue = String.valueOf( 
GridClienti.getValueAt(row,1) );
	txtCF.setText(cellValue);
 
       }
 
Ci sono riuscito, anche se non è tutta farina del mio sacco e anche se 
son convinto che il modo in cui prelevo l'index di row non sia molto 
ortodosso.
Il mio problema ora è un altro, in realtà la colonna di cui voglio 
visualizzare il valore in txtCF, non è una colonna visualizzata in 
GridClienti, ma presente nel database. E' possibile ottenere lo stesso 
risultato?


 risultato?
Direi di si', ammesso che sappia con quale chiave reperire il record.
Ammesso che il tuo cellValue sia la chiave, potresti:
final String cellValue = String.valueOf(GridClienti.getValueAt(row,1) );
SwingUtilities.invokeLater(new Runnable() {
   public void run() {
     PreparedStatement st = getPreparedStatement();
     st.clearParameters();
     st.setString(1, cellValue);
     Resultset rs = null;
     try {
       rs = st.executeQuery();
       if (rs != null && rs.next())
         txtCF.setText(rs.getString(1);
     } catch(Exception e) {
     } finally {
       if (rs != null)
         try {
           rs.close();
         } catch(Exception e) {}
     }
   }
});
 
 
dove getPreparedStatement() e' un metodo singleton che crea ed 
inizializza il membro "PreparedStatement preparedStatement" della tua 
classe (o di un'altra che lo faccia):
 
private PreparedStatement getPreparedStatement() {
   if (preparedStatement == null)
     preparedStatement = connection
      .prepareStatement("select campo from tabella where chiave = ?");
   return preparedStatement;
}