# Schiffe versenken - tableCellRenderer



## Silas770 (28. Okt 2015)

Hi,
ich darf/soll in der Schule für Informatik ein Zusatzprojekt machen und zwar das Spiel Schiffe versenken inkl. GUI. 
Insgesamt ist das Projekt schon so gut wie fertig, allerdings will ich, damit es etwas übersichtlicher ist, die Tabellen, in denen die Spielfelder dargestellt werden, farblich "gestalten" (siehe dazu auch das Bild von den Spielfeldern unten). Sprich: im linken Spielfeld sollen die Felder mit "0" blau sein, mit "#" gelb oder schwarz sein, mit "*" rot und im rechten Spielfeld sollen die Felder mit "0" weiß, mit "~" blau, mit "*" rot und mit "!" grün sein. 

Ich hab in vielen Foren schon gelesen, dass man dies mit tableCellRenderern realisieren kann. Allerdings habe ich noch in keinem Forum verstanden, wie genau man diese implementiert, wo der Quellcode für diese eingefügt werden muss und wie man diese aufruft.

Könnt ihr mir da helfen und mir die Sachen bezüglich den tableCellRenderern genauer erklären?

Ich würde mich über eure Hilfe sehr freuen. 

mfg Silas770

Spielfelder:


----------



## Silas770 (30. Okt 2015)

Ich dachte ja eigentlich immer, dass Foren dazu da wären, dass man sich gegenseitig bei Problemen hilft. Aber das scheint ja in diesem Forum nicht der Fall zu sein. Mal wieder ein Forum mehr, in dem man sich besser nicht registrieren sollte. ^^


----------



## Joose (2. Nov 2015)

Natürlich gibt es hier einige die versuchen zu helfen. Jedoch kann man niemanden zwingen auf einen Post zu antworten, da bleibt natürlich jeden selber überlassen ob er dir hier helfen will (falls er überhaupt das Wissen hat dir zur helfen).

Hier ein komplettes Beispiel mit TableCellRenderer. Eine Tablle bei der jede 2.Zeile eingefärbt wird.
http://www.java2s.com/Tutorial/Java/0240__Swing/implementsTableCellRenderer.htm


----------



## Flown (2. Nov 2015)

Vor allem, je mehr Code du deinerseits postest und je besser du dein Problem beschreibst, umso besser fallen die Antworten aus. 

Aber du stellst eine Frage wie TableCellRenderer funktionieren und wie man diese implementiert.  Darum antwortet keiner, denn das ist eine Sache die in zig Tutorials im Internet aufgegriffen werden und nicht nochmal extra für dich zusammengefasst werden. Man sollte schon Eigeninitiative zeigen.

Aber um den Good-Will zu beweisen: HIER ein Beispiel, wie gerade und ungerade Zeilen farblich anders dargestellt werden.


----------



## Silas770 (2. Nov 2015)

Erstmal Danke, dass ihr mir versucht zu helfen.

Ich hab jetzt mal versucht einen tableCellRenderer für meine Bedürfnisse zu implementieren:


Spoiler: tableCellRenderer





```
class tableRenderer implements TableCellRenderer {
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            JTextField editor = new JTextField();          
            if(value != null){
                editor.setText(value.toString());
            }
          
            if(table == eigeneSchiffeTable){
                editor.setHorizontalAlignment(JTextField.CENTER);
                editor.setForeground(Color.white);
                if(value.equals("0")){
                    editor.setBackground(Color.blue);
                }
                else if(value.equals("#")){
                    editor.setBackground(Color.yellow);
                }
                else if(value.equals("*")){
                    editor.setBackground(Color.red);
                }
            }
            else if(table == gegnSchiffeTable){
                editor.setHorizontalAlignment(JTextField.CENTER);
                editor.setForeground(Color.black);
                if(value.equals("0")){
                    editor.setBackground(Color.white);
                }
                else if(value.equals("~")){
                    editor.setBackground(Color.blue);
                }
                else if(value.equals("*")){
                    editor.setBackground(Color.red);
                }
                else if(value.equals("!")){
                    editor.setBackground(Color.green);
                }
            }
            return editor;
        }
    }
```




Die Erstellung der Tables sieht im Konstruktor der GUI wie folgt aus:


Spoiler: tables





```
renderer = new tableRenderer();

        String eigWater = spiel.getEigenesWasser();
        Object[][] tableInitialisierer1 = {
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater}};
        Object[] columnNames1 = {0,1,2,3,4,5,6,7,8,9};

        String gegnWater = spiel.getGegnUnknown();
        Object[][] tableInitialisierer2 = {
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater}};
        Object[] columnNames2 = {0,1,2,3,4,5,6,7,8,9};

        eigeneSchiffeTable = new JTable(tableInitialisierer1, columnNames1);
        eigeneSchiffeTable.setBounds(35, 35, 200, 200);
        eigeneSchiffeTable.setRowHeight(20);
        //eigeneSchiffeTable.setBackground(Color.blue);
        cp.add(eigeneSchiffeTable);
      
        /**
        DefaultTableCellRenderer eigeneSchiffeRenderer = new DefaultTableCellRenderer();
        eigeneSchiffeRenderer.setHorizontalAlignment( JLabel.CENTER );
        eigeneSchiffeRenderer.setForeground(Color.white); */
        for(int i=0; i<10; i++){
            eigeneSchiffeTable.getColumn("" + i).setMaxWidth(20);
            //eigeneSchiffeTable.getColumn("" + i).setCellRenderer(eigeneSchiffeRenderer);
        }

        gegnSchiffeTable = new JTable(tableInitialisierer2, columnNames2);
        gegnSchiffeTable.setBounds(280, 35, 200, 200);
        gegnSchiffeTable.setRowHeight(20);
        gegnSchiffeTable.setBackground(Color.white);
        gegnSchiffeTable.setEnabled(false);
        cp.add(gegnSchiffeTable);
      
        /**
        DefaultTableCellRenderer gegnSchiffeRenderer = new DefaultTableCellRenderer();
        gegnSchiffeRenderer.setHorizontalAlignment( JLabel.CENTER );
        gegnSchiffeRenderer.setForeground(Color.black); */
        for(int i=0; i<10; i++){
            gegnSchiffeTable.getColumn("" + i).setMaxWidth(20);
            //gegnSchiffeTable.getColumn("" + i).setCellRenderer(gegnSchiffeRenderer);
        }
```




Und die update-Funktion, mit der die tables immer aktualisiert werden und mit der eigentlich auch der tableCellRenderer aufgerufen werden sollte, sieht folgend aus:


Spoiler: update-Funktion





```
public void updateGUI(){
        schiffe4erField.setText("" + schiffe4erUebrig);
        schiffe3erField.setText("" + schiffe3erUebrig);
        schiffe2erField.setText("" + schiffe2erUebrig);

        Object[][] A1 = spiel.getSpielfeldArray("spielflaecheA1");
        Object[][] A2 = spiel.getSpielfeldArray("spielflaecheA2");

        for(int i=0; i<10; i++){
            for(int a=0; a<10; a++){
                Object cell1 = renderer.getTableCellRendererComponent(eigeneSchiffeTable, A1[i][a], false, false, i, a);
                Object cell2 = renderer.getTableCellRendererComponent(gegnSchiffeTable, A2[i][a], false, false, i, a);
              
                eigeneSchiffeTable.setValueAt(cell1, i, a);
                gegnSchiffeTable.setValueAt(cell2, i, a);
            }
        }
    }
```




Allerdings habe ich jetzt das Problem, dass das GUI dann so aussieht:




Hab mal in der Zelle (1|1) nachgeguckt, was da genau drin steht und da steht drin: 



Spoiler



javax.swing.JTextField[,0,0,0x0,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@8ea496,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=0,columnWidth=0,command=,horizontalAlignment=CENTER]


Und wie man sieht, sind die Zellen auch nicht blau im linken Table und die Schrift auch nicht weiß, wie es eigentlich im Renderer geschrieben steht.

Was hab ich denn da genau falsch gemacht?


----------



## Silas770 (2. Nov 2015)

Hab gerade den Fehler gefunden. Der Konstruktor, in dem die tables erstellt werden, sieht jetzt, wie folgt aus:


Spoiler: tables





```
//renderer = new tableRenderer();

        String eigWater = spiel.getEigenesWasser();
        Object[][] tableInitialisierer1 = {
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater},
                {eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater,eigWater}};
        Object[] columnNames1 = {0,1,2,3,4,5,6,7,8,9};

        String gegnWater = spiel.getGegnUnknown();
        Object[][] tableInitialisierer2 = {
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater},
                {gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater,gegnWater}};
        Object[] columnNames2 = {0,1,2,3,4,5,6,7,8,9};

        eigeneSchiffeTable = new JTable(tableInitialisierer1, columnNames1);
        eigeneSchiffeTable.setBounds(35, 35, 200, 200);
        eigeneSchiffeTable.setRowHeight(20);
        //eigeneSchiffeTable.setBackground(Color.blue);
        cp.add(eigeneSchiffeTable);
       
       
        tableRenderer eigeneSchiffeRenderer = new tableRenderer();
        //eigeneSchiffeRenderer.setHorizontalAlignment( JLabel.CENTER );
        //eigeneSchiffeRenderer.setForeground(Color.white);
        for(int i=0; i<10; i++){
            eigeneSchiffeTable.getColumn("" + i).setMaxWidth(20);
            eigeneSchiffeTable.getColumn("" + i).setCellRenderer(eigeneSchiffeRenderer);
        }

        gegnSchiffeTable = new JTable(tableInitialisierer2, columnNames2);
        gegnSchiffeTable.setBounds(280, 35, 200, 200);
        gegnSchiffeTable.setRowHeight(20);
        gegnSchiffeTable.setBackground(Color.white);
        gegnSchiffeTable.setEnabled(false);
        cp.add(gegnSchiffeTable);
       
       
        tableRenderer gegnSchiffeRenderer = new tableRenderer();
        //gegnSchiffeRenderer.setHorizontalAlignment( JLabel.CENTER );
        //gegnSchiffeRenderer.setForeground(Color.black);
        for(int i=0; i<10; i++){
            gegnSchiffeTable.getColumn("" + i).setMaxWidth(20);
            gegnSchiffeTable.getColumn("" + i).setCellRenderer(gegnSchiffeRenderer);
        }
```




Und die update-Funktion jetzt so:


Spoiler: update-Funktion





```
public void updateGUI(){
        schiffe4erField.setText("" + schiffe4erUebrig);
        schiffe3erField.setText("" + schiffe3erUebrig);
        schiffe2erField.setText("" + schiffe2erUebrig);

        Object[][] A1 = spiel.getSpielfeldArray("spielflaecheA1");
        Object[][] A2 = spiel.getSpielfeldArray("spielflaecheA2");

        for(int i=0; i<10; i++){
            for(int a=0; a<10; a++){

                eigeneSchiffeTable.setValueAt(A1[i][a], i, a);
                gegnSchiffeTable.setValueAt(A2[i][a], i, a);
            }
        }
    }
```




Funktioniert soweit so, wie es soll, nur sieht der table jetzt etwas merkwürdig aus und man sieht bspw. nicht mehr, welche Zelle man selektiert hat. Zum Vergleich mal wie es vorher ohne Renderer aussah und wie es jetzt mit aussieht:

ohne Renderer:




mit Renderer:


----------



## Silas770 (4. Nov 2015)

Hab es jetzt geschafft das alte Design wieder hinzubekommen, allerdings zeigt er immernoch nicht, welche Zeile und welche Zelle selektiert ist. 
Dachte eigentlich, dass man einfach das SelectionModel vom table abspeichern und dann im Renderer auf das TextField "setten" könnte, aber beim TextField, was im Renderer erstellt wird, kann man ja gar kein SelcetionModel setzen. 

Wie bekomm ich das denn wieder so hin, dass er mir anzeigt, welche Zeile und Zelle selektiert ist?

Würde mich über eure Hilfe freuen, weil dann hab ich das Projekt endlich fertig und kann mit meiner Facharbeit beginnen.


----------



## Silas770 (4. Nov 2015)

So, habs jetzt nochmal auf eigene Faust versucht und es einfach so gemacht, dass im tableCellRenderer wenn isSelected true entspricht, die Zelle hellgrau gefärbt wird. 

Somit wäre Project Schiffe versenken - done.


----------

