TableCellRenderer alcune celle con scritta rossa

di il
8 risposte

TableCellRenderer alcune celle con scritta rossa

class MyCustomTable extends JTable {

    private Color[] backgroundColors;

    public MyCustomTable(int numRows, int numColumns, Color[] backgroundColors) {
        super(numRows, numColumns);
        this.backgroundColors = backgroundColors;
    }

    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component comp = super.prepareRenderer(renderer, row, column);

        if (column == 0) {
            comp.setFont(new java.awt.Font("Tahoma", 1, 14));
        } else if (column == 3) {
            comp.setFont(new java.awt.Font("Tahoma", 3, 14));
        }

        if (!isCellSelected(row, column)) {
            comp.setBackground(backgroundColors[row % backgroundColors.length]);
        }

        return comp;
    }

    @Override

    public boolean isCellEditable(int row, int column
    ) {
        //all cells false
        return false;
    }
}
La mia è una richiesta credo molto semplice. Di alcune celle specifiche (sempre della stessa colonna) la scritta deve essere rossa.
Dove lo passo il booleano per quando la scritta deve essere rossa?


Qui sotto è dove lancio la classe che vedete sopra.
   JTable tabella = new MyCustomTable(0, 0, 
            new Color[]{
                new java.awt.Color(colore_riga_alterna[0], colore_riga_alterna[1], colore_riga_alterna[2]),
                new java.awt.Color(250, 250, 250)
            }
    );

8 Risposte

  • Re: TableCellRenderer alcune celle con scritta rossa

    p0ll0_ ha scritto:


    ...
    La mia è una richiesta credo molto semplice. Di alcune celle specifiche (sempre della stessa colonna) la scritta deve essere rossa.
    Dove lo passo il booleano per quando la scritta deve essere rossa?
    ...
    Non sono sicuro di aver capito, comunque vedi si ti è di aiuto

    https://examples.javacodegeeks.com/desktop-java/swing/jtable/drawing-swing-jtable-rows-different-colors-using-tablecellrenderer-interface-example/
  • Re: TableCellRenderer alcune celle con scritta rossa

    p0ll0_ ha scritto:


    La mia è una richiesta credo molto semplice. Di alcune celle specifiche (sempre della stessa colonna) la scritta deve essere rossa.
    Dove lo passo il booleano per quando la scritta deve essere rossa?
    In realtà no, non è così semplice (non è detto che lo sia, insomma). Non è questione di "passare" un boolean ma di stabilire e chiarire bene in base a COSA la cella deve essere rossa. In base al valore stesso della cella? Allora è facile. In base ad una impostazione differente e/o arbitraria? Dipende.

    Per dire (esempio): una colonna che contiene solo numeri e vuoi che se il numero è > 100 allora diventa rossa. Questo è BANALE, nel prepareRenderer hai row/column (della vista, non direttamente del model) quindi puoi prendere il valore e fare un test. Qui in questo caso non c'è nulla da "passare" ...
  • Re: TableCellRenderer alcune celle con scritta rossa

    Sì, se la data che inserisco nella cella è di oggi o di prima di oggi deve diventare rossa la scritta (sono le scadenze) Quindi come si fa? Grazie mille...
  • Re: TableCellRenderer alcune celle con scritta rossa

    p0ll0_ ha scritto:


    Sì, se la data che inserisco nella cella è di oggi o di prima di oggi deve diventare rossa la scritta (sono le scadenze) Quindi come si fa? Grazie mille...
    Ok, è fattibile perché dipende direttamente dal dato nella cella. Però visto che parli di date devi chiarire che tipo di dato hai realmente fornito dal model. Sono dei Date? LocalDate? O delle stringhe formattate? Altro? Se sono stringhe chiaramente è tutto un po' più scomodo perché sono da parsare. L'alternativa al parsing stringa x stringa è quello di avere un table model custom che espone "a parte" la data come oggetto temporale (non String). Oppure che sia già il table model custom a dire con un flag che la data per la riga x è "in scadenza".
  • Re: TableCellRenderer alcune celle con scritta rossa

    new SimpleDateFormat("yyyy-MM-dd").format(new Date())
    Per quanto riguarda il parsing credo di riuscire a trovare un modo per arrangiarmi. Non riesci a fare un esemio banalse senza usare il parsing?
  • Re: TableCellRenderer alcune celle con scritta rossa

    p0ll0_ ha scritto:


    Non riesci a fare un esemio banalse senza usare il parsing?
    Una cosa che si potrebbe fare (e parlo molto in generale, perché sarebbe poi facilmente ri-utilizzabile) è un table model base astratto e "generico" (nel senso dei generics) in modo che possa gestire un ArrayList<T> e con i metodi per inserire, rimuovere, estrarre gli oggetti T. E poi da estendere in modo da customizzare la "mappatura" verso i metodi standard di TableModel (getValueAt ecc...). In questo modo avresti direttamente gli oggetti "crudi" del tuo dominio e puoi usare/testare i dati come vuoi.

    Non è una cosa che si fa solo in 1-2 minuti .... serve un po' di design object-oriented ma si fa ...
  • Re: TableCellRenderer alcune celle con scritta rossa

      @Override
        public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
            Component comp = super.prepareRenderer(renderer, row, column);
          if (column == colonna) {
    
                try {
                    Date data = new SimpleDateFormat("dd/MM/yyyy").parse(super.getValueAt(row, column) + "");
    
                    if (!new Date().before(data)) {
    
                        comp.setForeground(new java.awt.Color(200, 0, 0));
                    }
    
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
            if (!isCellSelected(row, column)) {
    
                comp.setBackground(backgroundColors[row % backgroundColors.length]);
            }
    
            return comp;
        }

    volevo fare in modo che se è scaduto diventa rosso. Quando si apre la tabella è tutto nero ma scorrendo appena trova una data scaduta diventa tutto rosso, tutte le colonne... Quando seleziono una riga la scrtta di quella riga diventa tutta nera...
  • Re: TableCellRenderer alcune celle con scritta rossa

    p0ll0_ ha scritto:


    volevo fare in modo che se è scaduto diventa rosso. Quando si apre la tabella è tutto nero ma scorrendo appena trova una data scaduta diventa tutto rosso, tutte le colonne...
    Sì ma devi capire il perché. I renderer delle celle possono essere associati ad un Class specifico (quello esposto dal table model) o ad una colonna x specifica. Non so ora che table model hai usato ma è possibile/probabile che esponga Object.class per tutte le colonne. In questa condizione, c'è un unico renderer per tutte le colonne e quindi per l'intera tabella!

    Un renderer tipicamente restituisce sempre lo stesso identico componente. Non solo: tipicamente il renderer stesso è il componente, nel senso che generalmente si definisce es.: class MyRenderer extends JLabel { .... }
    E il getTableCellRendererComponent restituisce semplicemente la istanza dell'oggetto renderer (ovvero sé stesso, il this), previo setup del componente, naturalmente. Tutto questo è stato fatto così semplicemente per "giocare" moltissimo sul risparmio degli oggetti, per non dover creare decine/centinaia di oggetti continuamente.

    In uno scenario come questo succede quello che hai descritto. Purtroppo non è facile spiegarlo meglio, dovresti dare una occhiata al sorgente di DefaultTableCellRenderer per avere una idea della logica che c'è dietro.

    Le soluzioni ci sono, più di una. O fai in modo che qualunque sia il "flusso" del tuo prepareRenderer (ovvero in qualunque ramo passa) alla fine imposti sempre un foreground, rosso in quel caso specifico, nero in qualunque altro.

    Oppure per fare la cosa più accurata, prendere una prima volta il foreground dal componente per settarlo subito all'inizio prima della tua logica nel prepareRenderer.
Devi accedere o registrarti per scrivere nel forum
8 risposte