# JSpinner in einer JTable?



## matzze2000 (13. Nov 2007)

Hallo,

ist es möglich einen JSpinner (oder beliebige andere GUI Klassen) in einer Tabelle zu verwenden? Ich wollte so ne Art Liste machen. Die erste und zweite Spalte der Tabelle sollte aus nem String bestehen und die letzte aus einem JSpinner in dem ich dann die Anzahl einstellen kann. Ich habe es so versucht:


```
//Erzeugt ein Object das dann in der Tabelle verwendet wird

javax.swing.JSpinner spinner = new javax.swing.JSpinner(new javax.swing.SpinnerNumberModel(10, 0, 100, 1));
		Object[][] data = new Object[][] { 
				   {"Neu", "Neues Dokument anlegen", spinner}, 
				   {"öffnen", "Vorhandenes Dokument öffnen", spinner}, 
				   {"Speichern", "Speichern des Dokumentes", spinner} 
				 };
```

Wenn die Tabelle dann erstellt wird steht in der Zelle in die der Spinner sollte 





> javax.swing.JSpinner[,0,0,0x0,invalid,layout=javax.swing.plaf.basic.BasicSpinnerUI$Handler,
> alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIRe
> source@53c015,flags=16777544,maximumSize=,minimumSize=,preferredSize=]



_[Edit by Beni: ein paar \n\r eingefügt zwecks Platzmanagement]_


----------



## GRudiD (13. Nov 2007)

Ohne mich viel damit auseinandergesetzt zu haben, würde ich sagen, dass du dir einen CellRenderer (und später auch einen CellEditor) schreiben musst. Siehe dir dazu einfach mal in den FAQs das JTable Tutorial an. Speziell Kapitel 4.
JTable und alles was damit zusammenhängt ist relativ komplex und nicht einfach zu verstehen. Also mach dir vorher ne Kanne Kaffee


----------



## matzze2000 (15. Nov 2007)

Hmm, also nachdem ich mich mit der JTable jetz schon ein bissel auseinander gesetzt habe und auch das ein oder andere Problem lösen konnte habe ich immer noch nicht so richtig ne Idee wie ich jetzt das mit den Spinnern in der Zeile lösen kann. Was ich gelesen habe ist, dass ich wohl für Tabellenfelder mit Integerwerten einen TableCellRenderer anlegen muss und in ihm definiere was denn nun genau gemacht werden soll wenn eine Integerzahl in einer Zelle steht. In dem Beispiel in dem Tutorial wurde das ja auch für einen Farbwert gemacht. Aber dort wurde ja nur Textfarbe und sowas geändert. So sieht der TableCellRenderer dort aus:


```
class ColorTableCellRenderer extends DefaultTableCellRenderer{ 
   public Component getTableCellRendererComponent(JTable table, Object value, 
         boolean isSelected, boolean hasFocus, int row, int column) { 
      super.getTableCellRendererComponent(table, value, isSelected, 
            hasFocus, row, column); 
       
      Color color = (Color)value; 
       
      setText( color.getRed() + ", " + color.getBlue() + ", " + color.getGreen() ); 
      setForeground( color ); 
       
      return this; 
   } 
}
```

Ich nehme an da muss was in der Art stehen, dass der Object-Wert in einen Integer umgewandelt werden muss und dann muss ich da irgendwie ein JSpinner rein schreiben... Oder geht das so garnich?[/code]


----------



## GRudiD (16. Nov 2007)

Genau. Die Methode, die zum Zeichnen einer Zelle aufgerufen wird lautet doch:

```
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
...
}
```

Diese gibt ein Component zurück. Im Standartrenderer ist das ein JLabel, bei dem du wie im Tut die Farbe etc. ändern kannst. Du willst ein statt dem JLabel ein JSpinner, also musst du dir vorher einen erstellen und diesen dann zurückgeben.


```
/* nur als Beispiel
 * du solltest allerdings nicht den DefaultTableCellRenderer nehmen (der erbt bereits von JLabel, was du ja nicht brauchst)  
 * sondern dir eine eigene Klasse schreiben, die TableCellRenderer implementiert
 */
		meinJTable.setDefaultRenderer(Integer.class, new DefaultTableCellRenderer() {
			JSpinner spinner = new JSpinner();
			
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
				super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				this.spinner.setValue((Integer) value);

				return this.spinner;
			}
		});
```

Analog dazu sollte es auch mit dem CellEditor funktionieren.

PS: Der Wert, der in value übergeben wird, ist der Wert aus deinem TableModel.getValueAt(..). Du musst diesen Wert also nicht umwandeln sondern nur entsprechend casten.


----------



## matzze2000 (26. Nov 2007)

Also im Prinzip funktioniert die Tabelle jetz so wie sie soll. Im Integerfeld wird ein Spinner dargestellt. Ich habe nur noch das eine Problem, dass nicht sofort alles in der Tabelle neu berechnet wird wenn ich einen anderen Wert einstelle. Das wird daran liegen, dass ich folgende Funktion im TableCellEditor nicht implementiert habe:


```
public TestEditor(){ 
        // Der Editor hört sich selbst ab, so kann er auf jede Benutzereingabe reagieren 
        getDocument().addDocumentListener( this ); 
    }
```

Im Beispiel kann man das ja einfach so machen, denn die Klasse TestEditor extends JTextField. Mein IntegerEditor extends aber JSpinner der die verwendeten Methoden (getDocument()) nicht besitzt. Ich weiß aber nicht so wirklich, was ich statt dessen da für nen Listener rein scheiben kann, damit immer wenn jemand die Anzahl im Spinner verändert auch ein Ereignis gesendet wird.


----------



## matzze2000 (26. Nov 2007)

Und ich hab noch ein Problem. Damit keine Negativen Werte eingegeben werden können habe ich noch das SpinnerNumberModel geändert:


```
class IntegerTableCellRenderer extends DefaultTableCellRenderer{ 
	   
	JSpinner spinner = new JSpinner(new SpinnerNumberModel( 0, 0, 1000, 1 ));
	
	public Component getTableCellRendererComponent(JTable table, Object value, 
	         boolean isSelected, boolean hasFocus, int row, int column) { 
	      super.getTableCellRendererComponent(table, value, isSelected, 
	            hasFocus, row, column); 
	       
	      this.spinner.setValue((Integer) value);
	      return this.spinner;
	   } 
	}
```

Nur leider hat das irgendwie keine Auswirkungen. Im Spinner kann ich trotzdem weiterhin fröhlich negative Zahlen einstellen :-\


----------

