# jTable anpassen



## Senbei (6. Dez 2006)

Hallo,
ich habe gleich mehrere Probleme was die jTable angeht. Ich arbeite mit dem eclipse (3.2.1) Visual Editor (1.2.1), den finde ich auch ganz gut, vorallem weil er mir als Javanoob einiges an Syntax abnimmt.
Ich bin gerade an einem Projekt, bei dem ich Werte in eine jTable 
1.) selbst eintragen kann
2.) Werte berechnen und eintragen lasse
3.) per Drag and Drop und/oder Copy&Paste einfügen kann evtl. Kontextmenü -(geht noch nicht)

Außerdem soll 
* die Tabelle aus einem jTextField rauslesen können, aus wie vielen Zeilen sie bestehen soll
* per JRadioButton.isSelected() erkennen können, ob sie editierbar bzw nicht editierbar ist (selektieren soll aber gehn)
* die linke Spalte durchnummeriert sein

Zur Veranschaulichung vorab mal n Screenshot von meiner Tabelle (links):







Der betreffende Code für die Tabelle sieht so aus:


```
/**
	 * This method initializes jTable_Wertetabelle	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private JTable getJTable_Wertetabelle() {
		if (jTable_Wertetabelle == null) {
			DefaultTableModel defaultTableModel = new DefaultTableModel();
			defaultTableModel.addColumn("n"); 		//Spalte1 Überschrift
			defaultTableModel.addColumn("Werte");			
			
			//Das Funktioniert (noch) nicht:
			//Irgendwie sollte diese Zeile bei Änderung von jTextField_n.getText()
			//(nochmal)aufgerufen werden
			defaultTableModel.setRowCount(Integer.parseInt(jTextField_n.getText()));

			defaultTableModel.setColumnCount(2);
			jTable_Wertetabelle = new JTable();
			jTable_Wertetabelle.setName("Wertetabelle");
			jTable_Wertetabelle.setShowGrid(true);
			jTable_Wertetabelle.setCellSelectionEnabled(true);
			jTable_Wertetabelle.setRowHeight(18);
			jTable_Wertetabelle.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
			jTable_Wertetabelle.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
			jTable_Wertetabelle.setCellEditor(new TableCellEditor(){

	public Component getTableCellEditorComponent(JTable arg0, Object arg1, boolean arg2, int arg3, int arg4) {
		// TODO Auto-generated method stub
		return null;
		
	}

	public void addCellEditorListener(CellEditorListener arg0) {
	}

	public void cancelCellEditing() {
	}

	public Object getCellEditorValue() {
		// TODO Auto-generated method stub
		return null;
		
	}

	/**
	 * Tabelle nicht editierbar,
	 * wenn "Eingabe von Verteilunen" ausgewählt
         * -- FUNKTIONIERT NICHT !?
	 */
	public boolean isCellEditable(EventObject arg0) {
		//TODO Auto-generated method stub
		if (jRadioButton_Verteilungen.isSelected() == true)
			return false;
		else
			return true;
		
	}

	public void removeCellEditorListener(CellEditorListener arg0) {
	}

	public boolean shouldSelectCell(EventObject arg0) {
		// TODO Auto-generated method stub
		return false;
		
	}

        /**
	 * Editieren abbrechen
	 * wenn "Eingabe von Verteilunen" ausgewählt
         * -- FUNKTIONIERT NICHT !?
	 */
	public boolean stopCellEditing() {
		// TODO Auto-generated method stub
		if (jRadioButton_Verteilungen.isSelected() == true)
			return true;
		else
			return false;
		
	}});
			jTable_Wertetabelle.setModel(defaultTableModel);
			jTable_Wertetabelle.getColumnModel().getColumn(0).setPreferredWidth(40);
			jTable_Wertetabelle.getColumnModel().getColumn(1).setPreferredWidth(380);

			//damit kann ich nur aus der Tablle rausDraggn, aber nicht rein:
			jTable_Wertetabelle.setDragEnabled(true);			
			//Copy&Paste bzw. DROP -Funktion später hier

			jTable_Wertetabelle.setValueAt("0x0", 0, 0);
			jTable_Wertetabelle.setValueAt("Test 0x1", 0, 1);
						
			
			
		}
		return jTable_Wertetabelle;
	}
```

Code für das Textfeld unten links:


```
/**
	 * This method initializes jTextField_n	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getJTextField_n() {
		if (jTextField_n == null) {
			jTextField_n = new JTextField();
			jTextField_n.setBounds(new Rectangle(194, 517, 50, 20));
			jTextField_n.setPreferredSize(new Dimension(50, 20));
			jTextField_n.setText("20");
			jTextField_n.setMinimumSize(new Dimension(20, 20));	
			
			//Wenn is das Textfeld keine ganze Zahl eingegeben wird
			//erscheint rechts daneben in einem jLabel die Nachricht:
			//"Nur ganze Zahlen eingeben"
			//Wenn eine gültige Zahl eingegeben, verschindet der Text wieder
			// -- FUNKTIONIERT !
                        jTextField_n.addKeyListener(new java.awt.event.KeyListener() {
				public void keyPressed(java.awt.event.KeyEvent e) {
					// TODO Auto-generated Event stub keyPressed()					
				}
				public void keyTyped(java.awt.event.KeyEvent e) {
					try {
						Integer.valueOf(jTextField_n.getText());
						jLabel_Eingabefehler.setText("");
						}
					catch (NumberFormatException e1) {
						jLabel_Eingabefehler.setText("Nur ganze Zahlen eingeben");
					}
					if (jLabel_Eingabefehler.getText()==""){
						
					}
				}
				public void keyReleased(java.awt.event.KeyEvent e) {
				}
			});
			
		}
		return jTextField_n;


	}
```

Wie man das "Durchnummerieren" der ersten Spalte macht weis ich noch nicht. Mit einer for() vielleicht, wenn es nicht elleganter geht.

Ich habe auch schon einzelne Brocken, die mir die Suchfunktion zu meinen Problemen geliefert hat, ausprobiert - hat aber immer was nicht gepasst.
Hab ihr vielleicht Ideen, meinen Code um die fehlenden Features zu erweitern?

Danke vielmals jetzt schon^^
 :?  Senbei


----------



## André Uhres (7. Dez 2006)

Senbei hat gesagt.:
			
		

> * die Tabelle aus einem jTextField rauslesen können, aus wie vielen Zeilen sie bestehen soll
> * per JRadioButton.isSelected() erkennen können, ob sie editierbar bzw nicht editierbar ist (selektieren soll aber gehn)


1. DefaultTableModel#setRowCount
2. "public boolean isCellEditable(int rowIndex, int columnIndex)" vom DefaultTableModel überschreiben


----------



## Senbei (9. Dez 2006)

Aus dieser Antwort werd' ich nicht schlau.

1.  den "." durch ein "#" bringt mir den Syntaxfehler:
Multiple markers at this line:
- The methode setRowCount(int) is undefined for the type Hauptfenster.
- Syntax error on token "Invalid Charakter", invalid AssignmentOperator

2. wie und wo muss ich das reinschreiben? Wenn ich nämlich die Zeile

```
public boolean isCellEditable(EventObject arg0) {
```
mit der hier ersetze

```
public boolean isCellEditable(int rowIndex, int columnIndex) {
```
taucht ein Fehler in Zeile 26 auf:
"The type new TableCellEditor(){} nust implement the inherited abstract method Cell.isCellEditable(EventObject)"

Stehe aufm Schlauch...

edit:/> Zu der Drag'n'Drop Geschichte.... sehe ich das richtig, dass man in eine jTable nicht "reindroppen kann"? Dann wäre das Thema gegessen :B
(seihe hier)


----------



## André Uhres (9. Dez 2006)

1. # gehört nicht zur Syntax, wird aber oft in den Beschreibungen benutzt um die Klasse zu identifizieren, zu der die Methode gehört.

2. "public boolean isCellEditable(int rowIndex, int columnIndex)" ist eine Methode vom DefaultTableModel, wie ich bereits sagte.

EDIT: Bei Swing-Komponenten, die von Natur aus kein (oder nur begrenzt) Drag-and-Drop unterstützen, kann man dies nachprogrammieren.


----------



## Senbei (9. Dez 2006)

Und kannst du mir bitte auch verraten wie man die Methode des defaultTableModel überschreibt?


----------



## André Uhres (9. Dez 2006)

Eine Methode überschreibt man, indem man die Klasse erweitert zu der sie gehört, so wie du's beim TableCellEditor gemacht hast.


----------



## Senbei (16. Dez 2006)

André Uhres hat gesagt.:
			
		

> Bei Swing-Komponenten, die von Natur aus kein (oder nur begrenzt) Drag-and-Drop unterstützen, kann man dies nachprogrammieren.


Ist denn dann Copy and Paste einfacher zu aktivieren? Evtl. über ein Kontextmenü?
Wenn ja, wie heisst denn die "Methode"?

edit:\> ich sehe gerade, dass mit einem 'gemeinsamen' Clipboard (jtable <-> z.B. Excel)



			
				Stefan Matthias Aust hat gesagt.:
			
		

> Für Copy&Paste muss ein Applet vertrauenswürdig und damit signiert sein.
> In einigen Java-Versionen funktionierte das Clipboard auch ohne
> Signierung, dass ist/war aber ein Bug. Innerhalb des Applets könnte man
> in jedem Fall ein eigenes Clipoard benutzen, nur die Kommunikation mit
> der Außenwelt ist eingeschränkt.



Ok, ich kann mich damit abfinden wenn es nicht funktioniert, dann werd ich diese Funktion eben weglassen. Der Aufwand wäre dann zu hoch...


----------



## Senbei (30. Dez 2006)

Also das Problem mit der Editierbarkeit habe ich endlich lösen können, dazu musste ich die Zeile 9 (des ersten Codestücks) ändern/erweitern zu

```
DefaultTableModel defaultTableModel = new DefaultTableModel(){
				/**
				 * Tabelle nicht editierbar,
				 * wenn "Eingabe von Verteilunen" ausgewählt
				 */
				public boolean isCellEditable(int row, int col){
					if(col==0 || jRadioButton_Verteilungen.isSelected()==true)
						return false;
					else return true;
				}
			};
```

Mein nächstes Problem ist nun, dass ich nicht weis, wie ich die Methode 'cancelCellEditing' (Zeile 39) aufrufen soll.
Wenn 'neu berechnen' Button gedrückt wird soll dieses ausgeführt werden:
"Breche das Editieren der Tabelle ab (soll den selben Effekt bewirken wie 'beende die Eingabe durch Enter')."

Entweder funktioniert das, indem ich die Bedingung ('neu berechnen' wurde gedrückt) direkt in der Methode (Zeile 37-38) stelle:

```
public void cancelCellEditing() { 
  if(jButton_neuBerechnen./* wurde gedrückt */ == true
  fireEditingCanceled();   // <-- Fehler: The Method fireEditingCancelled() is undefined for the type new TableCellEditor(){}
   }
```

Oder indem ich mich schon im 'ActionListener' des 'neu berechnen' Buttons befinde und dort die Methode aufrufe:

```
//geht nicht
jTable_Wertetabelle.TableCellEditor.cancelCellEditing();
```
...funktioniert aber beides so nicht, aber ich denke ihr versteht was ich brauche. Eine Lösung würde mir schon reichen


----------



## Beni (30. Dez 2006)

In dem ActionListener:

```
jTable_Wertetabelle.getCellEditor().cancelCellEditing();
```
Mach aber noch einen Test rein, das Resultat von "getCellEditor" kann *null* sein!

P.S. eine Bemerkung zum Textfeld mit dem KeyListener: da hast du keine Garantie, dass der in jedem Fall anspricht, wenn der Text verändert wird. Mit einem DocumentListener, dem du dem Document (an das Document kommst du über "JTextField#getDocument()") hinzufügst, hättest du die Garantie :wink:


----------

