Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    JTable: Ridefinizione comportamento button

    Buongiorno a tutti,


    Ho una JTable nella quale sono registrati degli eventi (presi opportunamente da un DB).
    Alla fine, come ultima colonna, ho un mio bottone che se cliccato ha il compito di scaricare un documento da internet, scandirlo e caricare dei risultati nel DB, in un tempo apprezzabile (max 10-15 secondi, ma più la rete è lenta più cresce il tempo dell'operazione).


    Fino a qualche tempo non avevo problemi in quanto era tutto nel thread principale dell'EDT
    quindi al click del bottone stava tutto bloccato per il tempo necessario.
    Adesso ho implementato uno SwingWorker con un JProgressBar che mi permette di tenere libero l'EDT, e quindi di far girare il mio Progressbar, e far vedere che l'applicazione è viva è che sta girando correttamente.


    Visto che i tasti non devono essere cliccati in maniera contemporanea come faccio a dire di bloccare la colonna dei tasti?


    Ho la mia classe TableModelFrame che estende DefaultTableModel e li si trova il mio metodo isCellEditable(int row, int column) dove viene data istruzione di quali colonne devono essere editabili e quali no.

    Al momento in cui vengono fatte queste operazioni richieste sono su un'altra classe (ButtonEditor) che descrive il comportamento del bottone.


    Come faccio a richiamare il metodo isCellEditable sul mio TableModelFrame e ridefinire il comportamento, dato che al momento della conclusione delle operazioni deve ritornare al comportamento precedente?


    Grazie.
    Ciao.

    Allego la mia SwingWorkerClass dove dovrò editare il comportamento della colonna dei bottoni
    codice:
    class SwingWorkerClass extends SwingWorker<Void, Void> {   
        private ProgressPanel progressBar;
        private Risultato r;
        private ButtonEditor ed;
        private TableFrame aframe;
    
    
        public SwingWorkerClass(ProgressPanel aProgressBar, ButtonEditor ed, Risultato ris, TableFrame frame) {        
            this.progressBar = aProgressBar;
            r=ris;
            this.ed=ed;
            aframe=frame;
            //editare comportamento colonna tasti tabella ?!?!?
            progressBar.setVisible(true);
        
        }
    
    
        @Override
        public Void doInBackground() {
            //long running task
            ed.modifyResult(r);
            return null;
        }    
    
    
        @Override
        public void done() {                
             //ridefinire vecchio comportamento colonna tasti tabella ?!?!?
            progressBar.setVisible(false);      
        }
    }
    Ultima modifica di schumy2000; 24-02-2016 a 18:13
    I computer sono incredibilmente veloci, accurati e stupidi.
    Gli uomini sono incredibilmente lenti, inaccurati e intelligenti.
    Insieme sono una potenza che supera l'immaginazione.

    A.Einstein

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da schumy2000 Visualizza il messaggio
    Visto che i tasti non devono essere cliccati in maniera contemporanea come faccio a dire di bloccare la colonna dei tasti?
    Se hai messo dei pulsanti nelle celle, devi per forza aver implementato un renderer e un editor appositi per visualizzare/gestire il pulsante nelle celle.
    In generale l'editor si attiva solo se la cella è "editabile", cioè dipendentemente da cosa restituisce isCellEditable del table model.
    Se hai implementato un tuo table model (che tipicamente estende AbstractTableModel), e vuoi (s)bloccare l'intera colonna dei pulsanti, nessuno ti vieta di mettere nel tuo table model un metodo es.

    public void setButtonsEnable(boolean enabled)

    Chiaramente serve mantenere una variabile di istanza per questo stato. Poi nel isCellEditable, se la colonna è quella dei pulsanti, restituisci questo flag.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  3. #3
    Per quanto posso aver capito tramite public void setButtonsEnable(boolean enabled) cambio una varibile booleana che gestirà il mio cellEditor e di riflesso il comportamento della colonna.
    Indi nella swingworker devo portami l'istanza della mia
    TableModelFrame...
    Stasera provo.
    Grazie del suggerimento
    Ultima modifica di schumy2000; 24-02-2016 a 18:53
    I computer sono incredibilmente veloci, accurati e stupidi.
    Gli uomini sono incredibilmente lenti, inaccurati e intelligenti.
    Insieme sono una potenza che supera l'immaginazione.

    A.Einstein

  4. #4
    Perfetto.
    Funziona alla grande.

    nel TableModelFrame:
    codice:
    public class TableModelFrame extends DefaultTableModel {//ormai ho estesto il DefaultTableModel e fuziona bene
       ...
        private boolean buttonsVisible;
        ...
    
        public TableModelFrame(Object[][] data, Object[] title, String tipo) {      ...
           ....
           buttonsVisible=true;
        }
    
        public void setButtonVisible(boolean visible){
            this.buttonsVisible=visible;
        }
    
        public boolean isCellEditable(int row, int column) {
           ....
           ....
           ....
           if(buttonsVisible) {         
              if(column==3 || column==4 || column==7 )  return true;
              else return false;
          }
          else return false;
          
        }
    
    ...
    ...

    e facilmente nello SwingWorker:
    codice:
    class SwingWorkerClass extends SwingWorker<Void, Void> {   
        private ProgressPanel progressBar;
        private Risultato r;
        private ButtonEditor ed;
        private TableModelFrame a_model;
    
    
        public SwingWorkerClass(ProgressPanel aProgressBar, ButtonEditor ed, Risultato ris, TableModelFrame m_model) {        
            this.progressBar = aProgressBar;
            r=ris;
            this.ed=ed;
            a_model=m_model;
            a_model.setButtonVisible(false);
            progressBar.setVisible(true);
        
        }
    
    
        @Override
        public Void doInBackground() {
            //long running task
            ed.modifyResult(r);
            return null;
        }    
    
    
        @Override
        public void done() {                
            a_model.setButtonVisible(true);
            progressBar.setVisible(false);      
        }


    Ma se io volessi anche rendere quel bottone come se fosse disabled (in grigetto per intenderci) come dovrei operare?ù
    Dovrei modificare il renderer dei bottoni? (fra l'altro già presente nella mia classe ButtonRenderer)


    Grazie.
    Ultima modifica di schumy2000; 25-02-2016 a 12:32
    I computer sono incredibilmente veloci, accurati e stupidi.
    Gli uomini sono incredibilmente lenti, inaccurati e intelligenti.
    Insieme sono una potenza che supera l'immaginazione.

    A.Einstein

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da schumy2000 Visualizza il messaggio
    Ma se io volessi anche rendere quel bottone come se fosse disabled (in grigetto per intenderci) come dovrei operare?
    Chissà perché ma mi aspettavo che lo chiedevi, perché è abbastanza utile/logico.

    Innanzitutto, solo a livello dei nomi, nel tuo codice parli di setButtonVisible, buttonsVisible, ecc.. ma in realtà questo non ha a che fare con la "visibilità" ma con la editabilità. E riguardo alle celle vuol dire poter cliccare o meno il pulsante e quindi è sostanzialmente una questione di "abilitazione" (per questo ti avevo detto setButtonsEnable). Ma è solo una questione di nome ... poco conto.

    Torniamo alla questione del disabled. Servono 2 cose:

    Innanzitutto hai sicuramente implementato un renderer apposito. Lì dentro ricevi il JTable, row/column e altro nel metodo getTableCellRendererComponent. row/column sono gli indici nella view (non nel model!) e quindi sono appropriati per usarli nel isCellEditable di JTable (e non del model). Quindi invochi isCellEditable per quella cella del pulsante e setti il true/false direttamente al setEnabled del pulsante.

    Ma così non è ancora completo. Quando invochi il tuo setButtonVisible sul table model adesso aggiorni solo la variabile di istanza. Questo di per sé non causa alcun aggiornamento "visivo". Serve fare anche il "fire" dell'evento di notifica apposito. Purtroppo tra i vari fireXXX() di AbstractTableModel non ce n'è uno apposito che descrive la modifica su una intera colonna. Ma TableModelEvent è in grado di rappresentare questo tipo di aggiornamento. Ti basta usare il costruttore:

    TableModelEvent(TableModel source, int firstRow, int lastRow, int column)

    A quel punto: quando invochi setButtonVisible: a) aggiorni la variabile di istanza, b) notifichi l'update di quella colonna dei pulsanti, c) JTable scatenerà l'update visivo che invocherà di nuovo il renderer per le celle di quella colonna e quindi il setEnabled che ho detto prima verrà usato.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  6. #6
    Bene, una procedura più corposa.
    Si ho il renderer, la mia classe ButtonRenderer e sviluppato il getTableCellRendererComponent che fà un bel pò di cose.

    Inoltre ho sviluppato una classe che si chiama Tabella che eredita da JTable, tant'è che quando devo istanziare la table (dove mi serve) istanzio direttamente la classe Tabella, quindi penso dovrò sviluppare il isCellEditable nella classe Tabella e fino a qua ci siamo.

    Per quanto riguarda il
    TableModelEvent non l'ho sviluppato ma in un'altro progettino usavo una classe che implementava il TableModelListener quindi tramite il metodo tableChanged selezionavo un checkbox nella colonna di una tabella e automaticamente doveva flaggare un'altro flag e viceversa, cosi si scandiva tutta colonna vedeva qual'era flaggato e automaticamente flaggava l'altro vicino.

    Ma nel mio caso come faccio a notificare questa aggiornamento?
    tramite il TableModelEvent? come?

    Credo di aver compreso tutto la procedura, e mi serve solo comprendere questo piccolo passo.

    Grazie.
    Ultima modifica di schumy2000; 25-02-2016 a 16:01
    I computer sono incredibilmente veloci, accurati e stupidi.
    Gli uomini sono incredibilmente lenti, inaccurati e intelligenti.
    Insieme sono una potenza che supera l'immaginazione.

    A.Einstein

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da schumy2000 Visualizza il messaggio
    Bene, una procedura più corposa.
    Per niente! Vengono fuori poche righe di codice in più.

    Quote Originariamente inviata da schumy2000 Visualizza il messaggio
    quindi penso dovrò sviluppare il isCellEditable nella classe Tabella
    No, è già di JTable.

    Quote Originariamente inviata da schumy2000 Visualizza il messaggio
    Per quanto riguarda il TableModelEvent non l'ho sviluppato
    No, TableModelEvent è già del framework (come ActionEvent, MouseEvent, ecc...). Devi solo istanziarlo.

    Quote Originariamente inviata da schumy2000 Visualizza il messaggio
    Ma nel mio caso come faccio a notificare questa aggiornamento?
    Nel getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)

    codice:
    boolean editable = table.isCellEditable(row, column);
    pulsante.setEnabled(editable);

    L'unica cosa che non posso sapere è se crei un JButton al volo ogni volta oppure se (come è più tipico), il renderer IS-A JButton.

    Mentre nel tuo setButtonVisible:

    codice:
        public void setButtonVisible(boolean visible){
            this.buttonsVisible = visible;
    
            fireTableChanged(new TableModelEvent(this, 0, getRowCount()-1, nnn));
        }

    Dove nnn è l'indice di colonna dei pulsanti. Se hai più colonne di pulsanti coinvolte, semplicemente replica la riga.


    E non mi dire che è "corposa".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  8. #8
    Ho testato e purtroppo non va.
    Forse perché il mio table model estende DefaultTableModel.
    I computer sono incredibilmente veloci, accurati e stupidi.
    Gli uomini sono incredibilmente lenti, inaccurati e intelligenti.
    Insieme sono una potenza che supera l'immaginazione.

    A.Einstein

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da schumy2000 Visualizza il messaggio
    Forse perché il mio table model estende DefaultTableModel.
    Quasi sicuramente no, DefaultTableModel estende AbstractTableModel, quindi ha i fireXXX ecc...

    Senza vedere cosa hai scritto esattamente, chiaramente non saprei dire molto di più.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da schumy2000 Visualizza il messaggio
    Forse perché il mio table model estende DefaultTableModel.
    Quasi sicuramente no, DefaultTableModel estende AbstractTableModel, quindi ha i fireXXX ecc...

    Senza vedere cosa hai scritto esattamente, chiaramente non saprei dire molto di più.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.