2011-10-31 22 views
8

Nella mia applicazione ho usato una tabella java che è simile all'esempio this. Il mio problema è quando cambio un valore di una cella (anche nell'esempio sopra) il modello di dati non viene aggiornato finché non clicco su una cella diversa. Perfino clicco sull'area grigia sotto la tabella dopo aver cambiato il valore della cella che il modello non cambierà. Penso che la ragione sia che la cella rimanga focalizzata fino a quando clicco su una cella diversa. Come posso evitare questo e aggiornare il modello senza fare clic sulla cella della tabella. Grazie in anticipoJTable Cell Update non funziona

ho modificare il codice di esempio sopra per riflettere il problema

public class JTableDemo extends JApplet { 
    private JTextArea txt = new JTextArea(4, 20); 

    // The TableModel controls all the data: 
    class DataModel extends AbstractTableModel { 
    Object[][] data = { { "one", "two", "three", "four" }, 
     { "five", "six", "seven", "eight" }, 
     { "nine", "ten", "eleven", "twelve" }, }; 

    // Prints data when table changes: 
    class TML implements TableModelListener { 
     public void tableChanged(TableModelEvent e) { 
     txt.setText(""); // Clear it 
     for (int i = 0; i < data.length; i++) { 
      for (int j = 0; j < data[0].length; j++) 
      txt.append(data[i][j] + " "); 
      txt.append("\n"); 
     } 
     } 
    } 

    public DataModel() { 
     addTableModelListener(new TML()); 
     fireTableDataChanged(); 
    } 

    public int getColumnCount() { 
     return data[0].length; 
    } 

    public int getRowCount() { 
     return data.length; 
    } 

    public Object getValueAt(int row, int col) { 
     return data[row][col]; 
    } 

    public void setValueAt(Object val, int row, int col) { 
     data[row][col] = val; 
     System.out.println(val); 
     // Indicate the change has happened: 
     fireTableDataChanged(); 
    } 

    public boolean isCellEditable(int row, int col) { 
     return true; 
    } 
    } 

    public void init() { 
    Container cp = getContentPane(); 
    JTable table = new JTable(new DataModel()); 
    cp.add(new JScrollPane(table)); 
    cp.add(BorderLayout.SOUTH, txt); 
    } 

    public static void main(String[] args) { 
    run(new JTableDemo(), 350, 200); 
    } 

    public static void run(JApplet applet, int width, int height) { 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.getContentPane().add(applet); 
    frame.setSize(width, height); 
    applet.init(); 
    applet.start(); 
    frame.setVisible(true); 
    } 
} 

Quando si esegue l'esempio è possibile visualizzare il contenuto della tabella nell'area di testo sotto la tabella. Dopo aver aggiornato una cella dovrebbe apparire nella casella di testo qui sotto. Ma il metodo 'setValueAt' non chiamerà finché non clicchi su una cella diversa.

+1

Puoi modificare la domanda e aggiungere un [SSCCE] (http://sscce.org) che mostri il problema? –

+0

sembra come SSCCE +1 – mKorbel

risposta

8

Il meccanismo di aggiornamento predefinito modifica il modello solo quando l'editor delle celle perde lo stato attivo. Entrare fuori dalla cella o fare clic in una cella diversa causerà l'evento vitale "perdita di messa a fuoco" che attiva il cambio di modello.

Fare clic nell'area grigia non ha alcun effetto perché non ci sono elementi attivi che potrebbero elaborare l'evento: la tabella ignora il clic.

Se si desidera modificare questo, è necessario trovare un evento che dice al computer che l'utente è "fatto con modifica". Come fai a saperlo?

[EDIT] Si noti che l'aggiunta di un pulsante "Salva" può interrompere il "flusso" di modifica di utenti (clicca cella di una tabella, modificare, mouse afferrare, mirare, fare clic su Salva, fare clic su cella successiva, tornare a tastiera, modifica, ...)

+0

Come posso usare il pulsante Salva per quello. Sento che può funzionare per me .. – nath

+0

Basta aggiungere un pulsante che non fa nulla con un'etichetta "Salva".Insieme alla proprietà del cliente dalla risposta di kleopatra, questo dovrebbe fare il trucco. Si noti che disturberà notevolmente gli utenti perché significa un clic del mouse aggiuntivo. Prova ad aggiungere un codice mnemonico in modo che le persone possano smettere di editare con "Alt + S" (senza lasciare la tastiera). –

+1

no: un focusLost per impostazione predefinita _non attiva il commit di un commit (che era un problema di vecchia data da anni, fino a quando THEY potrebbe essere convinto almeno a supportare per impostare facoltativamente tale comportamento). In effetti, il commit su tabulazioni o cliccando su un'altra cella è attivato esplicitamente dal codice tableUI – kleopatra

12

Comportamento previsto: il valore modificato non viene eseguito sul modello di supporto fino a quando un utente esplicito non esegue il gesto, ad esempio f.i. premendo invio o tabulazione o facendo clic in un altro punto della tabella ...

Una stranezza (alcuni la chiamano bug :-) di JTable è che la modifica non è terminata per impostazione predefinita quando si trasferisce lo stato attivo sul "fuori" della tabella . Per forzarlo questo modo, è necessario configurarlo come:

table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 

BTW (non correlato, solo per la sanità mentale): sempre fuoco il tipo di evento più a grana fine, ecco che sarebbe un cellUpdated al posto del martello DataChanged .

+0

Mi piace il tuo lunedì, ottima e preziosa risposta +1 – mKorbel