Strona główna > Java SE > JTable nie takie “straszne”.

JTable nie takie “straszne”.

Mamy okres wakacyjny, dla wielu w tym i mnie jest to czas wyjazdów do pracy, aby zarobić trochę pieniążków na chleb (czyt. kolejny rok studiów, itd.). Pomimo tego, że czasu nie mam za wiele, postanowiłem napisać cokolwiek, żeby blog nie był taki martwy. Temat dzisiejszej rozkminy prosty, ale na pewno przyda się początkującym adeptom Java którzy podobnie jak ja jeszcze nie dawno, staną w pewnym momencie do walki o ujarzmienie JTable.

Z moich obserwacji wynika, że kłopoty z prawidłową obsługą tabeli ma duża część początkujących. Zwykle wybierana przez nich droga rozwiązania nie jest najlepsza i kończy się dużą ilością kompletnie nie potrzebnego kodu, koszmarnego w utrzymaniu, zwłaszcza jeśli w programie mamy wiele różnych tabel. Wydaje mi się, że wynika to przede wszystkim z faktu nie znajomości wzorców projektów, szczególnie MVC, z którego to biblioteka Swing czerpie pełnymi garściami, gdzie nawet najmniejszy JButton jest przykładem tego wzorca.

Ale do rzeczy, model dla JTable jest implementacją interfejsu TableModel, programiści API wyręczyli nas z bezpośredniej implementacji tego interfejsu, tworząc jego szkieletową implementację AbstractTableModel, dzięki czemu odpada nam dużo roboty.

Przykład, model tabeli operujący na obiektach klasy Person:

public class PersonTableModel extends AbstractTableModel {

    private List<Person> persons = null;
    private final static Object[] columnNames = {"", "Imię", "Nazwisko", "Płeć",
        "Ulica","Nr. d/m", "Miasto", "Kod pocztowy", "Województwo",
        "Tel. kom", "Tel. dom", "Email"};

    private final static int HIDDEN_IDX = 0;
    private final static int NAME_IDX = 1;
    private final static int SURNAME_IDX = 2;
    private final static int GENDER_IDX = 3;
    private final static int STREET_IDX = 4;
    private final static int APARTMENT_IDX = 5;
    private final static int CITY_IDX = 6;
    private final static int ZIPCODE_IDX = 7;
    private final static int PROVINCE_IDX = 8;
    private final static int CELL_IDX = 9;
    private final static int PHONE_IDX = 10;
    private final static int EMAIL_IDX = 11;

    public PersonTableModel() {}

    @Override
    public int getRowCount() {
        if(persons==null) return 0;
        return persons.size();
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {

        if(persons == null) return null;
        Person p = (Person) persons.get(rowIndex);
        switch (columnIndex) {
            case HIDDEN_IDX:
                return p.getId();
            case NAME_IDX:
                return p.getName();
            case SURNAME_IDX:
                return p.getSurname();
            case GENDER_IDX:
                return p.getGender().toString();
            case STREET_IDX:
                return p.getStreet();
            case APARTMENT_IDX:
                return p.getApartment();
            case CITY_IDX:
                return p.getCity();
            case ZIPCODE_IDX:
                return p.getZipCode();
            case PROVINCE_IDX:
                return p.getProvince().toString();
            case CELL_IDX:
                return p.getCellNumber();
            case PHONE_IDX:
                return p.getPhoneNumber();
            case EMAIL_IDX:
                return p.getEmail();
            default:
                return p;
        }
    }

    @Override
    public String getColumnName(int column) {
        return columnNames[column].toString();
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return false;
    }

    public void setModelData(List<Person> persons) {
       this.persons =  persons;
    }
    public Person getPerson(int position) {
        return persons.get(position);
    }

}

Aby stworzyć model o podstawowej funkcjonalności wystarczy zaimplementować 3 metody abstrakcyjne:

  • public int getRowCount() – zwracającą liczbę wierszy w tabeli
  • public int getColumnCount() – analogicznie liczbę kolumn
  • public Object getValueAt(int rowIndex, int columnIndex) – zwracają wartość o podanych współrzędnych

Bardzo często w modelu dodaję się obsługę nagłówka tabeli, zwłaszcza jeśli mamy pewność, że liczba kolumn w tabeli nie będzie się zmieniać, wtedy należy przesłonić metodę public String getColumnName(int column), a jeśli chcemy zablokować możliwość edycji komórek tabeli przeciążamy metodę public boolean isCellEditable(int row, int column)
Jak widać model tabeli przechowuje referencję do kolekcji obiektów Person, gdy stan tej listy zmieni się wystarczy wywołać metodę fireTableDataChanged(), aby odświeżyć stan tabeli.

I to już wszystko, jak widać nie takie to straszne, więcej przydatnych informacji przechowuje skarbonka wiedzy suna: JTable Tutorial.

Kategorie:Java SE
  1. Brak komentarzy.
  1. No trackbacks yet.