Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11

Discussione: Bordi in JTable

  1. #1

    Bordi in JTable

    Ciao a tutti,
    costruito una tabella nella quale inserisco testo e JLabel che dove vengono incapsulate le immagini.
    Fin qui tutto bene.
    Il problema è che ho la necessità in determinati momenti "staccare" visivamente una riga dalla successiva in base ad una determinata variabile.
    Avevo pensato ad un bordo inferiore da applicare alla tabella ma non viene applicato.
    io avevo fatto una cosa del genere nel renderer.


    codice:
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        if(jump[row]){
            Border b=BorderFactory.createMatteBorder(0, 0, 3, 0, Color.BLACK);
            this.setBorder(b);
            repaint();
        }
    }

    Dove jump è la mia variabile che ho valorizzato con dei booleani che indica se inserire o meno il bordo inferiore.
    Quando il valore è true ovviamente entra nel blocco "if" ma non fà nulla.

    Grazie mille per ogni aiuto/consiglio
    Ciao
    Ultima modifica di schumy2000; 12-02-2014 a 12:25
    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
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Per poterlo fare all'intera riga, non è sufficiente/ergonomico il Renderer (che lavora per colonne).
    Devi ridefinire JTable.

    Un esempio, che uso per colorare un'intera riga quando una condizione è verificata (tu, al posto di cambiare il colore di sfondo, semplicemente aggiungerai il bordo):

    codice:
    public class Tabella extends JTable {
        
        public Tabella(TableModel model) {
            super( model );
        }
    
        @Override
        public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
            Component rendererComponent = super.prepareRenderer(renderer, row, column);
    
            if ( !isCellSelected(row, column) ) {
                // Se la cella NON E' selezionata, verifico
                // se sussiste la condizione per colorarla
    
                // Di default sarà bianca
                rendererComponent.setBackground( Color.WHITE );
    
                // Recupero dal modello la riga
                Riga r = modello.getRow( row );
    
                // Se la condizione è verificata, coloro la riga di rosso
                if ( condizione ) {
                    rendererComponent.setBackground( Color.RED );
                }
            }
    
            return rendererComponent;
        }
    }

    Come detto, io lo uso per la colorazione dell'intera riga e verifico anche che la riga non sia selezionata... tu basta che cambi l'istruzione del setBackground() con il setBorder() e, se non ti interessa lo stato della selezione, rimuovi anche l'if esterno.

    L'importante è capire che il Renderer agisce per colonna (ed, eventualmente, sulla singola cella)... per applicare effetti sull'intera riga è necessario ridefinire il prepareRenderer() di JTable.

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Beh mi sembrava più semplice...
    però è strano visto che con lo stesso renderer riesco anche a colorare le celle quando si verifica una condizione...
    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
    anche volendo come faccio a passare la variabile jump?
    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
    ho provato col SetBorder...non va lo stesso era destino che non dovevo farlo
    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

  6. #6
    Ti passo il codice magari capisci dove può essere l'errore

    codice:
    
    public class Tabella extends JTable {
        private boolean[] jump;
        private String tipo;
    
    
        public Tabella(TableModel model, DefaultTableColumnModel columnModel1, String tipo) {
                   super( model, columnModel1 );
                   this.tipo=tipo;
        }
        
        
        public void setJumpVector(boolean[] jump){
            this.jump=jump;
            
        }
        
        @Override
        public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
            Component rendererComponent = super.prepareRenderer(renderer, row, column);
                // Se la condizione è verificata, coloro la riga di rosso
            if(tipo.equalsIgnoreCase("TG")){
                if (!jump[row]) {
                    this.setBorder(BorderFactory.createMatteBorder(0,0,3,0,Color.BLACK));
                        
                }
            }
            return rendererComponent;
        }
    }
    e questa è la chiamata alla tabella:
    codice:
     table = new Tabella(tableModel, columnModel, tipo);
    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
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Un errore tuo e un errore mio.
    Errore tuo: stai applicando il bordo alla tabella ( this.setBorder(...) ) e non al rendererComponent.
    Errore mio: il rendererComponent deve essere un JComponent (basta un cast, visto che lo è) altrimenti non si può chiamare setBorder(), dato che Component non prevede tale metodo.

    Un esempio:

    codice:
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableModel;
    
    public class BordiTabella extends JFrame {
    
        private class Tabella extends JTable {
    
            private boolean[] jump;
            
            public Tabella(TableModel model) {
                super( model );
            }
            
            public void setJump(boolean[] jump) {
                this.jump = jump;
            }
    
            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                JComponent rendererComponent = (JComponent) super.prepareRenderer(renderer, row, column);
    
                // Di default sarà senza bordo
                rendererComponent.setBorder( null );
    
                // Se la condizione è verificata, coloro la riga di rosso
                if ( jump[row] ) {
                    rendererComponent.setBorder( BorderFactory.createMatteBorder(0,0,3,0,Color.BLACK) );
                }
    
                return rendererComponent;
            }
        }    
    
        private Tabella tabella;
        private String[][] data = {
            {"Data1", "Data2", "Data3"},
            {"Data1", "Data2", "Data3"},
            {"Data1", "Data2", "Data3"},
            {"Data1", "Data2", "Data3"},
            {"Data1", "Data2", "Data3"},
            {"Data1", "Data2", "Data3"}
        };
        
        private String[] columnNames = {"Nome1", "Nome2", "Nome3"};
        
        public BordiTabella() {
            Container c = getContentPane();
            c.setLayout( new BorderLayout() );
            
            DefaultTableModel tableModel = new DefaultTableModel(data, columnNames);
            tabella = new Tabella( tableModel );
            tabella.setJump( new boolean[]{false, false, true, false, true, false} );
            
            JScrollPane jsp = new JScrollPane( tabella );
            
            c.add(jsp, BorderLayout.CENTER);
            
            setTitle("Tabella con bordi");
            setSize(800, 600);
            setLocationRelativeTo( null );
            setDefaultCloseOperation( EXIT_ON_CLOSE );
        }
        
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            SwingUtilities.invokeLater( new Runnable() {
                @Override
                public void run() {
                    new BordiTabella().setVisible( true );
                }
            });
        }
    }
    Ho notato, inoltre, che viene fatto un test su tipo.equalsIgnoreCase("TG")... il parametro "tipo" viene passato alla creazione della tabella e non cambia per tutta la durata della sua esistenza (non essendovi metodi che lo permettano)... ora, non so se così sia corretto (dal punto di vista logico)... io mi sarei aspettato che il controllo fosse fatto sul dato presente sulla singola riga, non su un dato fisso per tutta la tabella...


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  8. #8
    ESATTO...è andata
    Si il Tipo è un parametro che serve una volta sola in quanto sono tutte InternalFrame che mostrano dati (o tramite bottoni memorizzano risultati).
    al momento avevo implementato tutte le sviluppi sul Renderer anche se basato su colonna.
    Però le celle me li colorava correttamente (nel mio caso cmq ciò che dovevo colorare era sempre una riga).
    Pazientemente sposterò tutte le logiche dal Renderer al prepareRenderer di JTable.

    Grazie
    Ciao
    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
    Un problema che mi è sorto adesso...
    Sempre nell'ambito del prepareRenderer ho la necessità di centrare i valori per ogni cella.

    Ho provato a fare setHorizontalAlignment(CENTER) ma a quanto pare non lo eredita dalla classe padre.
    Ho provato con setAlignmentX(CENTER_ALIGNMENT) ma non sortisce alcun effetto.
    Come posso fare?

    Grazie
    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

  10. #10
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Non è una questione "banale" e non è da delegare alla JTable... questo è un "problema" da delegare al Renderer... come detto, ciascun Renderer sa come disegnare la singola cella (di una determinata colonna). Ciascuna "cella" può essere un componente particolare (una JLabel nella maggior parte dei casi, ma potrebbe essere "qualunque cosa" anche un componente complesso). Quindi hai due alternative:

    1) Ti scrivi un renderer specifico per le celle (leggi "colonne") in cui vuoi avere il testo centrato e la centratura la fai lì
    2) Cerchi di "castare" l'oggetto "rendererComponent" al corretto tipo (JLabel o quel che è) e a quel punto hai il metodo (se previsto dal componente) setHorizontalAlignment()


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

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.