Java a řazení záznamů v JTable

Jan1122

Java a řazení záznamů v JTable
« kdy: 10. 12. 2011, 11:03:25 »
Ahoj.

Dokázal by mi někdo poradit s řazením dat v JTable?

Mám vytvořenou vlastní třídu, která je potomkem TableRowSorter a metodě getComparator(int column) jsem si vytvořil vlastní comparator. Funguje to, ale já bych potřeboval při řazení brát ohled také na data v jiných sloupcích.

Mám tabulku:

Jan;Praha
Petr;Olomouc
Jana;Brno
Tomáš;Praha
Pavel;Plzeň
Jan;Brno
Ivana;Praha
Veronika;Praha

A když kliknu na hlavičku tabulky se jménem, potřeboval bych to seřadit tak, aby se seřadili jména s ohledem na město. Tedy nějaký takový výsledek:


Ivana;Praha
Jan;Praha
Tomáš;Praha
Veronika;Praha
Jan;Brno
Jana;Brno
Pavel;Plzeň
Petr;Olomouc

Mám seřazené jména podle abecedy v Praze, potom Brno, pak Plzeň a Olomoouc. Na řazenítěch měst mi nezáleží jestli budou nějak podle abecedy, ale potřebuji, aby ty jména, která jsou seřazeny po sobě, byly ze stejného města.
« Poslední změna: 12. 12. 2011, 12:29:47 od Petr Krčmář »


k77

Re:Java - řazení záznamů v tabulce s ohledem na jiný sloupeček
« Odpověď #1 kdy: 10. 12. 2011, 11:23:22 »
Predpokladam, ze existuje nejaka trieda Person, ktora okrem mena ma aj mesto..

Potom staci do komparatoru pridat najprv porovnanie mesta a potom ak sa mesta rovnaju tak porovnanie mena..

Jan1122

Re:Java - řazení záznamů v tabulce s ohledem na jiný sloupeček
« Odpověď #2 kdy: 10. 12. 2011, 11:44:27 »
Díky. To mě také napadlo, že by to bylo dobré. Jenže problem je v tom, že mi nejde vytvořit jiný comparator než stringový.

V abstractTableModelu mám v metodě: public Object getValueAt(int rowIndex, int columnIndex)
return personList.get(row);

v personList je seznam všech Person
Ta třída Person má v toString(), aby vracela String name;

A takhle nyní vypadá ta třída pro řazení tabulky:
Kód: [Vybrat]
private class PersonsRowSorter extends TableRowSorter<PersonTableModel> {

public PersonsRowSorter(PersonTableModel model) {
super(model);
}

@Override
public Comparator<?> getComparator(int column) {
if (getColumnName(column).equals("jmeno")) {
return personComparator();
} else {
return super.getComparator(column);
}
}

private Comparator<Person> personComparator() {
Comparator<Person> comparator = new Comparator<Person>() {

@Override
public int compare(Person o1, Person o2) {
return 0;
}
};

return comparator;
}
}

Ale po kliknutí na hlavičku tabulky vyběhne chyba: ClassCastException - String cannot be cast to Person
A pokud použiji String moc mi to nepomůže, protože nevím jaký záznam se porovnává, znám jen ty dva porovnávané řetězce. Pokud bych se dokázal dostat v tom coparatoru i na hodnoty v ostatních sloupcích, už by to bylo dobré. Ale bohužel nevím jak a nebo ani jak jinak to udělat. Nebo jestli to musím celé implementovat jiným způsobem?

dTTb

Re:Java - řazení záznamů v tabulce s ohledem na jiný sloupeček
« Odpověď #3 kdy: 10. 12. 2011, 13:24:48 »
Jestli je javovskej sort() stabilni, tak by mohlo jit seradit to podle jmena a pak znova podle mesta.

k77

Re:Java - řazení záznamů v tabulce s ohledem na jiný sloupeček
« Odpověď #4 kdy: 10. 12. 2011, 16:22:35 »
Aha, zle som precital problem :)

Takze malo by to byt nejak takto (gettery a settery si domyslite a toString vracia name :) ), je to len narychlo urobene, ale princip je takyto..

Kód: [Vybrat]
public class Person implements Comparable {
    private String name;
    private String city;
   
    @Override
    public int compareTo(Object o) {
        Person p = (Person) o;
        if(p.getCity().compareTo(this.getCity()) != 0) {
            return this.getCity().compareTo(p.getCity());
        } else {
            return this.getName().compareTo(p.getName());

        }
    }

Kód: [Vybrat]
public class PersonTableModel extends AbstractTableModel {
    PersonDB db = new PersonDB();
    @Override
    public int getRowCount() {
        return db.persons.size();
    }

    @Override
    public int getColumnCount() {
        return 2;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if(columnIndex > 1) return null;
        return columnIndex == 0 ? db.persons.get(rowIndex) : db.persons.get(rowIndex).getCity();
    }
   
    @Override
    public Class getColumnClass(int columnIndex) {
        if(columnIndex == 0) return Person.class;
        else return String.class;
    }
}

PersonDB je defacto len List<Person>.
getValueAt pre stlpec kde je meno vrati objekt Person, nie len meno. Pre tento stlpec je aj trieda stlpca nastavena na Person.

V triede kde sa pouziva tabulka uz len:
Kód: [Vybrat]
PersonTableModel ptm = new PersonTableModel();
TableRowSorter trs = new TableRowSorter<PersonTableModel>(ptm);
jTable.setModel(ptm);
jTable.setRowSorter(trs);