# Icon in JTable abbilden



## xadoX (11. Apr 2011)

Ich hab mehrere Icons in Paketen gespeichert.
Die Pakete lauten u.A.

resource.img.tango.16x16.actions
resource.img.tango.16x16.animations
...
resource.img.tango.22x22.actions
resource.img.tango.22x22.animations
...
resource.img.tango.32x32.actions
resource.img.tango.32x32.animations
...

Einer existierende JTable jt soll jetzt in die linke spalte ein beliebiges Icon aus den obigen Paketen hinzugefügt werden können.

Folgender Code führt zu einer NullPointerException


```
jt.setValueAt(new ImageIcon(getClass().getResource("dialog-error.png")), 0, 0);
```

Was mach ich falsch?


----------



## Michael... (11. Apr 2011)

xadoX hat gesagt.:


> Folgender Code führt zu einer NullPointerException
> 
> 
> ```
> ...


Wo ist die Angabe des Packages? Oben steht immer etwas von *resource.img.tango...*
Müsste dann wohl eher so ungefähr aussehen:

```
getResource("/resource/img/tango/dialog-error.png")
```


----------



## xadoX (11. Apr 2011)

Das ist wohl richtig. Die NullPointerException ist jetzt weg. Code sieht jetzt wie folgt aus.


```
URL pic_url = this.getClass().getClassLoader().getResource("resource/img/tango/16x16/status/dialog-error.png");
              ImageIcon ii = new ImageIcon(pic_url);
              jTableStatusBericht.setValueAt(ii, zaehler, 0);
```

Allerdings schreibt er in die Zelle jetzt folgendes:
"file:/C:/Users/.../build/classes/resource/img/tango/16x16/status/dialog-error.png" 

Das Icon wird leider nicht dargestellt.


----------



## L-ectron-X (11. Apr 2011)

Teil 4 von Beni's JTable-Tutorial könnte das klären: http://www.java-forum.org/java-faq-beitraege/7032-jtable-teil-4-darstellung-daten.html


----------



## xadoX (11. Apr 2011)

Dort steht



> Ein Blick in den Quellcode von JTable verrät, dass Number, Float, Double, Date, Icon, ImageIcon und Boolean eine Spezialbehandlung erhalten.



Dann sollte die Tabelle beim Aufruf von setValueAt doch auch das ImageIcon als solches erkennen und keinen String daraus machen.


----------



## Michael... (11. Apr 2011)

Hast Du denn - wie in dem Tutorial - die getColumnClass (richtig) überschrieben?


----------



## xadoX (12. Apr 2011)

Habs jetzt wie folgt gelöst:

Den DefaultTableCellRenderer erweitert und die Methode setValue überschrieben.


```
class KeyIconCellRenderer extends DefaultTableCellRenderer {
    public KeyIconCellRenderer() {
        URL pic_url = this.getClass().getClassLoader().getResource("resource/img/tango/16x16/status/dialog-error.png");
        ImageIcon ii = new ImageIcon(pic_url);
        setIcon(ii);
    }
    @Override
    public void setValue(Object value) {
        if (value instanceof Icon) {
            setIcon((Icon) value);
        } else {
            setIcon(null);
            super.setValue(value);
        }
    }
```

Dann in der Gui der Tabelle den neuen Renderer zugewiesen:


```
jTableStatusBericht.setDefaultRenderer(Object.class, new KeyIconCellRenderer());
```

Danach kann man mit setValueAt ein Icon in eine bestimmte Zelle schreiben


```
pic_url = this.getClass().getClassLoader().getResource("resource/img/tango/16x16/status/haken.png");
        haken = new ImageIcon(pic_url);
jTableStatusBericht.setValueAt(haken, 5, 10);
```


----------



## xadoX (12. Apr 2011)

Jetzt gibts noch ein kleines weiteres Problem. Ich rufe nacheinander zwei Funktionen auf.

```
verwaltung.getCategories();
verwaltung.getCategories2CS();
```

in der ersten Funktionen wird 

jTableStatusBericht.setValueAt(haken, 0, 0);

aufgerufen und in der zweiten dann

jTableStatusBericht.setValueAt(haken, 1, 0);

Jetzt werden die Haken erst gezeichnet, sobald die zweite Funktion beendet ist.
Wünschenswert ist es aber, dass der 1. Haken bereits gesetzt wird, wenn die erste Funktion beendet ist 
und der zweite dann sobald die zweite Funktion terminiert.

Gibts dazu ne Lösung?


----------



## André Uhres (12. Apr 2011)

Hallo xadoX,

versuch's mal so:


```
verwaltung.getCategories();
SwingUtilities.invokeLater(new Runnable() {

    @Override
    public void run() {
        verwaltung.getCategories2CS();
    }
});
```

Gruß,
André


----------



## xadoX (13. Apr 2011)

Ja, das klappt sehr gut.
Was wenn noch weitere Funktionen aufgerufen werden? Z.b. verwaltung.getCategoriesData() und verwaltung.getCategoriesCSData();

Müsste dann für jede dieser Funktionen ein asynchroner Thread (invokeLater erzeugt doch einen asynchronen Thread oder?) erzeugen?

Also so?

```
verwaltung.getCategories();
SwingUtilities.invokeLater(new Runnable() {
   @Override
    public void run() {
        verwaltung.getCategories2CS();
    }
});
SwingUtilities.invokeLater(new Runnable() {
   @Override
    public void run() {
        verwaltung.getCategoriesData() ;
    }
});
SwingUtilities.invokeLater(new Runnable() {
   @Override
    public void run() {
        verwaltung.getCategoriesCSData();
    }
});
```

Es kann gut sein das noch weitere Funktionen aufgerufen werden müssen. Gibt es da vielleicht eine kürzere Variante?

EDIT: so wie ich es jetzt implementiert hab geht es nicht. Also man kann wohl nicht mehrmals 
SwingUtilities.invokeLater(new Runnable() {...}
aufrufen. Wie ist es anders möglich?


----------



## xadoX (13. Apr 2011)

Habs jetzt so gelöst, dass ich in der jeweiligen run() Methode nochmals invokeLater aufgerufen hab.


```
verwaltung.getCategories();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                verwaltung.getCategories2CS();
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {                
                        verwaltung.getAttributesCS();
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {            
                                verwaltung.getAttributesXLS();
                            }
                        });
                    }
                });
            }
        });
```

Das geht aber doch bestimmt eleganter oder?!


----------

