Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2009
    Messaggi
    50

    JTable: autoresize secondo il contenuto

    E' possibile settare la size delle colonne in automatico a seconda della size del loro contenuto?

    Grazie
    frapal

  2. #2
    Vengo a conoscenza ora dell'oggetto jTable e mi è bastato andare sulla javadoc per trovare questo metodo:

    setAutoResizeMode

    public void setAutoResizeMode(int mode)

    Sets the table's auto resize mode when the table is resized. For further information on how the different resize modes work, see doLayout().

    Parameters:
    mode - One of 5 legal values: AUTO_RESIZE_OFF, AUTO_RESIZE_NEXT_COLUMN, AUTO_RESIZE_SUBSEQUENT_COLUMNS, AUTO_RESIZE_LAST_COLUMN, AUTO_RESIZE_ALL_COLUMNS

    See Also:
    getAutoResizeMode(), doLayout()
    "Na' sedia te vojo tirà!"

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da frapal
    E' possibile settare la size delle colonne in automatico a seconda della size del loro contenuto?
    Purtroppo non c'è un metodo o sistema già fatto per far sì che le colonne si dimensionino in "automatico" in base al loro contenuto.
    La questione è che il contenuto è visualizzato tramite i ben noti "renderer" ma la larghezza della colonna non è in funzione del renderer .... è il contrario. Cioè è JTable tramite appositi criteri (o il programmatore esplicitamente) a poter impostare una larghezza alla colonna che poi a sua volta si ribalta sulla dimensione del Component (fornito dal renderer) che JTable "stampa" a video.

    Tecnicamente comunque si potrebbe fare, anche se "macchinoso". Prendi il renderer relativo alla colonna X, invochi il renderer (il getTableCellRendererComponent() ) passando tutti i dati compreso il valore della riga i-esima). Per ogni "cella" della colonna prendi il "preferred size" del Component fornito dal renderer. Quindi calcoli il massimo tra tutte le larghezze "preferite" e magari ci sommi qualcosina (penso innanzitutto ai bordi/gap delle celle, vedi i metodi di JTable).
    E ottieni la larghezza complessiva "preferita" per visualizzare al "giusto" quella colonna.

    Ma ripeto, non c'è nulla di già fatto.



    Originariamente inviato da Brazonet
    Vengo a conoscenza ora dell'oggetto jTable e mi è bastato andare sulla javadoc per trovare questo metodo:
    E quindi ora sai tutto di JTable ..... vero?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  4. #4
    Originariamente inviato da andbin

    E quindi ora sai tutto di JTable ..... vero?
    Assolutamente no, ho postato quello che mi è sembrato essere una possibile soluzione.
    "Na' sedia te vojo tirà!"

  5. #5
    Utente di HTML.it
    Registrato dal
    Feb 2009
    Messaggi
    502
    Originariamente inviato da andbin
    Purtroppo non c'è un metodo o sistema già fatto per far sì che le colonne si dimensionino in "automatico" in base al loro contenuto.
    La questione è che il contenuto è visualizzato tramite i ben noti "renderer" ma la larghezza della colonna non è in funzione del renderer .... è il contrario. Cioè è JTable tramite appositi criteri (o il programmatore esplicitamente) a poter impostare una larghezza alla colonna che poi a sua volta si ribalta sulla dimensione del Component (fornito dal renderer) che JTable "stampa" a video.

    Tecnicamente comunque si potrebbe fare, anche se "macchinoso". Prendi il renderer relativo alla colonna X, invochi il renderer (il getTableCellRendererComponent() ) passando tutti i dati compreso il valore della riga i-esima). Per ogni "cella" della colonna prendi il "preferred size" del Component fornito dal renderer. Quindi calcoli il massimo tra tutte le larghezze "preferite" e magari ci sommi qualcosina (penso innanzitutto ai bordi/gap delle celle, vedi i metodi di JTable).
    E ottieni la larghezza complessiva "preferita" per visualizzare al "giusto" quella colonna.

    Ma ripeto, non c'è nulla di già fatto.
    Sul tutorial Sun di JTable c'è un esempio di come fare. Basta adattarlo al proprio modello di tabella.
    L'ho implementato e funziona. Solo che non riesco a capire come fare in modo che la tabella prenda una dimensione preferita.
    Nel senso che io calcolo la larghezza di ogni colonna, e le sommo tutte per ottenere quella che dovrebbe essere la larghezza della tabella totale.
    La tabella è in uno JScrollPane.
    Come posso fare per rendere la tabella di una certa larghezza? E' possibile?
    al volante son nervoso

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Rubox
    Sul tutorial Sun di JTable c'è un esempio di come fare.
    Sul tutorial c'è un esempio (TableRenderDemo.java) che imposta una larghezza alle colonne ma lo fa in modo concettualmente ridotto (e forse poco utile) perché si limita solo a calcolare il massimo tra la larghezza "preferita" dell'header e la larghezza "preferita" della prima riga.

    E non è quello che dicevo io. Io parlavo di andare a prendere la larghezza "preferita" di ogni cella nella colonna e determinare quella massima. E magari (non l'ho detto prima perché subito non ci ho pensato) effettivamente si può inserire in questo calcolo anche la larghezza dell'header.

    Originariamente inviato da Rubox
    La tabella è in uno JScrollPane.
    Come posso fare per rendere la tabella di una certa larghezza?
    Quando un componente è in un JScrollPane succedono 2 cose: a) La dimensione "fisica" reale del componente è tutta la dimensione fisica della "viewport" del JScrollPane. b) JScrollPane si basa o sul fatto che il componente implementa Scrollable oppure sul "preferred size" del componente per sapere se/quanto "scrollare".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2009
    Messaggi
    502
    Originariamente inviato da andbin
    Sul tutorial c'è un esempio (TableRenderDemo.java) che imposta una larghezza alle colonne ma lo fa in modo concettualmente ridotto (e forse poco utile) perché si limita solo a calcolare il massimo tra la larghezza "preferita" dell'header e la larghezza "preferita" della prima riga.

    E non è quello che dicevo io. Io parlavo di andare a prendere la larghezza "preferita" di ogni cella nella colonna e determinare quella massima. E magari (non l'ho detto prima perché subito non ci ho pensato) effettivamente si può inserire in questo calcolo anche la larghezza dell'header.
    Infatti avevo messo che bisogna adattarlo al proprio modello di tabella.
    un ciclo sulle colonne, uno interno sulle righe, si ottiene il componente che renderizza la cella, se ne prende la dimensione preferita, si aggiunge un 20 per bordi e cose strane. Finito questo ciclo sulle righe si prende la dimensione dell'header, aggiungendo anche qui un 20 per bordi.
    Poi se ne fa il massimo e lo si imposta come dimensione preferita di quella colonna.
    Avendo la tabella in un JDialog, dopo ho richiamato pack() (forse inutilmente).

    Originariamente inviato da andbin
    Quando un componente è in un JScrollPane succedono 2 cose: a) La dimensione "fisica" reale del componente è tutta la dimensione fisica della "viewport" del JScrollPane. b) JScrollPane si basa o sul fatto che il componente implementa Scrollable oppure sul "preferred size" del componente per sapere se/quanto "scrollare".
    Io ho impostato AutoResizeMode della tabella a AUTO_RESIZE_OFF e la tabella mi appare con la dimensione voluta per le colonne. Se restringo la JDialog, compare correttamente la barra del JScrollPane in cui è inserita. Se allargo la JDialog, mi appare lo sfondo della JDialog. E non è il massimo.

    Se imposto la dimensione minima delle colonne della tabella, e restringo la JDialog, non mi compare la barra di scorrimento orizzontale del JScrollPane
    Lo so che sto sbagliando qualcosa, ma cosa non lo capisco.
    al volante son nervoso

  8. #8
    Utente di HTML.it
    Registrato dal
    Oct 2009
    Messaggi
    50
    Effettivamente avevo il sentore che fosse una cosa complessa!
    Grazie a tutti per il contributo.

    frapal

  9. #9
    Utente di HTML.it
    Registrato dal
    Feb 2009
    Messaggi
    502
    Originariamente inviato da frapal
    Effettivamente avevo il sentore che fosse una cosa complessa!
    Grazie a tutti per il contributo.

    frapal
    Non è complessa. E' più complicato a dirlo che a farlo.
    Il difficile sta solo nel provare poi dopo varie impostazioni per avere il risultato che uno si aspetta.
    L'impostazione della larghezza delle colonne che ho ottenuto è soddisfacente (oddio, ci vuole la i?? ), specialmente dovendo stampare la tabella con il suo comando print sono sicuro che le celle sono tutte visualizzate.
    al volante son nervoso

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Il seguente è un mio esempio completo che mostra come calcolare/impostare la larghezza delle colonne in base al loro contenuto.
    Ho cercato di gestire la cosa nel modo più generico possibile (e per come mi viene in mente ora), cercando di tenere presente:
    - Lo spostamento (drag) delle colonne (quindi indici di colonne in view e model possono non corrispondere più).
    - Lo spacing delle colonne.
    - Un renderer "esplicito" per celle e header.

    Spero di aver considerato tutto ....
    Provare a ridimensionare/draggare le colonne e poi premete il pulsante "Adjust Widths" e .... vedete.

    Tutta la logica è nel metodo statico setupTableWidths(JTable), quindi molto contenuto e riutilizzabile!


    codice:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class TableSizeTestFrame extends JFrame {
        private JTable testTable;
        private JButton adjustButton;
    
        public TableSizeTestFrame() {
            super("Table Size Test");
    
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            setSize(400, 300);
    
            Object[] columnNames = { "Acronym", "Description" };
    
            Object[][] tableData = {
                { "AWT"  , "Abstract Windowing Toolkit"                },
                { "CORBA", "Common Object Request Broker Architecture" },
                { "EJB"  , "Enterprise JavaBean"                       },
                { "JDK"  , "Java Development Kit"                      },
                { "JRE"  , "Java Runtime Environment"                  },
            };
    
            testTable = new JTable(tableData, columnNames);
            JScrollPane scrollPane = new JScrollPane(testTable);
            adjustButton = new JButton("Adjust Widths");
    
            getContentPane().add(scrollPane, BorderLayout.CENTER);
            getContentPane().add(adjustButton, BorderLayout.SOUTH);
    
            adjustButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    setupTableWidths(testTable);
                }
            });
    
            setupTableWidths(testTable);
        }
    
        private static void setupTableWidths(JTable table) {
            JTableHeader tableHeader = table.getTableHeader();
            TableModel model = table.getModel();
            TableColumnModel columnModel = table.getColumnModel();
            Dimension spacing = table.getIntercellSpacing();
    
            table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    
            int columns = model.getColumnCount();
            int rows = model.getRowCount();
    
            for (int c = 0; c < columns; c++) {
                int viewCol = table.convertColumnIndexToView(c);
    
                if (viewCol != -1) {
                    TableColumn tableColumn = columnModel.getColumn(viewCol);
    
                    TableCellRenderer headRend = tableColumn.getHeaderRenderer();
    
                    if (headRend == null) {
                        headRend = tableHeader.getDefaultRenderer();
                    }
    
                    TableCellRenderer cellRend = tableColumn.getCellRenderer();
    
                    if (cellRend == null) {
                        cellRend = table.getDefaultRenderer(model.getColumnClass(c));
                    }
    
                    Component headComp = headRend.getTableCellRendererComponent(table,
                                            tableColumn.getHeaderValue(), false, false, 0, c);
    
                    int maxWidth = headComp.getPreferredSize().width;
    
                    for (int r = 0; r < rows; r++) {
                        Component comp = cellRend.getTableCellRendererComponent(table,
                                            model.getValueAt(r, c), false, false, r, c);
    
                        int w = comp.getPreferredSize().width;
    
                        if (w > maxWidth) {
                            maxWidth = w;
                        }
                    }
    
                    maxWidth += spacing.width;
    
                    tableColumn.setPreferredWidth(maxWidth);
                }
            }
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new TableSizeTestFrame().setVisible(true);
                }
            });
        }
    }
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava 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 © 2025 vBulletin Solutions, Inc. All rights reserved.