# JTable sortieren nach Alphabet



## CelikBlek (11. Nov 2004)

Hallo,
ich möchte einen JTable sortieren. Habe mir den Tutorial hier im Forum durchgelesen. 
Die Frage nun ist: Geht es nicht einfacher? Ich habe eine JTable mit 2 Spalten und es soll Alphabetisch nach Spalte 1 sortiert werden ohne jegliches Extras wie beim Klick 
auf Spalte aufsteigend und absteigend sortieren usw.. Bloß bei init aufsteigend sortieren und die dazugehörige Zeile selbstverständlich mitschleppen.
Wie kann ich es am besten realisieren. 
Danke im voraus


----------



## thE_29 (11. Nov 2004)

Also ich finde mein SortDecorator is net so schwer zum Verstehen!

Musst du dir einfach angucken oder Benis Bsp (sind sicherlich leichter zu verstehen, als wenn du das JSortedTable anschaust )

oder du nimmst das JSortedTable


----------



## CelikBlek (11. Nov 2004)

kann ich nicht einfach die ausschlaggebende methode daraus kopieren und bei mir einbauen? wenn ja welche wäre es denn? der beispiel von beni ist ja etwas ausführlicher.


----------



## thE_29 (11. Nov 2004)

nunja, ausführlicher würde ich net sagen 

es ist nur auf mehrere Klassen aufgeteilt, jedenfalls funktioniert meins genausogut und hat nen quick sort drinnen!

Aber du müsstest nur die Funktionen die du brauchst rauskopieren, dann sollte das gehen!


----------



## CelikBlek (11. Nov 2004)

werde ich mal ausprobieren danke. melde mich danach wieder


----------



## CelikBlek (11. Nov 2004)

hatte mal noch eine frage. wie kann ich die tabellengröße dynamisch machen? 
also habe folgendes vor: ich habe eine tabelle mit irgendwelchen einträgen(2 spalten). daneben sind plus, minus buttons. 
wenn man auf plus drückt soll in der untersten zeile ein neuer eintrag entstehen, die ich in die tabelle hinzufügen kann. 
Was sollte ich denn für einen Konstruktor benutzen von JTable? 
habe bislanh den Konstruktor (Object[][], Object[]). sollte ich lieber den (Vector, Vector) nehmen? Habe ich auch schon versucht, aber dann zeigt die Tabelle nichts mehr :bahnhof: 
das programm listet alle Systemproperties in der JTable. so sieht es aus:
Spalte 1---------------Spalte 2____________Button plus
Key---------------------Wert
Eintrag 1--------------Eintrag1
Eintrag 2--------------Eintrag2


----------



## Beni (11. Nov 2004)

Das geht nur über das TableModel. Du kannst entweder das DefaultTableModel verwenden, oder selbst eines implementieren... guck mal in der FAQ nach, dort hat es noch mehr zu JTable :wink:


----------



## CelikBlek (11. Nov 2004)

danke 
habe zwar informatik studiert, aber habe im gesamten studium nicht einmal mit JTable programmiert...
irgendwie merkwürdig  :bahnhof:


----------



## CelikBlek (15. Nov 2004)

hallo, 
ich versuche die sortierung gerade einzubauen, aber irgend wie scheint es mir zu kompliziert zu sein. geht das nicht einfacher? ich will es doch nur sortieren?!?


----------



## Niki (15. Nov 2004)

Soweit ich weiss werden Einträge die zu einem TreeSet hinzugefügt werden automatisch sortiert. Ist wahrscheinlich nicht sehr performant, aber wenn ich das richtig verstanden habe möchtest du eh nur einmal sortieren, Für einfach die Sätze zu deinem TreeSet, und dann hole die Sätze wieder aus dem TreeSet raus und stecks in die Table.


----------



## CelikBlek (15. Nov 2004)

hallo,
habe gerade eine sehr leichte und uebersichtliche sortier Methode gefunden. falls es 
jemand ebenfalls benötigen sollte hier ist es:

```
...
    table.setAutoCreateColumnsFromModel(false);    
    sortAllRowsBy(model, 0, true);
    public void sortAllRowsBy(DefaultTableModel model, int colIndex, boolean ascending) {
        Vector data = model.getDataVector();
        Collections.sort(data, new ColumnSorter(colIndex, ascending));
        model.fireTableStructureChanged();
    }   
...
public class ColumnSorter implements Comparator {
        int colIndex;
        boolean ascending;
        ColumnSorter(int colIndex, boolean ascending) {
            this.colIndex = colIndex;
            this.ascending = ascending;
        }
        public int compare(Object a, Object b) {
            Vector v1 = (Vector)a;
            Vector v2 = (Vector)b;
            Object o1 = v1.get(colIndex);
            Object o2 = v2.get(colIndex);
    
            // Treat empty strains like nulls
            if (o1 instanceof String && ((String)o1).length() == 0) {
                o1 = null;
            }
            if (o2 instanceof String && ((String)o2).length() == 0) {
                o2 = null;
            }
    
            // Sort nulls so they appear last, regardless
            // of sort order
            if (o1 == null && o2 == null) {
                return 0;
            } else if (o1 == null) {
                return 1;
            } else if (o2 == null) {
                return -1;
            } else if (o1 instanceof Comparable) {
                if (ascending) {
                    return ((Comparable)o1).compareTo(o2);
                } else {
                    return ((Comparable)o2).compareTo(o1);
                }
            } else {
                if (ascending) {
                    return o1.toString().compareTo(o2.toString());
                } else {
                    return o2.toString().compareTo(o1.toString());
                }
            }
        }
    }
```
 :toll:


----------



## CelikBlek (16. Nov 2004)

Beni hat gesagt.:
			
		

> Das geht nur über das TableModel. Du kannst entweder das DefaultTableModel verwenden, oder selbst eines implementieren... guck mal in der FAQ nach, dort hat es noch mehr zu JTable :wink:


hatte noch mal eine frage. wie bekomme ich die ascending und descending icons in den header? habe den renderer implementiert und den in meinen header registriert. schrift usw. verändert sich auch, aber die icons kann ich nicht sehen? woran kann es denn liegen?


----------



## joschika77 (16. Nov 2004)

Ich versuche gerade deine Sortiermethode.Mal sehen.
Das andere von Beni ist zu umfangreich.
Das mit dem Header habe ich auch schon probiert.
Kriege ich auch nicht hin. Ich hatte zwar schon was drin im Header aber die Höhe des Headers war so minimal das man es kaum sehen konnte.Und somit habe ich es wieder verworfen.
Zeig doch mal dein Code vom Header usw.

MfG Ronn


----------



## CelikBlek (16. Nov 2004)

also das mit dem header habe ich auch hinbekommen.

```
private class PropertyTableHeaderRenderer extends DefaultTableCellRenderer {

        private Border m_borNormalBorder, m_borSelectedBorder;
        private Icon m_icAscendingIcon, m_icDescendingIcon, m_icEmptyIcon;
        private JLabel m_jbLabel = null;
        //
        private int m_iSortedColumn = 0;
        private boolean m_bAscending = false;

        public PropertyTableHeaderRenderer(){
            setHorizontalTextPosition( LEFT );
            m_borNormalBorder = BorderFactory.createBevelBorder( BevelBorder.RAISED );
            m_borSelectedBorder = BorderFactory.createBevelBorder( BevelBorder.LOWERED );
            //
            // Hier werden die Icons erzeugt
            m_icAscendingIcon = createAscendingIcon();
            m_icDescendingIcon = createDescendingIcon();
            m_icEmptyIcon = createEmptyIcon();
        }

        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column) {
            m_jbLabel = new JLabel();
            m_jbLabel.setText(value.toString());
            //
            // Sortierte Spalte und ist selektiert
            if( m_iSortedColumn == column && isSelected) {
                m_jbLabel.setBorder( m_borSelectedBorder );
                if( m_bAscending ) {
                    m_jbLabel.setIcon( m_icAscendingIcon );
                }
                else {
                    m_jbLabel.setIcon( m_icDescendingIcon );
                }
            }
            // Sortierte Spalte und ist nicht selektiert
            else if( m_iSortedColumn == column ) {
                m_jbLabel.setBorder( m_borNormalBorder );
                if( m_bAscending ) {
                    m_jbLabel.setIcon( m_icAscendingIcon );
                }
                else {
                    m_jbLabel.setIcon( m_icDescendingIcon );
                }
            }
            else {
                m_jbLabel.setBorder( m_borNormalBorder );
                m_jbLabel.setIcon( m_icEmptyIcon );
            }
            return m_jbLabel;
        }

        public void sorted( int sorted_column, boolean ascending ) {
            this.m_iSortedColumn = sorted_column;
            this.m_bAscending = ascending;
        }

        protected Icon createAscendingIcon(){
            return new Icon(){
                public int getIconHeight() {
                    return 3;
                }
                public int getIconWidth() {
                    return 5;
                }
                public void paintIcon(Component c, Graphics g, int x, int y) {
                    g.setColor( Color.BLACK );
                    g.drawLine( x, y, x+4, y );
                    g.drawLine( x+1, y+1, x+3, y+1 );
                    g.drawLine( x+2, y+2, x+2, y+2 );
                }
            };
        }

        protected Icon createDescendingIcon(){
            return new Icon(){
                public int getIconHeight() {
                    return 3;
                }
                public int getIconWidth() {
                    return 5;
                }
                public void paintIcon(Component c, Graphics g, int x, int y) {
                    g.setColor( Color.BLACK );
                    g.drawLine( x, y+2, x+4, y+2 );
                    g.drawLine( x+1, y+1, x+3, y+1 );
                    g.drawLine( x+2, y, x+2, y );
                }
            };
        }

        protected Icon createEmptyIcon(){
            return new Icon(){
                public int getIconHeight() {
                    return 3;
                }
                public int getIconWidth() {
                    return 5;
                }
                public void paintIcon(Component c, Graphics g, int x, int y) {}
            };
        }
    }
```
Dann musst du nur noch den header in einem mouseListener hängen und die sorted methode von oben aufrufen und es funktioniert ohne ende  und den repaint nicht vergessen.


----------



## joschika77 (16. Nov 2004)

Also ich habe noch Probleme mit dem Sortieren.
Ich habe die Klasse 
	
	
	
	





```
ColumnSorter
```
als innere Klasse genommen und die 
	
	
	
	





```
sortAllRowsBy()
```
 Methode übernommen.
Nun wird der Klick auf den Header abgefangen.Was mach ich dann?

MfG Ronn


----------



## CelikBlek (16. Nov 2004)

```
int m_iSortierSpalte = 0;
m_bAufsteigend = true;
...
                public void mousePressed(MouseEvent me){
                    m_iSortierSpalte = ((JTableHeader)me.getSource()).columnAtPoint(me.getPoint());
                    if (m_iSortierSpalte == 0) {
                        if (m_bAufsteigend) {
                            m_bAufsteigend = false;
                        }
                        else {
                            m_bAufsteigend = true;
                        }
                        sortAllRowsBy(m_dtm, m_iSortierSpalte, m_bAufsteigend);
                        m_pthr.sorted(m_iSortierSpalte, m_bAufsteigend);
                        m_dtm.fireTableStructureChanged();
                    }
                    else if (m_iSortierSpalte == 1) {
                        if (m_bAufsteigend) {
                            m_bAufsteigend = false;
                        }
                        else {
                            m_bAufsteigend = true;
                        }
                        sortAllRowsBy(m_dtm, m_iSortierSpalte, m_bAufsteigend);
                        m_pthr.sorted(m_iSortierSpalte, m_bAufsteigend);
                        m_dtm.fireTableStructureChanged();
                    }
                }
```
so sieht die mousePressed aus. übrigens ich habe nur 2 spalten.


----------



## joschika77 (16. Nov 2004)

Ich habe auch nur 2 Spalten.
Was ist 
	
	
	
	





```
m_pthr
```
 bei dir?

MfG Ronn


----------



## CelikBlek (16. Nov 2004)

oh sorry

```
PropertyTableHeaderRenderer  m_pthr = new PropertyTableHeaderRenderer();
```


----------



## joschika77 (16. Nov 2004)

Ach so!
Das ist die Klasse wo du das Dreieck einfügst,oder?
Die Klasse 
	
	
	
	





```
PropertyTableHeaderRenderer
```
habe ich auch als innere Klasse.
Leider kennt er 
	
	
	
	





```
return new Icon()
```
 & 
	
	
	
	





```
paintIcon(Component c, Graphics g, int x, int y)
```
nicht.Da macht der Compile Fehler.Hast du ne Ahnung?

Also das mit dem Sortieren klappt ja einwandfrei.Danke schon mal dafür.

MfG Ronn


----------



## CelikBlek (16. Nov 2004)

hast du den import gemacht?

```
import javax.swing.*;
```
genau die klasse fügt die kleinen dreiecke usw. an. der macht quasi den gesamten header design. schrift, dreieck usw.
nach dem import solltest du den icon kennen.


----------



## thE_29 (16. Nov 2004)

Und wenn ihr fertig seit, werdet ihr sehen das net wirklich viel unterschied zwischen euren Bsp, und Benis und meines sein wird 

Aber selber arbeiten ist immer besser :bae:


----------



## CelikBlek (16. Nov 2004)

also ich bin fertig und ist um einiges kürzer. muss aber auch zu geben, dass ich einige techniken von euch abgeguckt habe


----------



## joschika77 (16. Nov 2004)

Das ist importiert.
Er sagt immer 

```
Class must implement the inherited abstract method Icon.paintIcon(Component, Graphics, int, int)
Graphics cannot be resolved to a type
```
Keine Ahnung!

MfG Ronn


----------



## thE_29 (16. Nov 2004)

Naja, du hast einen kürzeren Sortier Source als ich (ich hab meinen ja auch selbst implementiert) 

Hab ja nur kurz über dein Bsp drübergesehen 

Aber sieht net aus


----------



## CelikBlek (16. Nov 2004)

bei euch hatte ich das problem, dass ich die interfaces nicht einbauen wollte, weil ich ziemlich grosses klassenstruktur habe.


----------



## joschika77 (16. Nov 2004)

Ich habe jetzt die 
	
	
	
	





```
PropertyTableHeaderRenderer
```
 als innere Klasse.
Am Anfang meiner Klasse implementiere ich

```
PropertyTableHeaderRenderer m_pthr = new PropertyTableHeaderRenderer();
```
Muß ich den Renderer jetzt noch der Tabelle übergeben oder so?

MfG Ronn


----------



## CelikBlek (16. Nov 2004)

nein. das ist der renderer für den header. du musst es den header übergeben.

```
m_pthr = new PropertyTableHeaderRenderer();
m_jth = m_propertyTable.getTableHeader();
m_jth.setDefaultRenderer(m_pthr);
```


----------



## joschika77 (16. Nov 2004)

Ja danke man. Das klappt.Sehr gut sogar.
Ich bin sicher das das hier noch so einige brauchen werden.
Ist es normal das in der 1 Spalte das Dreieck von Anfang an drin ist?

MfG Ronn


----------



## CelikBlek (16. Nov 2004)

ja weil beim initialisieren die erste spalte sortiert und so eingetragen wird. kannst du natürlich jederzeit ändern.

```
sortAllRowsBy(deinModel, spalte, m_bAufsteigend);
m_pthr.sorted(spalte, m_bAufsteigend);
```


----------



## joschika77 (16. Nov 2004)

CelikBlek funktioniert bei Dir die Bordergeschichte im Header?

MfG Ronn


----------



## CelikBlek (16. Nov 2004)

nein. aber ich weiss woran es liegt. ich brauche es nicht deshalb habe ich mich nicht darum gekümmert. wenn du es willst musst du in der PropertyTableHeaderRenderer Klasse und in der getTableCellRendererComponent rumspielen, dann geht es. ich fand es aber so schöner


----------



## joschika77 (16. Nov 2004)

Ja da habe ich schon rumgespielt.Aber irgendwie tut sich da nix.
Auch mit dem
	
	
	
	





```
setHorizontalTextPosition( LEFT );
```
 klappt nix. Z.B: RIGHT oder CENTER
oder bspw.

```
if(column == 0)
    setToolTipText("Ferienwohnung-Index");
 else
    setToolTipText("Verfügbare Ferienwohnungen");
```
Das macht er auch nicht.

MFg Ronn


----------



## CelikBlek (16. Nov 2004)

so geht es auch nicht. versuche es mal mit

```
m_jbLabel.setToolTipText("");
```
genau so bei alignment. das sollte gehen. wenn du nämlich nichts vor schreibst tut er es mit den Renderer, er soll es aber mit den JLabel.


----------



## joschika77 (8. Dez 2004)

Hallo!

Kann mir jemand erklären warum es mit dem TableHeaderRenderer mal geht und mal nicht.
Das heisst ich habe diesen Renderer einer Jtable zugewiesen.Da gehts auch.Also der Header ist und bleibt normal.
Nun ist das Problem wenn ich den Renderer nun auch noch einer anderen JTable im selben Prog zuweise
klappts bei der zweiten Tabelle mit dem Header nicht mehr.Der ist dann in der Höhe nur ganz schmal.
Weiss jemand woran das liegen kann?

MfG


----------



## Beni (8. Dez 2004)

Soviel ich weiss kann jeder Header nur einer Tabelle zugewiesen werden (das war jedenfalls der Sinn...), also versuch einfach mal eine zweite Instanz dieses Headers der zweiten Tabelle zuzuordnen.


----------



## joschika77 (8. Dez 2004)

Ne das ist klar.
War ein anderen Problem.
Hatte dem spaltennamen Array in einer Zeile kein Namen übergeben.
Damit kam er nicht klar.

Etwa so:

```
final String spaltennamen[] ={"","Name","Von","Bis","Ferienobjekt"};
```

Und so muss es:

```
final String spaltennamen[] ={"Index","Name","Von","Bis","Ferienobjekt"};
```

Danke trotzdem fürs Interesse.

MfG


----------

