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.