Tabulky v Javě
Z MiS
(Rozdíly mezi verzemi)
m (Přidána kategorie GUI) |
(Přidáno <code>getColumnClass(int)</code>.) |
||
(Nejsou zobrazeny 3 mezilehlé verze od 1 uživatele.) | |||
Řádka 13: | Řádka 13: | ||
== <code>javax.swing.table.AbstractTableModel</code> == | == <code>javax.swing.table.AbstractTableModel</code> == | ||
− | * Rozhraní <code>TableModel</code> má mnoho metod, které by se u většiny tabulek | + | * Rozhraní <code>TableModel</code> má mnoho metod, které by se u většiny tabulek opakovaly. |
− | * Abstraktní třída <code>AbstractTableModel</code> | + | * Abstraktní třída <code>AbstractTableModel</code> nabízí standardní implementaci většiny metod rozhraní <code>TableModel</code>. Stačí tedy zdědit tyto metody a předefinovat ty, u kterých vyžadujeme jiné než standardní chování. |
Řádka 21: | Řádka 21: | ||
− | + | === Abstraktní metody (musí být předefinovány) === | |
+ | Tyto metody volá třída <tt>JTable</tt>. Sdělíme jí tak, jaká data má v tabulce zobrazovat a jak velká má být tabulka. | ||
* <code>int getRowCount()</code> | * <code>int getRowCount()</code> | ||
+ | *: Touto metodou třídě <code>JTable</code> sdělujeme, kolik chcme mít v tabulce řádků. | ||
* <code>int getColumnCount()</code> | * <code>int getColumnCount()</code> | ||
+ | *: Touto metodou třídě <code>JTable</code> sdělujeme, kolik chcme mít v tabulce sloupců. | ||
* <code>Object getValueAt(int row, int column)</code> | * <code>Object getValueAt(int row, int column)</code> | ||
− | *: | + | *: Třída <code>JTable</code> se nás touto metodou ptá, co má vypsat do buňky na řádku ''row'' a ve sloupci ''column''. |
− | + | === Lze předefinovat také další metody === | |
− | * <code>String getColumnName(int col) | + | ; Nastavení nadpisů a datového typu sloupců: |
+ | * <code>String getColumnName(int col)</code> | ||
*: popis sloupce, tedy co se má zobrazit v hlavičce sloupce | *: popis sloupce, tedy co se má zobrazit v hlavičce sloupce | ||
− | * <code>boolean isCellEditable(int row, int col) | + | * <code>Class getColumnClass(int col)</code> |
+ | *: jaký datový typ se má zapisovat do tohoto sloupce? | ||
+ | *: například <code>Boolean</code> zajistí, že se v tabulce zobrazí zatržítka (checkbox). | ||
+ | |||
+ | ; Editovatelnost údajů v tabulce | ||
+ | * <code>boolean isCellEditable(int row, int col)</code> | ||
*: pokud vrátí <code>true</code>, pak bude buňka na řádku <code>row</code> a ve sloupci <code>col</code> editovatelná | *: pokud vrátí <code>true</code>, pak bude buňka na řádku <code>row</code> a ve sloupci <code>col</code> editovatelná | ||
*: při zapsání hodnoty <code>JTable</code> zavolá metody <code>setValueAt()</code>. | *: při zapsání hodnoty <code>JTable</code> zavolá metody <code>setValueAt()</code>. | ||
− | * <code>void setValueAt(Object, row, col) | + | * <code>void setValueAt(Object, row, col)</code> |
*: touto metodou informuje <code>JTable</code> naši třídu, že hodnota v buňce se změnila. Je na nás, abychom zařídili odpovídající úpravu našich dat. | *: touto metodou informuje <code>JTable</code> naši třídu, že hodnota v buňce se změnila. Je na nás, abychom zařídili odpovídající úpravu našich dat. | ||
− | + | === Jak s třídou pracujeme? === | |
* Typicky vytváříme potomka této třídy. | * Typicky vytváříme potomka této třídy. | ||
* Náš potomek přidává jako atribut data, která se mají zobrazovat v tabulce. | * Náš potomek přidává jako atribut data, která se mají zobrazovat v tabulce. | ||
*: Například pro tabulku s údaji studentů ve třídě by mohla fungovat třída <code>TridaModel</code>, která by byla potomkem <code>AbstractTableModel</code> a jako atribut měla <code>ArrayList<Student></code>, kde <code>Student</code> bude třída nesoucí informace o studentovi. | *: Například pro tabulku s údaji studentů ve třídě by mohla fungovat třída <code>TridaModel</code>, která by byla potomkem <code>AbstractTableModel</code> a jako atribut měla <code>ArrayList<Student></code>, kde <code>Student</code> bude třída nesoucí informace o studentovi. | ||
* Když <code>JTable</code> chce zobrazit tabulku, vyžádá si data od modelu. | * Když <code>JTable</code> chce zobrazit tabulku, vyžádá si data od modelu. | ||
− | *: V našem příkladě zavolá metodu <code>getValueAt</code> třídy <code>TridaModel</code> postupně pro čísla řádku a sloupce (1,1), (2,1),... atd. Každým voláním zjistí hodnotu jedné buňky a vypíše ji. | + | *: V našem příkladě zavolá metodu <code>getValueAt(...)</code> třídy <code>TridaModel</code> postupně pro čísla řádku a sloupce (1,1), (2,1),... atd. Každým voláním zjistí hodnotu jedné buňky a vypíše ji. |
* Pokud se uživatel pokusí do některé buňky zapsat, <code>JTable</code> mu to povolí pouze, pokud mu metoda <code>isCellEditable</code> vrátí <code>true</code>. | * Pokud se uživatel pokusí do některé buňky zapsat, <code>JTable</code> mu to povolí pouze, pokud mu metoda <code>isCellEditable</code> vrátí <code>true</code>. | ||
* Pokud je zápis povolen, předá <code>JTable</code> data našemu modelu | * Pokud je zápis povolen, předá <code>JTable</code> data našemu modelu | ||
− | *: Instance <code>JTable</code> tedy zavolá metodu <code>setValueAt</code> třídy <code>TridaModel</code>. Na toto volání je třeba zareagovat tak, že se vyhledá v seznamu správný student (podle čísla řádku) a upraví se jeho údaje (podle čísla sloupce zjistíme, který údaj se změnil). | + | *: Instance <code>JTable</code> tedy zavolá metodu <code>setValueAt(...)</code> třídy <code>TridaModel</code>. Na toto volání je třeba zareagovat tak, že se vyhledá v seznamu správný student (podle čísla řádku) a upraví se jeho údaje (podle čísla sloupce zjistíme, který údaj se změnil). |
− | ; Pokud se změní data | + | ; Pokud se změní data, je to třeba třídě <tt>JFrame</tt> sdělit |
− | * K tomu stačí zavolat připravené metody, které zdědíme ze třídy <code>AbstractTableModel</code> | + | * K tomu stačí zavolat připravené metody, které zdědíme ze třídy <code>AbstractTableModel</code>. |
* <code>void fireTableDataChanged()</code> — obecná změna dat | * <code>void fireTableDataChanged()</code> — obecná změna dat | ||
* <code>void fireTableRowsDeleted(int firstRow, int lastRow)</code> — smazání daných řádků | * <code>void fireTableRowsDeleted(int firstRow, int lastRow)</code> — smazání daných řádků | ||
* a další... | * a další... | ||
− | + | == Příklad použití == | |
− | + | public void setValueAt(Object obj, int row, int col) { | |
+ | Osoba osoba = this.osoby.get(row); | ||
+ | switch (col) { | ||
+ | case 0: | ||
+ | osoba.setJmeno(obj.toString()); | ||
+ | break; | ||
+ | case 1: | ||
+ | try { | ||
+ | osoba.setRokNarozeni(Integer.parseInt(obj.toString())); | ||
+ | } catch (NumberFormatException ex) { | ||
+ | ... | ||
+ | } | ||
+ | break; | ||
+ | ... | ||
+ | } | ||
+ | } | ||
+ | } | ||
== <code>javax.swing.JScrollPane</code> == | == <code>javax.swing.JScrollPane</code> == |
Aktuální verze z 4. 2. 2019, 12:00
Více viz: Oracle.com > Tutorial > Table.
Obsah |
javax.swing.JTable
- Zobrazuje data v podobě tabulky.
- Data pro zobrazení čerpá z libovolné třídy, která implementuje interface
TableModel
JTable table = new JTable(new MyTableModel());
javax.swing.table.AbstractTableModel
- Rozhraní
TableModel
má mnoho metod, které by se u většiny tabulek opakovaly. - Abstraktní třída
AbstractTableModel
nabízí standardní implementaci většiny metod rozhraníTableModel
. Stačí tedy zdědit tyto metody a předefinovat ty, u kterých vyžadujeme jiné než standardní chování.
- Řeší ošetření události a uložení posluchačů (listenerů).
- Pokud neřekneme jinak, tabulka je standardně needitovatelná.
Abstraktní metody (musí být předefinovány)
Tyto metody volá třída JTable. Sdělíme jí tak, jaká data má v tabulce zobrazovat a jak velká má být tabulka.
-
int getRowCount()
- Touto metodou třídě
JTable
sdělujeme, kolik chcme mít v tabulce řádků.
- Touto metodou třídě
-
int getColumnCount()
- Touto metodou třídě
JTable
sdělujeme, kolik chcme mít v tabulce sloupců.
- Touto metodou třídě
-
Object getValueAt(int row, int column)
- Třída
JTable
se nás touto metodou ptá, co má vypsat do buňky na řádku row a ve sloupci column.
- Třída
Lze předefinovat také další metody
- Nastavení nadpisů a datového typu sloupců
-
String getColumnName(int col)
- popis sloupce, tedy co se má zobrazit v hlavičce sloupce
-
Class getColumnClass(int col)
- jaký datový typ se má zapisovat do tohoto sloupce?
- například
Boolean
zajistí, že se v tabulce zobrazí zatržítka (checkbox).
- Editovatelnost údajů v tabulce
-
boolean isCellEditable(int row, int col)
- pokud vrátí
true
, pak bude buňka na řádkurow
a ve sloupcicol
editovatelná - při zapsání hodnoty
JTable
zavolá metodysetValueAt()
.
- pokud vrátí
-
void setValueAt(Object, row, col)
- touto metodou informuje
JTable
naši třídu, že hodnota v buňce se změnila. Je na nás, abychom zařídili odpovídající úpravu našich dat.
- touto metodou informuje
Jak s třídou pracujeme?
- Typicky vytváříme potomka této třídy.
- Náš potomek přidává jako atribut data, která se mají zobrazovat v tabulce.
- Například pro tabulku s údaji studentů ve třídě by mohla fungovat třída
TridaModel
, která by byla potomkemAbstractTableModel
a jako atribut mělaArrayList<Student>
, kdeStudent
bude třída nesoucí informace o studentovi.
- Například pro tabulku s údaji studentů ve třídě by mohla fungovat třída
- Když
JTable
chce zobrazit tabulku, vyžádá si data od modelu.- V našem příkladě zavolá metodu
getValueAt(...)
třídyTridaModel
postupně pro čísla řádku a sloupce (1,1), (2,1),... atd. Každým voláním zjistí hodnotu jedné buňky a vypíše ji.
- V našem příkladě zavolá metodu
- Pokud se uživatel pokusí do některé buňky zapsat,
JTable
mu to povolí pouze, pokud mu metodaisCellEditable
vrátítrue
. - Pokud je zápis povolen, předá
JTable
data našemu modelu- Instance
JTable
tedy zavolá metodusetValueAt(...)
třídyTridaModel
. Na toto volání je třeba zareagovat tak, že se vyhledá v seznamu správný student (podle čísla řádku) a upraví se jeho údaje (podle čísla sloupce zjistíme, který údaj se změnil).
- Instance
- Pokud se změní data, je to třeba třídě JFrame sdělit
- K tomu stačí zavolat připravené metody, které zdědíme ze třídy
AbstractTableModel
. -
void fireTableDataChanged()
— obecná změna dat -
void fireTableRowsDeleted(int firstRow, int lastRow)
— smazání daných řádků - a další...
Příklad použití
public void setValueAt(Object obj, int row, int col) { Osoba osoba = this.osoby.get(row); switch (col) { case 0: osoba.setJmeno(obj.toString()); break; case 1: try { osoba.setRokNarozeni(Integer.parseInt(obj.toString())); } catch (NumberFormatException ex) { ... } break; ... } }
}
javax.swing.JScrollPane
- Zajistí, aby se vykreslila jen část tabulky, pokud je tabulka moc veliká a nevleze se do okna.
- Pokud se tabulka nevleze do okna, zobrazí na okrajích okna posuvníky tak, abychom mohli zobrazit libovolnou část tabulky.
- Součásti
-
JViewPort
- místo, kde se zobrazují data
- může zobrazit hlavičku řádku či sloupce —
setColumnHeaderView
,setRowHeaderView
-
JScrollBar
— posuvníky- mohou a nemusí být zobrazeny
- standardně se zobrazují jen pokud je potřeba
- Použití pro zobrazení tabulky
JScrollPane scrollPane = new JScrollPane(table); panel.add(scrollPane);