Bei JTable die Anzahl einzugebener Zeichen festlegen

Hallo nochmal!
So ganz klappt das noch nicht...
irgendwie "meckert" Eclipse rum.
1.) Was muss denn der Rückgabewert insertString sein? Denke mal void ist richtig
Eclipse markiert mir allerdings einige Sachen...
2.)bei String oldString = getText(0, getLength()); ->The method getLength() is undefined for the type Schulungsunterlagenverwaltung
Was muss ich denn dafür noch importieren?

3.)if ( isValid(s) && (newString.length() <= iNumberOfAllowedDigits)) ->The method isValid() in the type Component is not applicable for the arguments (String)
4.)super.insertString(offset, s, attributeSet);->The method insertString(int, String, AttributeSet) is undefined for the type Frame

Und nochmal zum einbauen in meine JTable. Also, ich habe ja meine einzelnen TableColumns (z.B TableColumn tc1 = this.mytable.getColumn("Nr"); ).
Ich verstehe immernoch nicht so ganz, wie ich dann beispielsweise sagen, dass die tc1 nur z.b. 5 Stellen lang sein soll.
Du sagst im CellEditor...muss ich dann also per if-Klausel sagen:
if (column ==1)
private Document normalesDocument = new MyDocument(5);

oder wie? Hmm, sorry, aber mit dieser Sache stehe ich echt ziemlich auf dem Schlauch! Aber ich hoffe, ich werde das noch gebacken kriegen.

Gruß
Philipp
 
Original geschrieben von philbo
Hallo nochmal!
So ganz klappt das noch nicht...
irgendwie "meckert" Eclipse rum.
1.) Was muss denn der Rückgabewert insertString sein? Denke mal void ist richtig
Eclipse markiert mir allerdings einige Sachen...

void ist richtig.

2.)bei String oldString = getText(0, getLength()); ->The method getLength() is undefined for the type Schulungsunterlagenverwaltung
Was muss ich denn dafür noch importieren?

public class MyDocument extends PlainDocument
Das ist der casus knacktus!
Denn für PlainDocument existieren:
getLength() und insertString()

3.)if ( isValid(s) && (newString.length() <= iNumberOfAllowedDigits)) ->The method isValid() in the type Component is not applicable for the arguments (String)

Grmpf. Natürlich ist isValid(String string) keine Funktion aus Component. Ich hatte sie weiter oben einmal kurz in MyDocument eingebaut:
"
/**
* Die prüfende Methode
*/
private boolean isValid(String str)
{
return true; // hier selbst prüfen
}
"

4.)super.insertString(offset, s, attributeSet);->The method insertString(int, String, AttributeSet) is undefined for the type Frame

S.o. Diese Methode musst Du in MyDocument implementieren und nicht in deiner Hauptklasse!

Und nochmal zum einbauen in meine JTable. Also, ich habe ja meine einzelnen TableColumns (z.B TableColumn tc1 = this.mytable.getColumn("Nr"); ).
Ich verstehe immernoch nicht so ganz, wie ich dann beispielsweise sagen, dass die tc1 nur z.b. 5 Stellen lang sein soll.
Du sagst im CellEditor...muss ich dann also per if-Klausel sagen:
if (column ==1)
private Document normalesDocument = new MyDocument(5);

oder wie? Hmm, sorry, aber mit dieser Sache stehe ich echt ziemlich auf dem Schlauch! Aber ich hoffe, ich werde das noch gebacken kriegen.

Gruß
Philipp

Es ist doch im Grunde ganz einfach und ich habe es doch auch schon beschrieben. Ich zitiere noch mal:
7. Den anfangs angelegten CellEditor weist Du nun entweder der ganzen Tabellen zu

MyCellEditor cellEditor = new MyCellEditor();
myTable.setDefaultEditor(Object.class, cellEditor);

oder nur einzelnen Klassen:
myTable.setDefaultEditor(Integer.class, cellEditor);

Für letzteres ist im TableModel eine Methode getColumnClass(int i) zu implementieren. Anhand dessen orientiert sich die Tabelle auch, welcher Editor zu öffnen ist, falls kein eigener definiert wurde. Setz mal testweise eine ColumnClass auf Boolean.class, und Du wirst eine CheckBox zu sehen bekommen...

Und Dein

if (column ==1)
private Document normalesDocument = new MyDocument(5);

ist nur halb richtig, weil pro Klasse der Editor für die Tabelle gesetzt wird., s.o.

Also noch einmal:
Du setzt für die Tabelle einen CellEditor für eine bestimmte Klasse. Dieser CellEditor ist üblicherweise ein JTextField. Diesem JTextField wird in Deiner MyCellEditor-Klasse ein Document zugewiesen. So läuft die Aufrufkette.
Willst Du also für die Spalte "Name" eine andere Eingabe erlauben als für die Spalte "Nummer", so ist z.B. für die Spalte "Name" in getColumnClass() (zu finden in Deinem TableModel) die String.class zurückzugeben, für die Spalte "Nummer" Integer.class. Für jede der beiden Spalten ist nun ein eigener CellEditor zu setzen:

MyStringCellEditor stringCellEditor = new MyStringCellEditor();
myTable.setDefaultEditor(String.class, stringCellEditor);

MyIntegerCellEditor intCellEditor = new MyIntegerCellEditor();
myTable.setDefaultEditor(Integer.class, intCellEditor);

Usw.
D.h. diese Editoren musst Du entsprechend Deinen Wünsche anpassen. Aber ich möchte mich eigentlich ungern wiederholen und den ganzen Sermond noch einmal beschreiben, steht doch schon alles da.
 
Also...
sorry, vielleicht bin ich auch einfach nur zu blöd.
Logisch, dass ich die Methoden in MyDocument einbauen muss...
Fehlermeldungen hab ich jetzt soweit keine mehr, und ich glaube es auch teilweise verstanden zu haben, aber:
Was ich leider immernoch nicht kapiert habe, ist WO ich denn das
MyCellEditor cellEditor = new MyCellEditor();
mytable.setDefaultEditor(Boolean.class, cellEditor);
und später entsprechend für String.class etc aufrufen muss?! Das muss ich in meiner Hauptklasse einbauen, nachdem meine JTable erzeugt wurde, und bevor ich diese mit Inhalten fülle, richtig?!
Da muss ich ja ein JTextField übergeben (wie du ja auch schreibst), aber das ist mir eben nicht klar, welches TextField das sein soll.
 
Zuletzt bearbeitet:
Original geschrieben von philbo
Also...
sorry, vielleicht bin ich auch einfach nur zu blöd.
Logisch, dass ich die Methoden in MyDocument einbauen muss...
Fehlermeldungen hab ich jetzt soweit keine mehr, und ich glaube es auch teilweise verstanden zu haben, aber:
Was ich leider immernoch nicht kapiert habe, ist WO ich denn das
MyCellEditor cellEditor = new MyCellEditor();
mytable.setDefaultEditor(Boolean.class, cellEditor);
und später entsprechend für String.class etc aufrufen muss?! Das muss ich in meiner Hauptklasse einbauen, nachdem meine JTable erzeugt wurde, und bevor ich diese mit Inhalten fülle, richtig?!

Na endlich! Natülich dort. :)

Da muss ich ja ein JTextField übergeben (wie du ja auch schreibst), aber das ist mir eben nicht klar, welches TextField das sein soll.

Kannst entweder eine Instanzvariable anlegen oder ein anonymes übergeben.

Instanz:
private JTextField myTextField = new JTextField();
.
.
.
MyCellEditor cellEditor = new MyCellEditor(myTextField);
.


anonym:
MyCellEditor cellEditor = new MyCellEditor(new JTextField());
 
Hey, ich glaub ich bin dem Sinn von allem auf der Spur :-)
Kann so langsam immer mehr nachvollziehen

Aber eine Frage hätte ich jetzt noch:
Was meinstest du denn mit der Checkbox?
Setz mal testweise eine ColumnClass auf Boolean.class, und Du wirst eine CheckBox zu sehen bekommen...

Und nochmal zum Verständnis:
Du meinstest mit
Für jede der beiden Spalten ist nun ein eigener CellEditor zu setzen:

MyStringCellEditor stringCellEditor = new MyStringCellEditor();
myTable.setDefaultEditor(String.class, stringCellEditor);

MyIntegerCellEditor intCellEditor = new MyIntegerCellEditor();
myTable.setDefaultEditor(Integer.class, intCellEditor);
Dass ich in der Klasse MyCellEditor einfach neue Methoden schreibe, je nachdem wie viel unterschiedlich lange Spalten ich haben will, oder?!
 
>Aber eine Frage hätte ich jetzt noch:
>Was meinstest du denn mit der Checkbox?


Na in der Tabellenspalte werden dann anzuhakende Checkboxen angezeigt.


>Und nochmal zum Verständnis:
>Du meinstest mit
>Dass ich in der Klasse MyCellEditor einfach neue Methoden schreibe, je nachdem wie viel unterschiedlich lange Spalten ich haben will, oder?!


Nein. Ich meine unterschiedliche Konstruktoren in MyDocument. Jeder CellEditor muss dann ein anderes Document erzeugen und dessen JTextField zuweisen.
 
Könntest du mir nochmal ganz kurz beim Erstellen der unterschiedlichen Konstruktoren helfen? Ich wollte einfach in der Klasse
Code:
public class MyCellEditor extends DefaultCellEditor {
Meine Konstruktoren entsprechend Cell1Editor usw nennen, aber das klappt natürlich nicht so einfach, wie ich mir das gedacht hatte :(
Wollte es einfach wie folgt machen, aber da bin ich bestimmt wieder mächtig auf dem Holzweg...
Code:
public class MyCellEditor extends DefaultCellEditor // Punkt 1
{
 private JTextField m_textField = null;
 private Document normalesDocument; 
 public MyCellEditor(JTextField textField) // Konstruktor
{
   super(textField);
   normalesDocument = new MyDocument(5);
   m_textField = textField;

 }
public Cell1Editor(JTextField textfield){
super(textfield);
normalesDocument = new MyDocument(10);
m_textField = textField;
}
 
Original geschrieben von philbo
Könntest du mir nochmal ganz kurz beim Erstellen der unterschiedlichen Konstruktoren helfen? Ich wollte einfach in der Klasse
Code:
public class MyCellEditor extends DefaultCellEditor {
Meine Konstruktoren entsprechend Cell1Editor usw nennen, aber das klappt natürlich nicht so einfach, wie ich mir das gedacht hatte :(
Wollte es einfach wie folgt machen, aber da bin ich bestimmt wieder mächtig auf dem Holzweg...
Code:
public class MyCellEditor extends DefaultCellEditor // Punkt 1
{
 private JTextField m_textField = null;
 private Document normalesDocument; 
 public MyCellEditor(JTextField textField) // Konstruktor
{
   super(textField);
   normalesDocument = new MyDocument(5);
   m_textField = textField;

 }
public Cell1Editor(JTextField textfield){
super(textfield);
normalesDocument = new MyDocument(10);
m_textField = textField;
}

Aua! (s.o.)
Der Konstruktor hat natürlich immer den Klassennamen, aber eine andere Signatur. Nimm doch einfach sowas hier:

Code:
public MyCellEditor(JTextField textField, int digits) // Konstruktor
{
   super(textField);
   normalesDocument = new MyDocument(digits);
   m_textField = textField;
}

Man kann die beiden Konstruktoren natürlich noch geschickter zusammenspielen lassen, um redundanten Code zu vermeiden.
Z.B.

Code:
public MyCellEditor(JTextField textField) // Konstruktor
{
   this(textField, 999);
 }
 
OK, soweit funktioniert das schonmal, die Eingabe für die gesamte Tabelle zu begrenzen. Einmal müsstest du mir bitte noch beim implementieren von getComlumnClass in mein TableModel helfen, und dann ist dieser Mammut-Thread auch mal beendet :)
Und zwar wollte ich
Code:
	public Class getColumnClass (int column) {
		 if(column == 2)
		return;
		}
in mein Tablemodel einbauen, weiß aber nicht, was ich bei return angeben muss, es muss ja irgendwie die entsprechende Klasse für die Spalte zurückgegeben werden.
Und das zweite wäre dann noch: muss ich denn das getComlumnClass() beim erstellen meiner JTable noch extra aufrufen, oder geschieht dies automatisch, da es ja zum Tablemodel gehört? Wenn ja, wie behandele ich denn die Klasse, die mir zurückgegeben wurde, weiter, um den Aufruf von mytable.setDefaultEditor(String.class,stringCellEditor); richtig zu bewerkstelligen?
 
Original geschrieben von philbo
OK, soweit funktioniert das schonmal, die Eingabe für die gesamte Tabelle zu begrenzen. Einmal müsstest du mir bitte noch beim implementieren von getComlumnClass in mein TableModel helfen, und dann ist dieser Mammut-Thread auch mal beendet :)
Und zwar wollte ich
Code:
	public Class getColumnClass (int column) {
		 if(column == 2)
		return;
		}
in mein Tablemodel einbauen, weiß aber nicht, was ich bei return angeben muss, es muss ja irgendwie die entsprechende Klasse für die Spalte zurückgegeben werden.
Und das zweite wäre dann noch: muss ich denn das getComlumnClass() beim erstellen meiner JTable noch extra aufrufen, oder geschieht dies automatisch, da es ja zum Tablemodel gehört? Wenn ja, wie behandele ich denn die Klasse, die mir zurückgegeben wurde, weiter, um den Aufruf von mytable.setDefaultEditor(String.class,stringCellEditor); richtig zu bewerkstelligen?

Deine Frage beinhaltet quasi schon die Antwort, siehe die fett markierten Stellen. ;) DIe passen nämlich zusammen. :)
Code:
public Class getColumnClass (int column)
{
 if(column == 2)
 return String.class;
 else
  return Object.class;
}

Explizit aufrufen ist getColumnClass nicht.

Ein praktisches Konstrukt ist z.B.

Code:
	private Class[] classTypes =
	{ 
		String.class, 
		String.class, 
		Object.class, 
		Integer.class,
		Float.class,
		Boolean.class,
	};
	public Class getColumnClass(int columnIndex)
	{
		return classTypes[columnIndex];
	}

Je nachdem, wie viele Spalten von welcher Klasse vorhanden sind.

So, und jetzt möchte ich den goldenen Geduldsfaden verliehen bekommen. ;)
 
Zurück