Ordinare le colonne di una JTable

di il
10 risposte

Ordinare le colonne di una JTable

Buongiorno amici,

mi sto arrovellando per impostare l'allineamento delle colonne di una JTable con 5 colonne di cui 4 visibili, mentre la prima ha la larghezza impostata a 0 per non essere visibile, perché contiene il puntatore al record corrispondente nella tabella del db.

Dopo aver caricato la tabella:

modTabella = CaricaTabella();
Tbl1.setModel(modTabella);
Chiamo il metodo ImpostaAllineamentoTabella:

  public void ImpostaAllineamentoTabella(javax.swing.JTable myTbl, int[] allineamenti) {
    DefaultTableCellRenderer renderAlign = new DefaultTableCellRenderer();

    TableColumn colonna;

    for (int ii=0; ii < allineamenti.length; ii++) {
      colonna = myTbl.getColumnModel().getColumn(ii);
      renderAlign.setHorizontalAlignment(allineamenti[ii]);
      colonna.setCellRenderer(renderAlign);      
    }
  }
che chiamo da con:

final int[] TITLE_ALIG = {SwingConstants.LEFT, SwingConstants.LEFT, SwingConstants.CENTER, SwingConstants.CENTER, SwingConstants.LEFT};

ImpostaAllineamentoTabella(Tbl1, TITLE_ALIG);
dove Tbl1 è la JTable con le colonne da allineare.
Io mi aspettavo che la 1° colonna visibile fosse allineata a sinistra, la 2° e la 3° fossero allineate al centro, mentre la 4° a sinistra.
Il risultato è che sono tutte allineate a sinistra.
Se invece cambio la costante dell'ultimo elemento del vettore TITLE_ALIG in SwingConstants.CENTER tutte le colonne risultano allineate al centro.


Allora ho provato con un vettore:

  public void ImpostaAllineamentoTabella(javax.swing.JTable myTbl, int[] allineamenti) {
    DefaultTableCellRenderer renderAlign = new DefaultTableCellRenderer();

    TableColumn[] colonna = new TableColumn[allineamenti.length];

    for (int ii=0; ii < allineamenti.length; ii++) {
      colonna[ii] = myTbl.getColumnModel().getColumn(ii);
      renderAlign.setHorizontalAlignment(allineamenti[ii]);
      colonna[ii].setCellRenderer(renderAlign);      
    }
  }
Ma si comporta esattamente allo stesso modo.

A questo punto non capisco se sia possibile e come, allineare ogni singola colonna con un diverso allineamento.

Qualcuno per cortesia sa darmi qualche dritta?

10 Risposte

  • Re: Ordinare le colonne di una JTable

    ZioCrick ha scritto:


    
      public void ImpostaAllineamentoTabella(javax.swing.JTable myTbl, int[] allineamenti) {
        DefaultTableCellRenderer renderAlign = new DefaultTableCellRenderer();
    
        TableColumn colonna;
    
        for (int ii=0; ii < allineamenti.length; ii++) {
          colonna = myTbl.getColumnModel().getColumn(ii);
          renderAlign.setHorizontalAlignment(allineamenti[ii]);
          colonna.setCellRenderer(renderAlign);      
        }
      }
    
    A questo punto non capisco se sia possibile e come, allineare ogni singola colonna con un diverso allineamento.
    Certo. Ma devi creare un DefaultTableCellRenderer per ciascuna colonna. Come hai fatto, ne hai creato solo uno fuori da quel for.

    In ogni caso un approccio di questo tipo pone varie altre questioni ....
  • Re: Ordinare le colonne di una JTable

    andbin ha scritto:


    Certo. Ma devi creare un DefaultTableCellRenderer per ciascuna colonna. Come hai fatto, ne hai creato solo uno fuori da quel for.
    E come al solito hai ragione!
    E ancora una volta mi rendo conto che non ho ancora capito i fondamenti di java.

    andbin ha scritto:


    In ogni caso un approccio di questo tipo pone varie altre questioni ....
    Eh, ma non puoi mica lanciare il sassolino e nascondere la mano...
    Dammi almeno qualche indicazione sulle "altre questioni".
    Quindi significa che c'è una soluzione più semplice per ottenere lo stesso risultato?
  • Re: Ordinare le colonne di una JTable

    ZioCrick ha scritto:


    andbin ha scritto:


    In ogni caso un approccio di questo tipo pone varie altre questioni ....
    Eh, ma non puoi mica lanciare il sassolino e nascondere la mano...
    Dammi almeno qualche indicazione sulle "altre questioni".
    Quindi significa che c'è una soluzione più semplice per ottenere lo stesso risultato?
    Innanzitutto il fatto che i table cell renderer normalmente vengono scelti in base al Class fornito dal table model. Esso ha il getColumnClass(int columnIndex) che espone appunto il Class per una colonna. JTable ha una mappatura predefinita (e si può modificare/espandere) che associa un Class ad un renderer.
    Se fai una logica come quella che hai scritto, sostanzialmente vai a "sovrascrivere" quella logica predefinita. Potrebbe non essere affatto un problema se i table model li fai/gestisci tu.

    Poi c'è un aspetto più "visivo". DefaultTableCellRenderer è solo il renderer predefinito ma un Look&Feel ha la facoltà di fare creare dei renderer più sofisticati dal punto di vista grafico o con particolarità su colori ecc... Quindi l'uso di DefaultTableCellRenderer "potrebbe" (il condizionale è molto d'obbligo!) non essere coerente con un certo L&F.
    Ora: con i L&F predefiniti di JavaSE non dovrebbe essere un problema. Ma di L&F se ne possono installare altri e li sarebbe da vedere il risultato grafico. Alla fine, anche ammesso che il risultato non sia coerente, potrebbe piacere oppure no ...
  • Re: Ordinare le colonne di una JTable

    Amico mio, ho aspettato a rispondere, perché ho cercato di capirci qualcosa con varie ricerche in rete relative al getColumnClass... ma purtroppo è ancora un argomento troppo ostico per me.
    Poi parli del Class (al maschile).... e qui sono andato in confusione totale; perché io fin'ora sapevo che esistevano "le" classi (al femminile)
    Quindi significa che ci sono le classi e i class?
    Comincio a credere che Java non sia il linguaggio che fa per me... troppo incasinato

    Ora evidentemente non pretendo che tu mi faccia un mini corso sull'argomento, per cui, se riesci a darmi anche solo qualche lume in più che mi faccia capire, per lo meno, se esiste una alternativa più semplice per ottenere l'allineamento delle colonne di una tabella, senza scomodare questi mistici "table cell renderer", ti ringrazio.
  • Re: Ordinare le colonne di una JTable

    ZioCrick ha scritto:


    Poi parli del Class (al maschile).... e qui sono andato in confusione totale; perché io fin'ora sapevo che esistevano "le" classi (al femminile)
    Quindi significa che ci sono le classi e i class?
    Nel framework di JavaSE esiste la classe java.lang.Class. A runtime, per ogni classe caricata dalla JVM, esiste un oggetto di questa java.lang.Class che serve a "descrivere" quella classe e rappresenta in pratica il punto di ingresso della "reflection" di Java. Tramite java.lang.Class si può scoprire dinamicamente quali campi/metodi/costruttori (e altro) ci sono in una classe, potendoli poi anche invocare dinamicamente tramite appunto reflection.
    Forse è meglio se vedi qualcosa a riguardo ....

    Banalmente, es.:
    import java.lang.reflect.Field;
    
    public class Prova {
        public static void main(String[] args) {
            Class<Persona> cls = Persona.class;
    
            for (Field field : cls.getDeclaredFields()) {
                System.out.println("campo [" + field.getName() + "] di tipo: " + field.getType());
            }
        }
    }
    
    class Persona {
        private String nome;
        private String cognome;
        private int annoNascita;
    
        // altro ......
    }
    Nell'esempio, a runtime esiste un singolo oggetto di tipo java.lang.Class (Persona.class è il riferimento a quel singolo oggetto) che serve a descrivere la classe Persona.

    ZioCrick ha scritto:


    Comincio a credere che Java non sia il linguaggio che fa per me... troppo incasinato
    Basta studiare con un po' di impegno ....

    ZioCrick ha scritto:


    una alternativa più semplice per ottenere l'allineamento delle colonne di una tabella, senza scomodare questi mistici "table cell renderer", ti ringrazio.
    No, purtroppo i table cell renderer entrano comunque in gioco se l'obiettivo è controllare l'aspetto della cella in quel modo ..
  • Re: Ordinare le colonne di una JTable

    Grazie Andrea per la tua pazienza, ma in me la confusione sta aumentando... ne so ancora troppo poco e non riesco a trovare materiale che spieghi in modo chiaro e possibilmente in italiano questi argomenti.
    In rete ho trovato qualcosa che parla del Package Reflection, ma mostra degli esempi che non riesco ad applicare alla JTable.

    Da quel che capisco invece di usare un DefaultTableCellRenderer dovrei usare quello assegnato alla JTable e dovrei ricavarlo con la getColumnClass(int columnIndex) giusto?

    Ho cercato di applicare quel metoto alla jTable e al suo table model ma poi non riesco a capire come ottenere il TableCellRenderer usato dalla JTable.

    Non ne sto uscendo.

    Non è che mi potresti mostrarmi un piccolo esempio?
  • Re: Ordinare le colonne di una JTable

    ZioCrick ha scritto:


    In rete ho trovato qualcosa che parla del Package Reflection, ma mostra degli esempi che non riesco ad applicare alla JTable.
    Non ti serve la reflection per usare JTable o i renderer. L'esempio fatto prima era solo per mostrarti cosa è e a cosa può servire un Class (java.lang.Class), dato che non ti era chiaro cosa fosse "Class". Tutto lì.

    ZioCrick ha scritto:


    Da quel che capisco invece di usare un DefaultTableCellRenderer dovrei usare quello assegnato alla JTable e dovrei ricavarlo con la getColumnClass(int columnIndex) giusto?
    No, non è quello il "punto". Se per dire è stato usato il DefaultTableModel, esso per default (cioè senza estenderlo) restituisce Object.class per TUTTE le colonne. Quindi il renderer scelto è di fatto uno solo, usato per tutte le colonne. Non ci faresti nulla di utile ...

    Il modo minimale per gestire l'allineamento arbitrario è quello che stavi facendo all'inizio, dove io ho solo corretto dicendo di creare N DefaultTableCellRenderer invece che uno solo. Questo approccio NON è di per sé sbagliato. Ma è da prendere con le pinze. Perché può sicuramente funzionare per table model basilari o comunque che crei tu. Ma non in senso universale.
  • Re: Ordinare le colonne di una JTable

    andbin ha scritto:


    Il modo minimale per gestire l'allineamento arbitrario è quello che stavi facendo all'inizio, dove io ho solo corretto dicendo di creare N DefaultTableCellRenderer invece che uno solo. Questo approccio NON è di per sé sbagliato. Ma è da prendere con le pinze. Perché può sicuramente funzionare per table model basilari o comunque che crei tu. Ma non in senso universale.
    Ah ecco! Inizia a sparire un po' di confusione.
    Però la mia curiosità è oceanica, per cui mi viene spontanea la domanda: se io volessi realizzare una soluzione "universale" cosa dovrei utilizzare?
    Chiedo troppo?
  • Re: Ordinare le colonne di una JTable

    ZioCrick ha scritto:


    se io volessi realizzare una soluzione "universale" cosa dovrei utilizzare?
    Guarda .. non sarebbe banale. Ma lo spiego con un caso ben particolare. Se il Class di una colonna è Icon.class (o più specificatamente ImageIcon.class) si può mostrare una immaginetta nella cella. Chiaramente il getValueAt del model deve restituire materialmente un oggetto Icon/ImageIcon.

    Il punto è che JTable in questo caso sceglie un suo renderer predefinito che è una estensione del DefaultTableCellRenderer ma che è specializzata nel settare l'icona nel JLabel usando setIcon().
    Il DefaultTableCellRenderer basilare invece usa solo setText che si basa sul toString() dell'oggetto fornito dal model, quindi se tu su quella colonna "sovrascrivi" il renderer con il tuo DefaultTableCellRenderer, vedresti una stringa che non ha senso.

    A naso si dovrebbe fare: scoprire che il class della colonna è Icon.class/ImageIcon.class, ottenere quel renderer predefinito, clonarlo e quindi settargli un altro allineamento.
    Nota che un renderer tipicamente estende lo stesso componente che restituisce. Di fatto DefaultTableCellRenderer estende JLabel che è appunto clonabile.
  • Re: Ordinare le colonne di una JTable

    Caro Andrea, ti ringrazio sinceramente per la disponibilità .
    Mi rendo conto che per il mio livello di conoscenza è "aramaico antico".
    Quindi continuerò ad usare la soluzione iniziale, sperando di arrivare, un giorno, a capirci qualcosa di più.
Devi accedere o registrarti per scrivere nel forum
10 risposte