Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Qualcosa mi sfugge sulla JTable

81 views
Skip to first unread message

Biagio

unread,
Dec 16, 2009, 5:47:00 AM12/16/09
to
Ciao a tutti,

sono un principiante e vorrei sapere se il mio approccio è corretto.

Per popolare una JTable faccio questo:

- connessione al database;
- passo il resultset ad un vettore;
- costruisco la TablelModel con il vettore;
- attribuisco la TablelModel alla JTable.

Il problema nasce quando voglio correttamente visualizzare i dati, mi
spiego meglio:

nel database MySql ho una colonna bit per gestire un valore boolean

- se uso row.add(rs.getBoolean(i));
vedo correttamente nella Jtable il checkbox

- se uso row.add(rs.getString(i));
vedo true o false

Lo stesso concetto non funziona con row.add(rs.getDate(i)); e con
row.add(rs.getFloat(i));
in alcuni siti viene suggerito di leggere tutto com getString(i) ma
poi come faccio a specificare che in quella colonna mi deve mostrare
il checkbox ???

Qual'è il giusto approccio, leggere il valore in base al tupo o
trattare tutti i valori come stringhe per poi fare la conversione?

Grazie

Dr.Ugo Gagliardelli

unread,
Dec 16, 2009, 1:39:58 PM12/16/09
to
il 16.12.2009 11.47, Scrive Biagio 43502112:
> Ciao a tutti,
>
> sono un principiante e vorrei sapere se il mio approccio ᅵ corretto.

>
> Per popolare una JTable faccio questo:
>
> - connessione al database;
> - passo il resultset ad un vettore;
> - costruisco la TablelModel con il vettore;
> - attribuisco la TablelModel alla JTable.
>
> Il problema nasce quando voglio correttamente visualizzare i dati, mi
> spiego meglio:
>
> nel database MySql ho una colonna bit per gestire un valore boolean
>
> - se uso row.add(rs.getBoolean(i));
> vedo correttamente nella Jtable il checkbox
>
> - se uso row.add(rs.getString(i));
> vedo true o false
>
> Lo stesso concetto non funziona con row.add(rs.getDate(i)); e con
> row.add(rs.getFloat(i));
> in alcuni siti viene suggerito di leggere tutto com getString(i) ma
> poi come faccio a specificare che in quella colonna mi deve mostrare
> il checkbox ???
>
> Qual'ᅵ il giusto approccio, leggere il valore in base al tupo o

> trattare tutti i valori come stringhe per poi fare la conversione?
>
> Grazie
Il problema e' che JTable usa il DefaultTableCellRenderer che non
funziona per qualsiasi tipo di oggetto, quindi per visualizzare cio' che
non conosce usa il toString() dell'oggetto.
Dovresti estenderlo e ridefinire il metodo
public Class<?> getColumnClass(int columnIndex)
per ritornare la classe delle colonne che ti interessano, ed utilizzare
il metodo
setDefaultRenderer(Class<?> columnClass, TableCellRenderer renderer)
di JTable per specificare il renderer di quella particolare classe.
Non e' difficile creare un renderer, se estendi DefaultTableCellRenderer
puoi ridefinire l'unico metodo getTableCellRendererComponent
dell'interfaccia TableCellRenderer che implementa, intervenendo per le
sole colonne che ti interessano.
Il Component che ritorna
DefaultTableCellRenderer.getTableCellRendererComponent e' sempre una
JLabel che puo' virtualmente rappresentare ogni tipo di grafia.

Biagio

unread,
Dec 16, 2009, 6:00:08 PM12/16/09
to
On 16 Dic, 19:39, "Dr.Ugo Gagliardelli"

<do.not.spam.me.ple...@nettuno.it> wrote:
> il 16.12.2009 11.47, Scrive Biagio 43502112:
>
> > Ciao a tutti,
>
> > sono un principiante e vorrei sapere se il mio approccio è corretto.

>
> > Per popolare una JTable faccio questo:
>
> > - connessione al database;
> > - passo il resultset ad un vettore;
> > - costruisco la TablelModel con il vettore;
> > - attribuisco la TablelModel alla JTable.
>
> > Il problema nasce quando voglio correttamente visualizzare i dati, mi
> > spiego meglio:
>
> > nel database MySql ho una colonna bit per gestire un valore boolean
>
> > - se uso row.add(rs.getBoolean(i));
> > vedo correttamente nella Jtable il checkbox
>
> > - se uso row.add(rs.getString(i));
> > vedo true o false
>
> > Lo stesso concetto non funziona con row.add(rs.getDate(i)); e con
> > row.add(rs.getFloat(i));
> > in alcuni siti viene suggerito di leggere tutto com getString(i) ma
> > poi come faccio a specificare che in quella colonna mi deve mostrare
> > il checkbox ???
>
> > Qual'è il giusto approccio, leggere il valore in base al tupo o

> > trattare tutti i valori come stringhe per poi fare la conversione?
>
> > Grazie
>
> Il problema e' che JTable usa il DefaultTableCellRenderer che non
> funziona per qualsiasi tipo di oggetto, quindi per visualizzare cio' che
> non conosce usa il toString() dell'oggetto.
> Dovresti estenderlo e ridefinire il metodo
> public Class<?> getColumnClass(int columnIndex)
> per ritornare la classe delle colonne che ti interessano, ed utilizzare
> il metodo
>   setDefaultRenderer(Class<?> columnClass, TableCellRenderer renderer)
> di JTable per specificare il renderer di quella particolare classe.
> Non e' difficile creare un renderer, se estendi DefaultTableCellRenderer
>   puoi ridefinire l'unico metodo getTableCellRendererComponent
> dell'interfaccia TableCellRenderer che implementa, intervenendo per le
> sole colonne che ti interessano.
> Il Component che ritorna
> DefaultTableCellRenderer.getTableCellRendererComponent e' sempre una
> JLabel che puo' virtualmente rappresentare ogni tipo di grafia.

Sei stato chiarissimo, ho capito molto di più da te che dalle mille
pagine che ho letto. Mi studio bene questo Class<?> !!!
Ma dimmi, approfitto della tua gentilezza, dal resultset conviene
leggere i valori come stringa ?

Grazie

Biagio

Dr.Ugo Gagliardelli

unread,
Dec 17, 2009, 4:56:44 AM12/17/09
to
il 17.12.2009 0.00, Scrive Biagio 38377736:

> On 16 Dic, 19:39, "Dr.Ugo Gagliardelli"
> <do.not.spam.me.ple...@nettuno.it> wrote:
>> il 16.12.2009 11.47, Scrive Biagio 43502112:
>>
>>> Ciao a tutti,
>>> sono un principiante e vorrei sapere se il mio approccio ᅵ corretto.

>>> Per popolare una JTable faccio questo:
>>> - connessione al database;
>>> - passo il resultset ad un vettore;
>>> - costruisco la TablelModel con il vettore;
>>> - attribuisco la TablelModel alla JTable.
>>> Il problema nasce quando voglio correttamente visualizzare i dati, mi
>>> spiego meglio:
>>> nel database MySql ho una colonna bit per gestire un valore boolean
>>> - se uso row.add(rs.getBoolean(i));
>>> vedo correttamente nella Jtable il checkbox
>>> - se uso row.add(rs.getString(i));
>>> vedo true o false
>>> Lo stesso concetto non funziona con row.add(rs.getDate(i)); e con
>>> row.add(rs.getFloat(i));
>>> in alcuni siti viene suggerito di leggere tutto com getString(i) ma
>>> poi come faccio a specificare che in quella colonna mi deve mostrare
>>> il checkbox ???
>>> Qual'ᅵ il giusto approccio, leggere il valore in base al tupo o

>>> trattare tutti i valori come stringhe per poi fare la conversione?
>>> Grazie
>> Il problema e' che JTable usa il DefaultTableCellRenderer che non
>> funziona per qualsiasi tipo di oggetto, quindi per visualizzare cio' che
>> non conosce usa il toString() dell'oggetto.
>> Dovresti estenderlo e ridefinire il metodo
>> public Class<?> getColumnClass(int columnIndex)
>> per ritornare la classe delle colonne che ti interessano, ed utilizzare
>> il metodo
>> setDefaultRenderer(Class<?> columnClass, TableCellRenderer renderer)
>> di JTable per specificare il renderer di quella particolare classe.
>> Non e' difficile creare un renderer, se estendi DefaultTableCellRenderer
>> puoi ridefinire l'unico metodo getTableCellRendererComponent
>> dell'interfaccia TableCellRenderer che implementa, intervenendo per le
>> sole colonne che ti interessano.
>> Il Component che ritorna
>> DefaultTableCellRenderer.getTableCellRendererComponent e' sempre una
>> JLabel che puo' virtualmente rappresentare ogni tipo di grafia.
>
> Sei stato chiarissimo, ho capito molto di piᅵ da te che dalle mille

> pagine che ho letto. Mi studio bene questo Class<?> !!!
In questo caso Class<?> equivale a Class e basta, in quanto Class<?> e'
come dire Class<? extends Object> ovvero Class<Object> quindi qualsiasi
tipo di classe.

> Ma dimmi, approfitto della tua gentilezza, dal resultset conviene
> leggere i valori come stringa ?
Dipende dallo scopo della "convenienza", dal punto di vista del
linguaggio; supponendo di avere dei metodi specializzati, sarebbe forse
piu conveniente utilizzare, ad esempio:
Object cell = resultset.getObject(columnindex);
addTableCell(cell, columnIndex);

void addTableCell(Number cell, int columnindex)..
void addTableCell(String cell, int columnindex)..
void addTableCell(Boolean cell, int columnindex)..
etc. etc.

L'utilizzo di resultset.getString(columnindex) non sempre sortisce un
effetto praticabile, ad esempio potresti trovarti la rappresentazione di
un numero in notazione scientifica, ad esempio 0.1234 +3 invece di 123,4
come forse lo si vorrebbe rappresentare.

Biagio

unread,
Dec 17, 2009, 11:50:58 AM12/17/09
to
On 17 Dic, 10:56, "Dr.Ugo Gagliardelli"

<do.not.spam.me.ple...@nettuno.it> wrote:
> il 17.12.2009 0.00, Scrive Biagio 38377736:
>
> > On 16 Dic, 19:39, "Dr.Ugo Gagliardelli"
> > <do.not.spam.me.ple...@nettuno.it> wrote:
> >> il 16.12.2009 11.47, Scrive Biagio 43502112:
>
> >>> Ciao a tutti,
> >>> sono un principiante e vorrei sapere se il mio approccio è corretto.

> >>> Per popolare una JTable faccio questo:
> >>> - connessione al database;
> >>> - passo il resultset ad un vettore;
> >>> - costruisco la TablelModel con il vettore;
> >>> - attribuisco la TablelModel alla JTable.
> >>> Il problema nasce quando voglio correttamente visualizzare i dati, mi
> >>> spiego meglio:
> >>> nel database MySql ho una colonna bit per gestire un valore boolean
> >>> - se uso row.add(rs.getBoolean(i));
> >>> vedo correttamente nella Jtable il checkbox
> >>> - se uso row.add(rs.getString(i));
> >>> vedo true o false
> >>> Lo stesso concetto non funziona con row.add(rs.getDate(i)); e con
> >>> row.add(rs.getFloat(i));
> >>> in alcuni siti viene suggerito di leggere tutto com getString(i) ma
> >>> poi come faccio a specificare che in quella colonna mi deve mostrare
> >>> il checkbox ???
> >>> Qual'è il giusto approccio, leggere il valore in base al tupo o

> >>> trattare tutti i valori come stringhe per poi fare la conversione?
> >>> Grazie
> >> Il problema e' che JTable usa il DefaultTableCellRenderer che non
> >> funziona per qualsiasi tipo di oggetto, quindi per visualizzare cio' che
> >> non conosce usa il toString() dell'oggetto.
> >> Dovresti estenderlo e ridefinire il metodo
> >> public Class<?> getColumnClass(int columnIndex)
> >> per ritornare la classe delle colonne che ti interessano, ed utilizzare
> >> il metodo
> >>   setDefaultRenderer(Class<?> columnClass, TableCellRenderer renderer)
> >> di JTable per specificare il renderer di quella particolare classe.
> >> Non e' difficile creare un renderer, se estendi DefaultTableCellRenderer
> >>   puoi ridefinire l'unico metodo getTableCellRendererComponent
> >> dell'interfaccia TableCellRenderer che implementa, intervenendo per le
> >> sole colonne che ti interessano.
> >> Il Component che ritorna
> >> DefaultTableCellRenderer.getTableCellRendererComponent e' sempre una
> >> JLabel che puo' virtualmente rappresentare ogni tipo di grafia.
>
> > Sei stato chiarissimo, ho capito molto di più da te che dalle mille

> > pagine che ho letto. Mi studio bene questo Class<?> !!!
>
> In questo caso Class<?> equivale a Class e basta, in quanto Class<?> e'
> come dire Class<? extends Object> ovvero Class<Object> quindi qualsiasi
> tipo di classe.> Ma dimmi, approfitto della tua gentilezza, dal resultset conviene
> > leggere i valori come stringa ?
>
> Dipende dallo scopo della "convenienza", dal punto di vista del
> linguaggio; supponendo di avere dei metodi specializzati, sarebbe forse
> piu conveniente utilizzare, ad esempio:
> Object cell = resultset.getObject(columnindex);
> addTableCell(cell, columnIndex);
>
> void addTableCell(Number cell, int columnindex)..
> void addTableCell(String cell, int columnindex)..
> void addTableCell(Boolean cell, int columnindex)..
> etc. etc.
>
> L'utilizzo di resultset.getString(columnindex) non sempre sortisce un
> effetto praticabile, ad esempio potresti trovarti la rappresentazione di
> un numero in notazione scientifica, ad esempio 0.1234 +3 invece di 123,4
> come forse lo si vorrebbe rappresentare.

Grazie ai tuoi suggerimenti ho fatto notevoli progressi.

Ho implementato una classe che estende la TableCellRender ed una che
estende la DefaultTableCellRenderer.
Leggo i valori con resultset.getObject(columnindex).

Ora nella mia JTable vedo correttamente il checkbox per i valori true
e false, i numeri allineati a destra e le date nel formato "dd mmm
yyyy". I record vengono mostrati alternando il colore nero e blu per
una lettura facilitata.
Devo solo sistemate i numeri nella rappresentazione ###.###,## e le
date in dd/mm/yyyy. Queste non sono urgenti.

Provengo dal linguaggio CA-Visual Object. Con Java mi trovo benissimo,
ma chiaramente essendo all'inizio mi sembra di avere una montagna
altissima davanti.

Uso NetBeans ma non voglio creare troppo codice automatico perché alla
fine non so più dove mettere le mani per fare le modifiche.
Per questo ho creato una classe generale per gestire dei valori
tabellari, con tutti i metodi necessari al suo funzionamento. In
questo modo posso avere una decina di JDialog diverse che ereditano la
classe generale e con pochissimo codice:
- nome della tabella del database
- nomi dei campi
gestire una serie di tabelle diverse tra loro.

Grazie ancora

Biagio


Dr.Ugo Gagliardelli

unread,
Dec 17, 2009, 1:04:13 PM12/17/09
to
il 17.12.2009 17.50, Scrive Biagio 38511040:
[...]

>
> Grazie ai tuoi suggerimenti ho fatto notevoli progressi.
>
> Ho implementato una classe che estende la TableCellRender ed una che
> estende la DefaultTableCellRenderer.
> Leggo i valori con resultset.getObject(columnindex).
>
> Ora nella mia JTable vedo correttamente il checkbox per i valori true
> e false, i numeri allineati a destra e le date nel formato "dd mmm
> yyyy". I record vengono mostrati alternando il colore nero e blu per
> una lettura facilitata.
> Devo solo sistemate i numeri nella rappresentazione ###.###,## e le
> date in dd/mm/yyyy. Queste non sono urgenti.
>
> Provengo dal linguaggio CA-Visual Object. Con Java mi trovo benissimo,
> ma chiaramente essendo all'inizio mi sembra di avere una montagna
> altissima davanti.

Visto che la montagna e' effettivamente alta, proviamo a darle una limatina.
Per le date ti consiglio qualcosa del genere:

static SimpleDateFormat ddmmyyy = new SimpleDateFormat("dd/MM/yyyy");

poi lo usi cosi':

Date data = ddmmyyyy.parse("17/12/2009");

e viceversa:

String dataConSeparatoriSbagliati = ddmmyyyy.format(new Date());

analogamente puoi utilizzare DecimalFormat, istanziandolo sia
direttamente che utilizzando il suo factory dipendente dalla locale che
indichi. Stando al tuo esempio:

static DecimalFormat fixed2 =
new DecimalFormat("###.##0,0#;-###.##0,0#");

Cosi' pero' non funzionerebbe, in quanto i seperatori decimale e di
ragguppamento cifre non sono quelli americani, pero'puoi creare un
oggetto ad-hoc in questo modo:

static DecimalFormat fixed2 =
new DecimalFormat("###.##0,0#;-###.##0,0#",
new DecimalFormatSymbols(Locale.ITALIAN));

quindi il pattern e' piu' o meno quello che ti aspettavi, ho aggiunto
gli zeri ad indicare il numero minimo di cifre, la seconda parte
separata dal punto e virgola, serve ad indicare la formattazione dei
numeri negativi ed e' opzionale.
Il pattern puo' essere omesso, visto che Decimal format ha metodi
espliciti per indicare le cifre il segno e gli altri aspetti inerenti la
formattazione dei numeri.
L'uso e' analogo:

Number numero = fixed2.parse("1.234,01");

e viceversa:

String numero = fixed2.format(1234.01D);

Biagio

unread,
Dec 17, 2009, 3:45:30 PM12/17/09
to
On 17 Dic, 19:04, "Dr.Ugo Gagliardelli"

Caspita, è un piacere leggerti !!!

Mi dispiace non poter ricambiare, difficilmente in Java potrei
competere.

Non sono un programmatore professionista, ma solo un appassionato di
informatica.
Faccio il commercialista, se hai quesiti in materia fiscale fammelo
sapere :-)))

Corro a provare i suggerimenti per le date e numeri.

Ancora grazie

Biagio

Dr.Ugo Gagliardelli

unread,
Dec 19, 2009, 7:00:49 AM12/19/09
to
il 17.12.2009 21.45, Scrive Biagio 38511040:
[...]
> Caspita, ᅵ un piacere leggerti !!!

>
> Mi dispiace non poter ricambiare, difficilmente in Java potrei
> competere.
>
> Non sono un programmatore professionista, ma solo un appassionato di
> informatica.
> Faccio il commercialista, se hai quesiti in materia fiscale fammelo
> sapere :-)))
>
> Corro a provare i suggerimenti per le date e numeri.
>
> Ancora grazie
>
> Biagio
Grazie delle lusinghiere considerazioni!
In realta' dovrei essere un commercialista anch'io, feci in corso
dell'ordine una ventina d'anni fa', ma poi non ho mai praticato. Forse
ho preso la strada sbagliata, ma come vedi mi diverto di piu' con la
tecnologia informatica!

Biagio

unread,
Dec 19, 2009, 9:10:14 AM12/19/09
to
On 19 Dic, 13:00, "Dr.Ugo Gagliardelli"

<do.not.spam.me.ple...@nettuno.it> wrote:
> il 17.12.2009 21.45, Scrive Biagio 38511040:
> [...]> Caspita, è un piacere leggerti !!!

Bene, abbiamo una formazione comune. Anche per me è una passione che
in alcuni casi mi semplifica la vita in ufficio.
Devo raggiungere un livello accettabile nella programmazione java,
così il confronto potrà essere costruttivo anche per te.

A presto (perché di sicuro mi servirà capire altro ....)

0 new messages