Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Jan1122 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.
-
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..
-
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:
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?
-
Jestli je javovskej sort() stabilni, tak by mohlo jit seradit to podle jmena a pak znova podle mesta.
-
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..
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());
}
}
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:
PersonTableModel ptm = new PersonTableModel();
TableRowSorter trs = new TableRowSorter<PersonTableModel>(ptm);
jTable.setModel(ptm);
jTable.setRowSorter(trs);