Bei JTable die Anzahl einzugebener Zeichen festlegen

philbo

Mitglied
Hallo mal wieder...
könntet ihr mir nochmal helfen?
Also, ich habe eine JTable, die als tablemodel ein selbst geschriebenes tablemodel hat (das wiederum erbt von defaulttablemodel).
Nun möchte ich z.b. für Spalte 1 festlegen, dass maximal 20 Zeichen eingegeben werden können, für Spalte 2 100 usw.. Das geht doch bestimmt irgendwie recht einfach, oder?!

Gruß
Philipp
 
Zuletzt bearbeitet:
Nicht ganz trivial

Original geschrieben von philbo
Hallo mal wieder...
könntet ihr mir nochmal helfen?
Also, ich habe eine JTable, die als tablemodel ein selbst geschriebenes tablemodel hat (das wiederum erbt von defaulttablemodel).
Nun möchte ich z.b. für Spalte 1 festlegen, dass maximal 20 Zeichen eingegeben werden können, für Spalte 2 100 usw.. Das geht doch bestimmt irgendwie recht einfach, oder?!

Gruß
Philipp

Das ist nicht ganz trivial und umständlich, wenn Du für jede Spalte andere Eingaben erlauben möchtest.

Folgende Vorgehensweise:

1. Du benötigst einen eigenen (Default)CellEditor

2. Darin muss eine Methode aus dem Interface implementiert werden:
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)

3. Achte darauf, dass Du als Component ein JTextField zurückgibst.

4. Diesem JTextField wird ein Document zugewiesen, z.B.
private Document normalesDocument = new MyDocument();
myTextField.setDocument(normalesDocument);
return myTextField;

5. Dieses MyDocument (extends PlainDocument) prüft die eigentliche Eingabe mit der Methode
public void insertString(int offset, String s, AttributeSet attributeSet)
throws BadLocationException

6. Darin kannst Du nun die Eingabe einschränken.

7. Den anfangs angelegten CellEditor weist Du nun entweder der ganzen Tabellen zu
Code:
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...

Mit dieser Vorgehensweise können natürlich noch ganz andere Einschränkungen bei der Eingabe vorgenommen werden, z.B. nur negative Zahlen, nur positive, mit Komma, ohne Komma, Zahlen-Buchstabenkombinationen usw. usw.
 
Hmm, irgendwie ahnte ich schon beim lesen deines Beitrags, dass ich das nicht hinkriegen werden. Ich glaube meine Kenntnisse in Java reichen wohl noch nicht, um sowas zu schreiben...
Ich scheitere schon beim Anfang vom schreiben des CellEditors.
Vielleicht werde ich ja irgendwann soweit sein, so etwas bewerkstelligen zu können. :)

Momentan ist das aber noch ne Stufe (oder zwei) zu hoch für mich. Die Grundfunktionalität meiner Anwendung steht ja, allerdings hätte ich die wahrscheinlich ohne die Hilfe hier im Forum auch nicht hinbekommen (!)
 
Original geschrieben von philbo
Hmm, irgendwie ahnte ich schon beim lesen deines Beitrags, dass ich das nicht hinkriegen werden. Ich glaube meine Kenntnisse in Java reichen wohl noch nicht, um sowas zu schreiben...
Ich scheitere schon beim Anfang vom schreiben des CellEditors.
Vielleicht werde ich ja irgendwann soweit sein, so etwas bewerkstelligen zu können. :)

Momentan ist das aber noch ne Stufe (oder zwei) zu hoch für mich. Die Grundfunktionalität meiner Anwendung steht ja, allerdings hätte ich die wahrscheinlich ohne die Hilfe hier im Forum auch nicht hinbekommen (!)

Zwei Möglichkeiten:
1. Wir kauen das jetzt hier Schritt für Schritt durch.
2. Besorg Dir mIRC, xchat, mirande, Trillian o.ä. und gehe ins IRC. Du findest mich auf dem Server irc.german-elite.net im Channel #java

Letzteres ist schneller weil zeitnah/"live"

Auf jeden Fall solltest Du mal sagen, was/wo das Problem genau liegt.
 
Also ich glaube wenn ich hier auf dem Firmenrechner nen Chatprogramm installiere, könnte es ärger geben, wenn die sehen, dass ich hier chatte - außerdem komme ich glaub ich damit hier eh nicht "raus".

Mein Problem genau?!
Hmm, wenn ich das mal so genau beschreiben könnte...
also, ich weiß gar nicht genau, wie ich denn mit dem 1. Punkt, den du geschrieben hast, anfage...
Also ich muss mir irgendwie ne Klasse meinCelleditor schreiben, und dann darin die restlichen Schritte, die du mir geschrieben hast, durchführen, aber ich scheitere halt schon daran, dass ich nicht weiß, was denn in meiner Klasse stehen muss :-/
 
>Also ich glaube wenn ich hier auf dem Firmenrechner nen Chatprogramm installiere, könnte es ärger geben, wenn die sehen, dass ich hier chatte - außerdem komme ich glaub ich damit hier eh nicht "raus".

Hehe, OK.

>Mein Problem genau?!
>Hmm, wenn ich das mal so genau beschreiben könnte...
>also, ich weiß gar nicht genau, wie ich denn mit dem 1. Punkt, den du geschrieben hast, anfage...
>Also ich muss mir irgendwie ne Klasse meinCelleditor schreiben, und dann darin die restlichen Schritte, die du mir geschrieben hast, durchführen, aber ich scheitere halt schon daran, dass ich nicht weiß, was denn in meiner Klasse stehen muss :-/

Ich zitiere:
Folgende Vorgehensweise:

1. Du benötigst einen eigenen (Default)CellEditor

2. Darin muss eine Methode aus dem Interface implementiert werden:
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)

3. Achte darauf, dass Du als Component ein JTextField zurückgibst.

4. Diesem JTextField wird ein Document zugewiesen, z.B.
private Document normalesDocument = new MyDocument();
myTextField.setDocument(normalesDocument);
return myTextField;

zu 1, 2, 3 und 4:
Code:
public class MyCellEditor extends DefaultCellEditor // Punkt 1
{
 private JTextField m_textField = null;
 private Document normalesDocument = new MyDocument(); 
public MyCellEditor(JTextField textField) // Konstruktor
 {
   super(textField);
   m_textField = textField;
 }
 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) // Punkt 2
 {
   m_textField.setDocument(normalesDocument); // Punkt 4
   return m_textField; // Punkt 3
 }
}

Hm, setDocument kann man sicher auch an anderer Stelle setzen, z.B. im Konstruktor.

Ich denke, das hilft Dir erst einmal weiter. Sonst noch Fragen?
 
Mensch, danke schonmal soweit!
Und mit private Document normalesDocument = new MyDocument();
was soll denn damit erstellt werden - ich meine ich habe ja keine Methode MyDocument()...?
Bzw. das kann ich ja so nicht verwenden, oder muss ich noch was importieren?
 
Zuletzt bearbeitet:
Original geschrieben von philbo
Mensch, danke schonmal soweit!
Und mit private Document normalesDocument = new MyDocument();
was soll denn damit erstellt werden - ich meine ich habe ja keine Methode MyDocument()...?
Bzw. das kann ich ja so nicht verwenden, oder muss ich noch was importieren?

ich zitiere noch einmal:
"5. Dieses MyDocument (extends PlainDocument) prüft die eigentliche Eingabe mit der Methode
public void insertString(int offset, String s, AttributeSet attributeSet)
throws BadLocationException"

Es ist also eine Klasse namens MyDocument anzulegen, die von PlainDocument abgeleitet ist.:

Code:
public class MyDocument extends PlainDocument
{
	/**
	 * Die Interface-Methode aus dem Document
	 */
	public void insertString(int offset, String s, AttributeSet attributeSet)
		throws BadLocationException
	{
            if ( isValid(s) )
              super.insertString(offset, s, attributeSet);
	}

	/**
	 * Die prüfende Methode
	 */
        private boolean isValid(String str)
        {
            return true; // hier selbst prüfen
        }
}
 
Okay, ich hab die beiden Klassen jetzt bei mir eingebunden, auch wenn ich nicht wirklich genau weiß, was die genau machen :)
Und wie benutze ich die jetzt, um meine Spalten (TableColumns) dementsprechend zu begrenzen, also beim erstellen bzw füllen meiner JTable muss das ja geschehen?!

Danke übrigens nochmal, dass du dir soviel Zeit nimmst, um mir und auch anderen hier im Forum zu helfen!

Gruß
Philipp

P.S.: Schaue mir das Montag dann an, hab jetzt feierabend...vielleicht verstehe ich dann (mit neuer Frische) auch die Funktion der beiden Klassen.
Wünsche dir ein schönes Wochenende!
 
Original geschrieben von philbo
Okay, ich hab die beiden Klassen jetzt bei mir eingebunden, auch wenn ich nicht wirklich genau weiß, was die genau machen :)

Schau es Dir in Ruhe an, ist wirklich nicht schwer.

Und wie benutze ich die jetzt, um meine Spalten (TableColumns) dementsprechend zu begrenzen, also beim erstellen bzw füllen meiner JTable muss das ja geschehen?!

Erstelle einen neuen Konstruktor in der MyDocument, dem Du z.B. die erlaubte Anzahl Stellen übergibst. Dann fragst Du ab, ob der neue String, also der alte String plus der Neueingabe diese Länge überschreitet.
Z.B.
Code:
private int iNumberOfAllowedDigits = 10000;
public MyDocument(int allowedDigits) // Konstruktor
{
 iNumberOfAllowedDigits = allowedDigits;
}
public void insertString(int offset, String s, AttributeSet attributeSet)
		throws BadLocationException
	{
		if (s == null)
			return;

		String oldString = getText(0, getLength());
		String newString =
			oldString.substring(0, offset) + s + oldString.substring(offset);
		iStringOffset = offset;

		if ( isValid(s) && (newString.length() <= iNumberOfAllowedDigits))
			super.insertString(offset, s, attributeSet);
        }

Der Konstruktor-Aufruf im CellEditor für das MyDocument sieht dann für 10 Stellen z.B. so aus:
private Document normalesDocument = new MyDocument( 10 );

Danke übrigens nochmal, dass du dir soviel Zeit nimmst, um mir und auch anderen hier im Forum zu helfen!

Gruß
Philipp

Ich mache es ja gern, denn mir ging es anfangs genauso und ich war auch dankbar für jede Hilfe. :)

P.S.: Schaue mir das Montag dann an, hab jetzt feierabend...vielleicht verstehe ich dann (mit neuer Frische) auch die Funktion der beiden Klassen.
Wünsche dir ein schönes Wochenende!

Schau es Dir in Ruhe an, im Grunde haben wir jetzt die komplette Lösung hier vorliegen.
 

Neue Beiträge

Zurück