JTable - Feldinhalte anzeigen

skrobi

Mitglied
Hallo, ich habe folgende Frage und hoffe mir kann jemand weiterhelfen.

In meiner Tabelle, bestehen aus 7 Spalten und 4 Zeilen, werden die Inhalte aller Zellen korrekt angezeigt solange es sich um „Texte“ handelt.
Enthält eine Zelle in irgendeiner Zeile/Spalte jedoch eine „Grafik“, werden sämtliche Texte dieser Spalte unterdrückt.
Erfolgt ein Doppelklick auf eine solche „leere“ Zelle, wird deren Feldinhalt angezeigt. Die Grafik bleibt unverändert und der Feldinhalt solange erhalten, bis eine andere Zelle angeklickt wird.

Ich vermute, es hängt mit meinem „DefaultTableModel model“ zusammen.


Java:
    DefaultTableModel model = new DefaultTableModel(data, columnNames)
    {
      
    public Class getColumnClass(int column)
    {
     return getValueAt(1, column).getClass(); 
     // 1 = Grafik/Bilder in Zeile 1 werden angezeigt
    }
   };
  
    JTable table = new JTable( model );

//  Spaltenbreite festlegen         
    table.getColumnModel().getColumn(0).setPreferredWidth(30);
    table.getColumnModel().getColumn(1).setPreferredWidth(30);
    table.getColumnModel().getColumn(2).setPreferredWidth(140);  //100
    table.getColumnModel().getColumn(3).setPreferredWidth(130);  //90
    table.getColumnModel().getColumn(4).setPreferredWidth(130);  //90
    table.getColumnModel().getColumn(5).setPreferredWidth(130);
    table.getColumnModel().getColumn(6).setPreferredWidth(130);

//  Spaltenhöhe bei Überschriften festlegen     
    table.setRowHeight(  0, 30 );
    table.setRowHeight(  1, 130 );
    table.setRowHeight(  2, 30 );
    table.setRowHeight(  3, 30 );
 
    JScrollPane scrollPane = new JScrollPane( table );
    scrollPane.setPreferredSize(new Dimension(480, 400));
    add( scrollPane );
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("TM_051_JTable_Bilder_einfügen");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new TM_051_JTable_Bilder_einfügen());
        frame.setSize(550, 450);
//         frame.setLocationByPlatform( true );
        frame.pack();
        frame.setLocationRelativeTo(null);       
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}
Vielen Dank für eine Nachricht

Skrobi
 

mihe7

Top Contributor
Enthält eine Zelle in irgendeiner Zeile/Spalte jedoch eine „Grafik“, werden sämtliche Texte dieser Spalte unterdrückt.
Was heißt "Grafik"? Wie füllst Du das Model?

Ansonsten:
TM_051_JTable_Bilder_einfügen
Klassennamen sollten keine Verben sein.
frame.setSize(550, 450);
frame.pack();
Das setSize kannst Du Dir sparen, wenn Du anschließend ein pack() verwendest - das legt die Größe nämlich fest.
 

skrobi

Mitglied
Grafik bedeutet ein Foto im" .jpg" -Format.
Übrigens, wenn ich in einer Spalte die Grafik durch einen "Text" ersetze, werden alle Texte dieser Spalte ohne Doppelklick angezeigt, so wie es auch mit Grafik funktionieren sollte.
 

skrobi

Mitglied
Das model wird folgendermassen gefüllt:

String[] columnNames = {"00", "01", "02", "03", "04", "05", "06"};
Object[][] data =
{
{"00", "TBz", "Bezeichnung", "Woche", "Graue", "Grüne", "Bio"},
{"01", " ", " ", TAFEL, GRAUE, GRUENE, BIO},
{"02", "00" , "01" , "02" , "03" , "04" , "05"},
{"03", "01" , "XX.XX.XXXX" , "Woche", "Graue", "Grüne", "Bio"},
};

wobei es sich bei bei den Grafiken "TAFEL, GRAUE, GRUENE, BIO" um Fotos im" .jpg" -Format handelt.
 

skrobi

Mitglied
Hallo mihe7,
zunächst vielen Dank für deine Mühe. Anbei das Coding, das bis auf die genanten Fehler soweit ganz gut läuft. Solltest due es kurz testen fügen noch irgend welche .pgm Dateien ein. Meiner Meinung nach liegt der Fehler im Bereich // ????????????????? Vielleicht kannst du etwas erkennen.
Gruss und tschüs skrobi
Java:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

public class TM_051_JTable_Bilder_einfügen extends JPanel
{
    static int zeile = 0;
    
    
//*****************************************************************************
//*****************************************************************************   
//*   A R B T A B - (2)  -  D E F I N I T I O N E N
//*   l o g i s c h e   D a r s t e l l u n g   
//*****************************************************************************
//*****************************************************************************
 
  static String[]  ÜB_ARBTAB_logisch = {"00", "01", "02", "03", "04", "05", "06"};
  static String[][]   ARBTAB_logisch = {
          
{ "00 ", "TBz", "Bezeichnung"   , "Kehrwoche ", "Graue Tonne" , "Grüne Tonne", "Bio Tonne",},         
{ "01 ", "   ", "          "    , "TAFEL BILD ", "GRAUE BILD" , "GRÜNE BILD ", "BIO BILD ",},
//=====+======+=================+==============+==============+==============+============:
{ "02" , "00" , "01"            , "02"         , "03"         , "04"         , "05"        },   
{ "03" , "01" , "XX.XX.XXXX"    , "Kehrwoche"  , "Graue Tonne", "Grüne Tonne", "Bio Tonne ",},
//=====+======+=================+==============+==============+==============+=============:
};
    

    public TM_051_JTable_Bilder_einfügen()
    {
        
//#############################################################################   
    System.out.println("\n" +
    " ARBTAB_logisch Länge(Rows) und Breite(Cols) ermitteln");
//#############################################################################

    int ARBTAB_logisch_rows = ARBTAB_logisch.length;
    int ARBTAB_logisch_cols = ARBTAB_logisch[0].length;
        
    System.out.println(" ARBTAB_logisch-Rows: " + ARBTAB_logisch_rows);
    System.out.println(" ARBTAB_logisch-Cols: " + ARBTAB_logisch_cols);
      
//#############################################################################   
   System.out.println("\n" +
   " ARBTAB_logisch aufbauen");
//#############################################################################

//   aboutIcon = new
Icon aboutIcon = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\PEREGRINOS\\PEREGRINOS_117x156.jpg");

Icon TAFEL = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\01_TAFEL_86x120.jpg");
System.out.println(" TAFEL  = " + TAFEL);
Icon GRAUE = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\02_GRAUE TONNE_86x120.jpg");   
System.out.println(" GRAUEL = " + GRAUE);
Icon GRUENE = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\03_GRUENE TONNE_83x117.jpg");   
System.out.println(" GRUENE = " + GRUENE);
Icon BIO = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\04_BIO TONNE_82x121.jpg");   
System.out.println(" BIO    = " + BIO);             

/*
    String[]   columnNames    = ÜB_ARBTAB_logisch;
    Object[][] data           = {  {ARBTAB_logisch},   };
*/   

String[] columnNames = {"00", "01", "02", "03", "04", "05", "06"};   
Object[][] data =
{
{"00", "TBz", "Bezeichnung", "Kehrwoche", "Graue Tonne", "Grüne Tonne", "Bio Tonne"},
{"01", "   ", "           ",  TAFEL,       GRAUE,         GRUENE,        BIO},       
{"02", "00" , "01"         , "02"       , "03"         , "04"         , "05"},   
{"03", "01" , "XX.XX.XXXX" , "Kehrwoche", "Graue Tonne", "Grüne Tonne", "Bio Tonne"},           
};




    DefaultTableModel model = new DefaultTableModel(data, columnNames)
    {
        
    public Class getColumnClass(int column)
    {
//    getValueAt  fragt  Wert einer bestimmten Zelle
//    setValueAt  setzt  Wert einer bestimmten Zelle       

        
//  ???????????????????????????????????????????????????????????????       
//      return getValueAt(1, column).getClass();
       return getValueAt(0, column).getClass();

     //   gleich  1, in Zeile/Spalte werden Grafik/Bilder angezeigt
     // ungleich  1, in Zeile/Spalte werden Texte angezeigt
//  ???????????????????????????????????????????????????????????????
      
      
    }
   };
  
    JTable table = new JTable( model );

//  Spaltenbreite festlegen         
    table.getColumnModel().getColumn(0).setPreferredWidth(30);
    table.getColumnModel().getColumn(1).setPreferredWidth(30);
    table.getColumnModel().getColumn(2).setPreferredWidth(140);  //100
    table.getColumnModel().getColumn(3).setPreferredWidth(130);  //90
    table.getColumnModel().getColumn(4).setPreferredWidth(130);  //90
    table.getColumnModel().getColumn(5).setPreferredWidth(130);
    table.getColumnModel().getColumn(6).setPreferredWidth(130);

//  Spaltenhöhe bei Überschriften festlegen     
    table.setRowHeight(  0, 30 );
    table.setRowHeight(  1, 130 );
    table.setRowHeight(  2, 30 );
    table.setRowHeight(  3, 30 );
 
    JScrollPane scrollPane = new JScrollPane( table );
    scrollPane.setPreferredSize(new Dimension(480, 400));
    add( scrollPane );
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("TM_051_JTable_Bilder_einfügen");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new TM_051_JTable_Bilder_einfügen());
//         frame.setSize(550, 450);
//         frame.setLocationByPlatform( true );
        frame.pack();
        frame.setLocationRelativeTo(null);       
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}
 

mihe7

Top Contributor
Danke, jetzt habe ich erst realisiert, dass ich
Enthält eine Zelle in irgendeiner Zeile/Spalte jedoch eine „Grafik“, werden sämtliche Texte dieser Spalte unterdrückt.
falsch gelesen habe :)

Das ist normal. JTable verwendet TableCellRenderer, um die Inhalte einer Zelle darzustellen. Standardmäßig kann dieser je Spalte festgelegt werden. Du möchtest einen Renderer, der abhängig davon, ob ein Icon in der Zelle steht, eben dieses Icon oder einen Text anzeigt. Das kann man mit dem DefaultTableCellRenderer umsetzen:
Java:
    static class IconCapableCellRenderer extends DefaultTableCellRenderer {
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
                int row, int column) {
            setIcon(null);
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            if (value != null && value instanceof Icon) {
                setIcon((Icon) value);
            }
            return this;
        }
       
    }

Das DefaultTableModel musst Du nicht mehr überschreiben, nur noch den Renderer für die betreffenden Spalten festlegen:
Java:
        DefaultTableModel model = new DefaultTableModel(data, columnNames);

        JTable table = new JTable(model);

        // Spaltenbreite festlegen
        table.getColumnModel().getColumn(0).setPreferredWidth(30);
        table.getColumnModel().getColumn(1).setPreferredWidth(30);
        table.getColumnModel().getColumn(2).setPreferredWidth(140); // 100
        table.getColumnModel().getColumn(3).setPreferredWidth(130); // 90
        table.getColumnModel().getColumn(4).setPreferredWidth(130); // 90
        table.getColumnModel().getColumn(5).setPreferredWidth(130);
        table.getColumnModel().getColumn(6).setPreferredWidth(130);

        // Renderer festlegen
        for (int i = 3; i < 7; i++) {
            table.getColumnModel().getColumn(i).setCellRenderer(new IconCapableCellRenderer());;
        }
 

skrobi

Mitglied
Danke, jetzt habe ich erst realisiert, dass ich

falsch gelesen habe :)

Das ist normal. JTable verwendet TableCellRenderer, um die Inhalte einer Zelle darzustellen. Standardmäßig kann dieser je Spalte festgelegt werden. Du möchtest einen Renderer, der abhängig davon, ob ein Icon in der Zelle steht, eben dieses Icon oder einen Text anzeigt. Das kann man mit dem DefaultTableCellRenderer umsetzen:
Java:
    static class IconCapableCellRenderer extends DefaultTableCellRenderer {
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
                int row, int column) {
            setIcon(null);
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            if (value != null && value instanceof Icon) {
                setIcon((Icon) value);
            }
            return this;
        }
      
    }

Das DefaultTableModel musst Du nicht mehr überschreiben, nur noch den Renderer für die betreffenden Spalten festlegen:
Java:
        DefaultTableModel model = new DefaultTableModel(data, columnNames);

        JTable table = new JTable(model);

        // Spaltenbreite festlegen
        table.getColumnModel().getColumn(0).setPreferredWidth(30);
        table.getColumnModel().getColumn(1).setPreferredWidth(30);
        table.getColumnModel().getColumn(2).setPreferredWidth(140); // 100
        table.getColumnModel().getColumn(3).setPreferredWidth(130); // 90
        table.getColumnModel().getColumn(4).setPreferredWidth(130); // 90
        table.getColumnModel().getColumn(5).setPreferredWidth(130);
        table.getColumnModel().getColumn(6).setPreferredWidth(130);

        // Renderer festlegen
        for (int i = 3; i < 7; i++) {
            table.getColumnModel().getColumn(i).setCellRenderer(new IconCapableCellRenderer());;
        }
Hallo mihe7,
vielen Dank für Deine großartige Unterstützung und nicht selbstverständliche Mühe. Ich habe Deine Korrektur in mein Testprogramm eingebaut und es läuft exakt so, wie ich es wollte. Das war eine 1A*** Lösung, nach der ich stundenlang vergeblich suchte. Nun werde ich die Korrektur noch in mein echtes Programm übernehmen und bin überzeugt, dass es dort auch klappt.
Auch wurde mir wieder einmal klar, wer zu Recht Küchenchef ist und ich nur der Kellner bin. Gruß und Dank skrobi
 

skrobi

Mitglied
Kein Problem, die JTable ist auch nicht ganz einfach.
Hallo mihe7,

mea culpa – dummer Weise sind mir zwei gravierende Denkfehler unterlaufen, die mir erst jetzt, beim Einbau Deiner vorgeschlagenen Korrektur in mein Programm auffielen.

1) In meinem Programm habe ich bereits einen (ersten) Renderer, mittels dem ich diverse Spalten und einzelne Zellen einfärbe. Dies funktioniert einwandfrei, solange nur dieser (erste) Renderer aktiv ist. Sobald beide ("mein erster" und "Dein zweiter") Renderer gleichzeitig aktiv sind, werden zwar die Grafiken/Bilder geladen und angezeigt, aber nur die Spalten/Zellen eingefärbt, in deren Spalten keine Grafiken/Bilder geladen wurden.

2) Bei Beendigung meines Programmes wird die Tabelle auf einen externen Speicher ("C:\\10__HAUSDIENSTE\\......) gespeichert. Beim nächsten Programmstart wird diese Sicherungsdatei gelesen und die Daten in die Tabelle übertragen. Die Anweisung „jTable.getColumnModel().getColumn(ix).setCellRenderer(„
erhält dadurch keine gültigen Adresskonstanten und kann somit die Grafiken/Bild-Dateien nicht finden. Erforderlich wäre eine Möglichkeit, mittels der, nachdem die Tabelle aufgebaut wurde, die aktuellen Adressen von ("C:\\10__HAUSDIENSTE\\......) in die Column(ix).übertragen werden.

Vielleicht hast Du noch einmal zwei Lösungen anzubieten, damit ich mein Übungsprogramm erfolgreich beenden kann.

Vielen Dank und MfG skrobi


Java:
    DefaultTableModel  model  =  new  DefaultTableModel(
                      ARBTAB_logisch, ÜB_ARBTAB_logisch);
  
    JTable  jTable  = new JTable( model );

//  Spaltenbreite festlegen         
    jTable.getColumnModel().getColumn(0).setPreferredWidth(30);
    jTable.getColumnModel().getColumn(1).setPreferredWidth(30);
    :

//  Spaltenhöhe bei Überschriften festlegen     
    jTable.setRowHeight(  1, 130 );
    jTable.setRowHeight(  3, 30 );
    :
 
//  01. Erster_Renderer  "Zellen gezielt einfärben"     
//  -----------------------------------------------
    jTable.setDefaultRenderer(Object.class, new DefaultTableCellRenderer()
    {
    @Override
    public Component getTableCellRendererComponent(
             JTable table, Object value, boolean isSelected, boolean hasFocus,
                        int row, int column)
         {
         final Component c = super.getTableCellRendererComponent(
                 table, value, isSelected, hasFocus, row, column);
//  ----------------------------------------------------------------
//  funktioniert grundsätzlich bei beiden Renderer!       
    if (row == 03 && column == 02)  {       
        c.setBackground(Color.RED);
       }else{c.setBackground(Color.WHITE);
       };
//  ----------------------------------------------------------------
//  funktioniert nur, wenn Renderer zum Einfügen Grafiken/Bilder
//  in diese Spalte inaktiv ist!       
    if (column == 04 )  {       
        c.setBackground(Color.LIGHT_GRAY);
       };       
//   ----------------------------------------------------------------
//  funktioniert nur, wenn Renderer zum Einfügen Grafiken/Bilder
//  in diese Spalte inaktiv ist!       
     if (column == 05 )  {       
         c.setBackground(Color.GREEN);
        };       
//   ----------------------------------------------------------------
//  funktioniert nur, wenn Renderer zum Einfügen Grafiken/Bilder
//  in diese Spalte inaktiv ist!       
     if (column == 06 )  {       
         c.setBackground(Color.ORANGE);
        };       
//   ----------------------------------------------------------------
//  ist nur der erste Renderer aktiv, werden die Zeilen komplett eingefärbt!
//  ist der zweite Renderer aktiv, werden nur die Zellen eingefärbt, deren
//  Spalten vom zweiten Renderer nicht involviert sind!       
     if (row == 04 || row == 10 || row == 15 ||
         row == 24 || row == 34 )  {       
         c.setBackground(Color.YELLOW);
        };       
//  ----------------------------------------------------------------
       return c;
    } });
    

//  02. Zweiter_Renderer  "BILDER/GRAFIKEN laden" festlegen       
//  -------------------------------------------------------
    for (int ix = 3; ix < ÜB_ARBTAB_logisch.length; ix++) {                 
         jTable.getColumnModel().getColumn(ix).setCellRenderer(
             new  Zweiter_Renderer());;   //IconCapableCellRenderer
    }
 
//  =======================================================   
 }  //  END  public TM_052_JTable_mihe7_MOD_4()   

//  02. Zweiter_Renderer  "BILDER/GRAFIKEN laden" festlegen
//  -------------------------------------------------------   
//               IconCapableCellRenderer
       static class Zweiter_Renderer extends DefaultTableCellRenderer {       
        @Override
        public Component getTableCellRendererComponent(
                JTable jTable, Object value, boolean isSelected,
                boolean hasFocus, int row, int column) {
            setIcon(null);
            super.getTableCellRendererComponent(
                    jTable, value, isSelected, hasFocus, row, column);
            if (value != null && value instanceof Icon) {
                setIcon((Icon) value);
               }
            return this;
        }
    }
 

mihe7

Top Contributor
zu 1) Wenn für eine Spalte der Renderer nicht explizit gesetzt ist, wird ein Renderer anhand des jeweiligen Typs (ggf. Object) ermittelt.

Du möchtest nun Farbe einerseits, Grafiken andererseits darstellen. Es gibt nun verschiedene Möglichkeiten, das Problem zu lösen.

Die brutale Variante ist, einfach den Code für das Färben mit in den IconCapableRenderer zu übernehmen. Nicht schön, würde aber funktionieren.

Ich würde mir hier einen "ColorCellRenderer" schreiben, der einen anderen Renderer als Delegate verwendet (und universell einsetzbar ist, das ist aber jetzt ein wenig Overkill).

Java:
import javax.swing.table.TableCellRenderer;

// snip

static class ColorCellRenderer implements TableCellRenderer {
    private final TableCellRenderer delegate;
    public ColorCellRenderer(TableCellRenderer delegate) {
        this.delegate = delegate;
    }
    
    @Override
    public Component getTableCellRendererComponent(
            JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int column) {
        final Component c = delegate.getTableCellRendererComponent(
                table, value, isSelected, hasFocus, row, column);
        if (row == 03 && column == 02) {
            c.setBackground(Color.RED);
        } else {
            c.setBackground(Color.WHITE);
        }
        if (column == 04) {
            c.setBackground(Color.LIGHT_GRAY);
        }
        if (column == 05) {
            c.setBackground(Color.GREEN);
        }
        if (column == 06) {
            c.setBackground(Color.ORANGE);
        }
        if (row == 04 || row == 10 || row == 15 ||
                row == 24 || row == 34) {
            c.setBackground(Color.YELLOW);
        }
        return c;
    }
}
(Achtung: ungetestet, nur eine Skizze)

Jetzt kannst Du Dir einen Renderer basteln, der beides kann:
Java:
        // Renderer festlegen
        for (int i = 3; i < 7; i++) {
            TableCellRenderer renderer = new ColorCellRenderer(new IconCapableCellRenderer());
            table.getColumnModel().getColumn(i).setCellRenderer(renderer);
        }

zu 2)
Die Anweisung „jTable.getColumnModel().getColumn(ix).setCellRenderer(„
erhält dadurch keine gültigen Adresskonstanten und kann somit die Grafiken/Bild-Dateien nicht finden.
Wie meinen?!?
 

skrobi

Mitglied
zu 1) Wenn für eine Spalte der Renderer nicht explizit gesetzt ist, wird ein Renderer anhand des jeweiligen Typs (ggf. Object) ermittelt.

Du möchtest nun Farbe einerseits, Grafiken andererseits darstellen. Es gibt nun verschiedene Möglichkeiten, das Problem zu lösen.

Die brutale Variante ist, einfach den Code für das Färben mit in den IconCapableRenderer zu übernehmen. Nicht schön, würde aber funktionieren.

Ich würde mir hier einen "ColorCellRenderer" schreiben, der einen anderen Renderer als Delegate verwendet (und universell einsetzbar ist, das ist aber jetzt ein wenig Overkill).

Java:
import javax.swing.table.TableCellRenderer;

// snip

static class ColorCellRenderer implements TableCellRenderer {
    private final TableCellRenderer delegate;
    public ColorCellRenderer(TableCellRenderer delegate) {
        this.delegate = delegate;
    }
   
    @Override
    public Component getTableCellRendererComponent(
            JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int column) {
        final Component c = delegate.getTableCellRendererComponent(
                table, value, isSelected, hasFocus, row, column);
        if (row == 03 && column == 02) {
            c.setBackground(Color.RED);
        } else {
            c.setBackground(Color.WHITE);
        }
        if (column == 04) {
            c.setBackground(Color.LIGHT_GRAY);
        }
        if (column == 05) {
            c.setBackground(Color.GREEN);
        }
        if (column == 06) {
            c.setBackground(Color.ORANGE);
        }
        if (row == 04 || row == 10 || row == 15 ||
                row == 24 || row == 34) {
            c.setBackground(Color.YELLOW);
        }
        return c;
    }
}
(Achtung: ungetestet, nur eine Skizze)

Jetzt kannst Du Dir einen Renderer basteln, der beides kann:
Java:
        // Renderer festlegen
        for (int i = 3; i < 7; i++) {
            TableCellRenderer renderer = new ColorCellRenderer(new IconCapableCellRenderer());
            table.getColumnModel().getColumn(i).setCellRenderer(renderer);
        }

zu 2)

Wie meinen?!?
Als Java-Anfänger möchte ich Dir den Sachverhalt aus meiner Sicht darstellen.
Das meine Tabelle betreffende Coding sieht wie unten definiert aus. Beispielsweise unter "TAFEL = new ImageIcon" wird die Adresse des zu ladenden Bildes definiert, das in meiner Tabelle ({ARBTAB_logisch}) Object[][] data = { in der Zeile 01/Spalte 03}; {"01", " ", " ", TAFEL, GRAUE, GRUENE, BIO}, später angezeigt werden soll, was auch durch Deinen mir gelieferten Renderer einwandfrei funktioniert.

Beim Programmstart wird meine Tabelle geladen und die Adressen der zu ladenden Bilder (TAFEL, GRAUE, GRUENE, BIO) in der Zeile 01/Spalte 03 bis 06 gespeichert. Während der Programmausführung werden verschiedene Feldinhalte mittels Eingabe und/oder Berechnungen verändert, die beim nächsten Programmstart als Vorgabe dienen. Beim Programmende wird deshalb der Tabelleninhalt meiner (veränderte) Tabelle in einer externe Datei ("C:\\10__HAUSDIENSTE\\......) gespeichert.

Beim nächsten Programmstart wird, nachdem meine Tabelle systembedingt geladen und initialisiert wurde, diese durch mein Programm mittels Lesen und Speichern der externen Datei ("C:\\10__HAUSDIENSTE\\......) überschrieben. Vermutlich stehen nun nicht mehr die aktuellen Adressen der zu ladenden Bilder (TAFEL, GRAUE, GRUENE, BIO) in der Zeile 01/Spalte 03 bis 06 zur Verfügung.

====>>>> Um die Kuh vom Eis zu bringen habe ich mir inzwischen folgende Lösung ausgedacht, die ich jedoch noch realisieren und testen muss:
1) Unmittelbar nach dem Programmstart den Inhalt von TAFEL, GRAUE, GRUENE, BIO der Zeile 01/Spalte 03 bis 06 sichern.
2) externe Datei ("C:\\10__HAUSDIENSTE\\......) laden und damit meine Tabelle mit Vorgabedaten überschreiben.
3) Die gesicherten Inhalte von TAFEL, GRAUE, GRUENE, BIO der Zeile 01/Spalte 03 bis 06 laden (Restore).

Mal sehen ob's klappt. Ich werde Dich in jedem Fall informieren auch hinsichtlic,h des mir angebotenen Renderer, was ich auch noch testen muss.
Vielen Dank und MfG skrobi


Java:
Icon TAFEL = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\01_TAFEL_86x120.jpg");
System.out.println(" TAFEL  = " + TAFEL);
Icon GRAUE = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\02_GRAUE TO NNE_86x120.jpg");   
System.out.println(" GRAUEL = " + GRAUE);
Icon GRUENE = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\03_GRUENE TONNE_83x117.jpg");   
System.out.println(" GRUENE = " + GRUENE);
Icon BIO = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\04_BIO TONNE_82x121.jpg");   
System.out.println(" BIO    = " + BIO);             

/*
    String[]   columnNames    = ÜB_ARBTAB_logisch;
    Object[][] data           = {  {ARBTAB_logisch},   };
*/   

String[] columnNames = {"00", "01", "02", "03", "04", "05", "06"};   
Object[][] data =
{
{"00", "TBz", "Bezeichnung", "Kehrwoche", "Graue Tonne", "Grüne Tonne", "Bio Tonne"},
{"01", "   ", "           ",  TAFEL,       GRAUE,         GRUENE,        BIO},       
{"02", "00" , "01"         , "02"       , "03"         , "04"         , "05"},   
{"03", "01" , "XX.XX.XXXX" , "Kehrwoche", "Graue Tonne", "Grüne Tonne", "Bio Tonne"},           
};
 

skrobi

Mitglied
Als Java-Anfänger möchte ich Dir den Sachverhalt aus meiner Sicht darstellen.
Das meine Tabelle betreffende Coding sieht wie unten definiert aus. Beispielsweise unter "TAFEL = new ImageIcon" wird die Adresse des zu ladenden Bildes definiert, das in meiner Tabelle ({ARBTAB_logisch}) Object[][] data = { in der Zeile 01/Spalte 03}; {"01", " ", " ", TAFEL, GRAUE, GRUENE, BIO}, später angezeigt werden soll, was auch durch Deinen mir gelieferten Renderer einwandfrei funktioniert.

Beim Programmstart wird meine Tabelle geladen und die Adressen der zu ladenden Bilder (TAFEL, GRAUE, GRUENE, BIO) in der Zeile 01/Spalte 03 bis 06 gespeichert. Während der Programmausführung werden verschiedene Feldinhalte mittels Eingabe und/oder Berechnungen verändert, die beim nächsten Programmstart als Vorgabe dienen. Beim Programmende wird deshalb der Tabelleninhalt meiner (veränderte) Tabelle in einer externe Datei ("C:\\10__HAUSDIENSTE\\......) gespeichert.

Beim nächsten Programmstart wird, nachdem meine Tabelle systembedingt geladen und initialisiert wurde, diese durch mein Programm mittels Lesen und Speichern der externen Datei ("C:\\10__HAUSDIENSTE\\......) überschrieben. Vermutlich stehen nun nicht mehr die aktuellen Adressen der zu ladenden Bilder (TAFEL, GRAUE, GRUENE, BIO) in der Zeile 01/Spalte 03 bis 06 zur Verfügung.

====>>>> Um die Kuh vom Eis zu bringen habe ich mir inzwischen folgende Lösung ausgedacht, die ich jedoch noch realisieren und testen muss:
1) Unmittelbar nach dem Programmstart den Inhalt von TAFEL, GRAUE, GRUENE, BIO der Zeile 01/Spalte 03 bis 06 sichern.
2) externe Datei ("C:\\10__HAUSDIENSTE\\......) laden und damit meine Tabelle mit Vorgabedaten überschreiben.
3) Die gesicherten Inhalte von TAFEL, GRAUE, GRUENE, BIO der Zeile 01/Spalte 03 bis 06 laden (Restore).

Mal sehen ob's klappt. Ich werde Dich in jedem Fall informieren auch hinsichtlic,h des mir angebotenen Renderer, was ich auch noch testen muss.
Vielen Dank und MfG skrobi


Java:
Icon TAFEL = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\01_TAFEL_86x120.jpg");
System.out.println(" TAFEL  = " + TAFEL);
Icon GRAUE = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\02_GRAUE TO NNE_86x120.jpg");  
System.out.println(" GRAUEL = " + GRAUE);
Icon GRUENE = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\03_GRUENE TONNE_83x117.jpg");  
System.out.println(" GRUENE = " + GRUENE);
Icon BIO = new ImageIcon(
"C:\\10__HAUSDIENSTE\\HD_GRAFIK\\ECLIPSE_BILDER_1234\\04_BIO TONNE_82x121.jpg");  
System.out.println(" BIO    = " + BIO);            

/*
    String[]   columnNames    = ÜB_ARBTAB_logisch;
    Object[][] data           = {  {ARBTAB_logisch},   };
*/  

String[] columnNames = {"00", "01", "02", "03", "04", "05", "06"};  
Object[][] data =
{
{"00", "TBz", "Bezeichnung", "Kehrwoche", "Graue Tonne", "Grüne Tonne", "Bio Tonne"},
{"01", "   ", "           ",  TAFEL,       GRAUE,         GRUENE,        BIO},      
{"02", "00" , "01"         , "02"       , "03"         , "04"         , "05"},  
{"03", "01" , "XX.XX.XXXX" , "Kehrwoche", "Graue Tonne", "Grüne Tonne", "Bio Tonne"},          
};
Hallo mihe7,
was soll ich sagen, dank Deiner fachmännischen Unterstützung, alles in "bester Butter".
Zunächst habe ich mein Programm etwas umstrukturiert. Danach Deinem Vorschlag entsprechend mich für "Die brutale Variante" entschieden, Deinen bereits zuvor gelieferten "individuellen IconCapableRenderer", für die Färbung der jeweiligen Spalten zu erweitern . Mittels eines zweiten "allgemeinen Renderer" färbe ich die restlichen Zeilen, Spalten und Zellen ein.
Das Problem mit den Adressen beim Programmfolgelauf, ist möglicherweise wegen meiner Programm-Neustrukturierung, plötzlich auch weg.
Nochmals besten Dank für deine erstklassige Unterstützung ohne die ich mein "Übungsprojekt" nicht erfolgreich hätte abschließen können.
Alles Gute für Deine Zukunft.
MfG skrobi
P.S.: Die Sache mit dem "ColorCellRenderer schreiben, der einen anderen Renderer als Delegate verwendet", werde ich mir in jedem Falle in aller Ruhe anschauen und mein Programm ggf. noch anpassen.
 

mihe7

Top Contributor
Die Sache mit dem "ColorCellRenderer schreiben, der einen anderen Renderer als Delegate verwendet", werde ich mir in jedem Falle in aller Ruhe anschauen und mein Programm ggf. noch anpassen.
Ja, das Anschauen würde ich Dir unbedingt empfehlen, da hier ein Design Pattern (https://de.wikipedia.org/wiki/Decorator) umgesetzt wurde, das ganz nützlich sein kann.

Universell ist der ColorRenderer allerdings noch nicht. Das kann man aber erweitern.

Man definiere erstmal ein ColorModel, das die Farbe jeder Zelle liefert:
Java:
public interface ColorModel {
    /** Returns the color of a cell.
     *
     * @param row  index of the cell's row.
     * @param col  index of the cell's column.
     * @return color of the given cell, {@code null} if none was specified.
     */
    Color getColor(int row, int col);
}
Man könnte die Parameter natürlich noch erweitern um die JTable, das TableModel usw., dann kann man z. B. abhängig vom Zellinhalt die Farbe setzen. Aber für's Prinzip reicht das erstmal.

Der Renderer selbst wird dann relativ einfach:
Java:
public class ColorCellRenderer implements TableCellRenderer {
    private final TableCellRenderer delegate;
    private final ColorModel backgroundColorModel;

    public ColorCellRenderer(TableCellRenderer delegate, ColorModel colorModel) {
        this.delegate = delegate;
        this.backgroundColorModel = colorModel;
    }
    
    @Override
    public Component getTableCellRendererComponent(
            JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int column) {
        final Component c = delegate.getTableCellRendererComponent(
                table, value, isSelected, hasFocus, row, column);

        final Color color = backgroundColorModel.getColor(row, column);
        c.setBackground(color != null ? color : table.getBackground());
        return c;
    }
}
Die Komponente bekommt der Renderer also vom delegate, die Farbe aus dem ColorModel. Schön an der Geschichte ist, dass das ColorModel nur ein Interface ist, das beliebig implementiert sein kann. Außerdem ist ColorModel ein "functional interface", es kann also ein Lambda-Ausdruck angegeben werden.

Du willst jede zweite Zeile rot haben? new ColorCellRenderer(delegate, (row, col) -> row % 2 == 0 ? Color.RED : null);

Der Lambda-Ausdrucks ist dabie nur die Kurzschreibweise für
Java:
new ColorCellRenderer(delegate, new ColorModel() {
    @Override
    public Color getColor(int row, int col) {
        return row % 2 == 0 ? Color.RED : null;
    }
});

Du möchtest explizit für jede Zelle die Farbe einstellen können? Dann kannst Du das ColorModel anders implementiert:
Java:
public class ExplicitColorModel implements ColorModel {
    private HashMap<Long, Color> colors = new HashMap<>();

    public void setColor(int row, int col, Color color) {
        colors.put(getKey(row, col), color);
    }

    public Color getColor(int row, int col) {
        return colors.get(getKey(row, col));
    }

    private Long getKey(int row, int col) {
        return ((long) Integer.MAX_VALUE) * row + col;
    }
}
Und so weiter, und so fort.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Drag und drop aus einer JTable - bitte um Unterstützung AWT, Swing, JavaFX & SWT 2
S HPRO und UPRO gemeinsame JTABLE gemeinsamer RENDERER ? AWT, Swing, JavaFX & SWT 1
F Swing JTable - MultiHeader inkl. Eingabemöglichkeit AWT, Swing, JavaFX & SWT 1
D Swing JTable Spaltenbreite AWT, Swing, JavaFX & SWT 1
W Gibt es einen "automatischen Listener" in Swing oder JTable oder der ATM-Klasse? AWT, Swing, JavaFX & SWT 14
G jTable - getSelectedRow() AWT, Swing, JavaFX & SWT 3
I JTable mit einem Button zu einer Detail Seite springen AWT, Swing, JavaFX & SWT 4
P JTable Listener für die Änderung einzelner Zellen oder Rows AWT, Swing, JavaFX & SWT 2
D Tastaturabfragen CTRL+t, CTRL+E bei eine JTable, bestehend aus JTextAteas AWT, Swing, JavaFX & SWT 4
P Checkboxes in JTable nicht editable AWT, Swing, JavaFX & SWT 9
F Best-Practise: JTable Text in Zelle zu groß AWT, Swing, JavaFX & SWT 2
izoards JTable in CSV File schreiben... AWT, Swing, JavaFX & SWT 23
Kohl Jedes Objekt einer JTable um ein Zeichen verkürzen AWT, Swing, JavaFX & SWT 7
I JTable, DefaultTableModel, zwei Zahlen multiplizieren. AWT, Swing, JavaFX & SWT 26
M JTABLE / wie oft wurde gewürfelt. AWT, Swing, JavaFX & SWT 1
F JTable vergrößern AWT, Swing, JavaFX & SWT 2
H JTable: Diverse NullPointer-Exceptions zur Laufzeit AWT, Swing, JavaFX & SWT 3
J Swing Werte des JTable werden nicht angezeigt AWT, Swing, JavaFX & SWT 9
T Swing JTable cellRenderer mit jpg Hintergrundfarbe lässt sich nicht ändern. AWT, Swing, JavaFX & SWT 1
HoT Einzelne Zelle in JTable Rahmen unten setzen AWT, Swing, JavaFX & SWT 24
B JTable Zellen zusammenfügen AWT, Swing, JavaFX & SWT 3
M Swing Cell Renderer für Zeilenumbruch in JTable AWT, Swing, JavaFX & SWT 0
H JTable im JSplitPane darstellen AWT, Swing, JavaFX & SWT 2
MadMax2506 Swing JTable lädt sehr lange AWT, Swing, JavaFX & SWT 1
D Zeilenumbruch in einer JTable AWT, Swing, JavaFX & SWT 9
R Swing JTable und Spaltenausrichtung AWT, Swing, JavaFX & SWT 8
G JTable füllen AWT, Swing, JavaFX & SWT 1
H JTable TableCellEditor-Problem AWT, Swing, JavaFX & SWT 0
W Swing JTable Zeilenumbruch innerhalb einer Zelle AWT, Swing, JavaFX & SWT 3
J Datensatz in jTable ausgeben AWT, Swing, JavaFX & SWT 3
M Swing Automatischer Editorstart in JTable-Zelle AWT, Swing, JavaFX & SWT 5
ralfb1105 Swing JTable aktualisieren AWT, Swing, JavaFX & SWT 5
adiko01 JTable: Nur markierte Zeilen aus der Tabelle in CSV exportiern AWT, Swing, JavaFX & SWT 9
M JTable.setDefaultRenderer(...) greift nicht AWT, Swing, JavaFX & SWT 0
J JTable: Eingabe in Tabellenzelle korrigieren AWT, Swing, JavaFX & SWT 4
T Problem mit JTable Sortierung AWT, Swing, JavaFX & SWT 2
D JTable nach INSERT aktualisieren /refreshen AWT, Swing, JavaFX & SWT 1
D MySQL Daten in JTable anzeigen AWT, Swing, JavaFX & SWT 2
H Swing Jtable extra spalte AWT, Swing, JavaFX & SWT 6
S Swing Rechteck über JTable zeichnen (per MouseListener) AWT, Swing, JavaFX & SWT 1
S Swing Mal wieder JTable Ansicht aktualisieren AWT, Swing, JavaFX & SWT 10
A JTable mit Daten füllen AWT, Swing, JavaFX & SWT 1
VfL_Freak Swing Einzelne Zeile in jTable selektieren klappt nicht AWT, Swing, JavaFX & SWT 7
N AWT jTable CellRenderer AWT, Swing, JavaFX & SWT 6
T Swing JTable valueChanged datensatz löschen AWT, Swing, JavaFX & SWT 1
0 Swing JTable aus anderer Klasse updaten AWT, Swing, JavaFX & SWT 5
S Jtable defaultRenderer wohin damit ? AWT, Swing, JavaFX & SWT 23
T Swing JTable / FocusListener AWT, Swing, JavaFX & SWT 0
it_is_all Warum wird die JTable im JDialog nicht angezeigt? AWT, Swing, JavaFX & SWT 1
L Swing JTable im Panel darstellen AWT, Swing, JavaFX & SWT 8
T Swing Double Click bei Buttons in JTable AWT, Swing, JavaFX & SWT 9
J addRow bei JTable AWT, Swing, JavaFX & SWT 6
M Jtable gibt -1 wert bei selectedRow und Column AWT, Swing, JavaFX & SWT 3
Meeresgott Swing JTable AWT, Swing, JavaFX & SWT 4
J JTable Selection Listener funktioniert nicht AWT, Swing, JavaFX & SWT 4
C Swing Daten in JTable wiedergeben per TableModel und MVC Pattern AWT, Swing, JavaFX & SWT 16
Z Swing Drag&Drop zwischen JTable und JTree AWT, Swing, JavaFX & SWT 4
Thallius JTable dynamisch Spaltenanzahl verändern AWT, Swing, JavaFX & SWT 2
Thallius JTable dynamisch laden? AWT, Swing, JavaFX & SWT 2
B Swing JTable sortieren AWT, Swing, JavaFX & SWT 2
T Swing JTable auslesen und befüllen AWT, Swing, JavaFX & SWT 8
B JTable wird nicht angezeigt AWT, Swing, JavaFX & SWT 1
J JTable und Suchlogik AWT, Swing, JavaFX & SWT 4
Viktim Swing JTable mit Tab verlassen AWT, Swing, JavaFX & SWT 1
F Swing Spaltenbreite einer Column eines JTable auslesen AWT, Swing, JavaFX & SWT 5
Viktim Swing JTable Mit Tab druch Zeilen Wechseln AWT, Swing, JavaFX & SWT 5
Thallius Warum refrehsed mein JTable nicht? AWT, Swing, JavaFX & SWT 5
Ghostman1711 Hinzufügen ausgewählter Dateinen des Filechoosers zu einem JTable AWT, Swing, JavaFX & SWT 9
S Swing JTable - Einzelne Rows einfärben AWT, Swing, JavaFX & SWT 11
M Wert einer Zelle aus JTable ziehen AWT, Swing, JavaFX & SWT 4
K JTable getValueAt() klappt nicht immer AWT, Swing, JavaFX & SWT 1
K JTable in extra Klasse, Zugriff in einer anderen klasse nicht möglich AWT, Swing, JavaFX & SWT 26
B Swing Tabelle(JTable) filtern swing GUI AWT, Swing, JavaFX & SWT 3
P JTable - bei Eingabe Selektion AWT, Swing, JavaFX & SWT 0
P Fokus auf Zelle in JTable AWT, Swing, JavaFX & SWT 1
S Swing Deselektion in JTable verhindern AWT, Swing, JavaFX & SWT 0
D Problem mit JTable AWT, Swing, JavaFX & SWT 1
N Swing Print JTable mit AbstractTableModel AWT, Swing, JavaFX & SWT 1
Ananaskirsche Swing jTable Reihen zuviel eingefügt AWT, Swing, JavaFX & SWT 12
P im JTable die Schriftfarbe ändern AWT, Swing, JavaFX & SWT 19
T Swing JTable wird nicht angezeigt AWT, Swing, JavaFX & SWT 4
S Dreiecke in bestimmte Zellen einer JTable AWT, Swing, JavaFX & SWT 9
LexeB4F Zelle in JTable gezielt einfärben AWT, Swing, JavaFX & SWT 4
LexeB4F JTable mehrere Zelle selektieren und inhalte Löschen.. Ideen gesucht AWT, Swing, JavaFX & SWT 1
D Swing JTable Renderer Grafikfehler AWT, Swing, JavaFX & SWT 0
K Swing JTable mit ImageIcon und Text in einer Zelle AWT, Swing, JavaFX & SWT 1
M Swing JTable GroupableHeader Background Color AWT, Swing, JavaFX & SWT 4
K Swing JTable updaten AWT, Swing, JavaFX & SWT 9
thet1983 Swing MySQL >> JTable AWT, Swing, JavaFX & SWT 5
J JTable bounds ändern durch resizing des Fensters AWT, Swing, JavaFX & SWT 9
F JTable Zellen-Hintergrund ändern AWT, Swing, JavaFX & SWT 7
O JTable linksbündig drucken (nicht der Zelleninhalt) AWT, Swing, JavaFX & SWT 2
Crazynet xls Datei in JTable AWT, Swing, JavaFX & SWT 3
O JTable ohne Rahmen printen AWT, Swing, JavaFX & SWT 3
L Swing JTable refresht die Column Namen nicht AWT, Swing, JavaFX & SWT 0
K JTable komplett durch andere ersetzen AWT, Swing, JavaFX & SWT 4
S JTable übernimmt Änderungen nicht AWT, Swing, JavaFX & SWT 2
Y JTable AWT, Swing, JavaFX & SWT 6
D Swing JCombobox in einem JTable vorbelegen AWT, Swing, JavaFX & SWT 4
R Swing JTable : Header der Spalten ergänzen mit caption (wie bei html-table) AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben