====== Pole v jazyce Java ====== Pole v jazyce Java uchovávají počet prvků v poli (žlutý obdélník na následujícím obrázku) \\ a jednotlivé hodnoty (modré odélníky). Všechna pole jsou objektovými typy, přistupujeme k nim přes odkazy (ukazatele). \\ Proměnné typu pole (odkazy na pole) jsou nakresleny jako červené obdélníky. \\ Jednotlivá pole (tak jako jiné objekty) evidují ukazatele, které na objekt vedou. \\ Až zanikne poslední ukazatel na dané pole, pole také zanikne a paměť může být znovu přidělena jinému objektu. \\ Na obrázku počet ukaztatelů naznačují zelené čárky. \\ ( Skutečná implementace v Javě se může lišit, Java nemusí počítat jednotlivé ukazatele na objekt, může jiným způsobem sledovat zda ještě nějaké ukazatele na objekt existují. ) int [] a = { 1, 2, 3 ,4, 5, 6, 7 }; int [] b = new int [10]; int [] c = { }; int [] e = null; int [] p = a; Pokud přiřadíme ** p = a; ** oba ukazatele vedou na stejné pole. Můžeme dynamicky vytvořit nové pole zadané délky ** b = new int [10]; ** \\ Pole je inicializováno na nuly (případně false nebo null, podle typu pole) Pole může mít nula prvků (na obrázku pole **c**) Nebo může mít odkaz hodnotu **null** (na obrázku pole **e**) {{pole.png}} [[https://app.diagrams.net/|obrázek byl nakreslen pomocí draw.io]] ===== Zobrazení jednorozměrných polí v samostatných oknech ===== Pokusíme se v několika oknech zobrazit pole z předešlého odstavce. \\ Program naleznete na [[https://gitlab.fjfi.cvut.cz/culikzde/java-priklady|gitlab]] v adresáři **Array**. Vytvoříme nový **JFrameForm**, pojmenujeme ho **Display** a dáme do balíčku **experiment**. \\ Postup je podobný jako v předešlém [[intro|příkladu]] Ve funkci **main** deklarujeme lokální proměnné **a**, **b**, **c** a **e** stejn2 jako předešlém odstavci. \\ Pro každé pole zavoláme funkci **demo ("zobrazovaný název pole", identifikátor pole)** \\ Funkce **demo** bude mít za parametr **name** typu **String** a parametr **a** typu //jednorozměrné pole celých čísel//. \\ Všechna jednorozměrná pole celých čísel jsou téhož typu (nezávisle na délce pole), tento typ zapisujeme ** int [] **. \\ (Novější verze Javy dovolují hranaté závorky zapisovat až za deklarovaný identifikátor, podobně jako jazyk C.) Pole jsou objektové typy a stejně jako třídy jsou odvozeny od společnéjo typy jaba.lang.**Object** ) Funkce //demo// je volána ze statické funkce //main//, a tak musí být rovněž statická. \\ Ve funkci vytvořímee novou instanci trřídy **Display**, odkaz na instanci uložíme do proměnné **w**. \\ Okno zobrazíme a umístíme na obrazovce na souřadnici **x, y**. \\ Proměnné //x// a //y// musí být statické, aby byli dostupné ze statické funkce. \\ (Můžeme si je představit jako globální prooměnné v jazyce C nebo proměnné "schované" do jmenného prostoru v C++.) \\ Máme zde tedy i návod jak vytvářet nová okna, a nemusí to být jen ze statických funkcí. private static int x = 10; private static int y = 10; public static void demo (String name, int [] a) { Display w = new Display (name, a); w.setVisible (true); w.setLocation(x, y); y = y + w.getHeight() + 10; } public static void main(String args[]) { int a [] = { 1, 2, 3 ,4, 5, 6, 7 }; /* ... */ demo ("a", a); demo ("b", b); demo ("c", c); demo ("e", e); } Třídě **Display** přidáme ještě jeden konstruktor s parametry, ten zavolá původní konstruktor bez parametů ** this (); ** \\ Volání jiného konstruktoru musí být jako první příkaz konstruktoru. \\ Podle počtu a typů použitých parametrů se zavolá příslušný konstruktor. \\ Nebo zápisem ** super (případné parametry); ** zavoláme konstruktor nadřazené třídy, z které je naše třída odvozena. public Display() { initComponents(); } public Display (String name, int [] a) { this (); put (name, a); } Vlastní zobrazení provede funkce **put** se stejnými parametry jako konstruktor \\ (a jsou to stejné parametry jako jsme předali funkci //demo//). Zkontrolujeme zda odkaz na pole uložený v parametru **a** není **null**. Pokud není **null** můžeme zjistit poet prvků pole ** a.length ** ( a může to být i nula ) Jméno pole spolu s textem ".length" uložíme do **jLabel1** \\ Délku pole (jako číslo typu int) převedeme na řetězec znaků přičtením prázdného řetězce. \\ Sčítání //string + jiný_typ// nebo //jiný_typ + string// převádí jiný typ na řetězec znaků. \\ ( Je to jedinná předefinovaná aritmetická operace v Javě. ) Potom alokujeme jednorozměrné pole řetězců o **n** prvcích pojmenované **title**. A dvourozměrné pole **data** s jednou řádkou a **n** sloupci. String [] title = new String [n]; String [] [] data = new String [1] [n]; Do těchto polí schováme popisky a hodnoty z pole **a**. \\ Nakonec vytvoříme tabulku s jednou řádkou. \\ (Vytvoříme model - objekt dodávající tabulce data v nasšm případě z právě alokovaných polí.) DefaultTableModel model = new DefaultTableModel (data, title); jTable1.setModel (model); Pokud má pole nula prvků, schováme panel na kterém je tabulka. if (n == 0) jScrollPane1.setVisible (false); public void put (String name, int [] a ) { setTitle (name); if (a == null) { /* zobrazit cervene null */ } else { int n = a.length; jLabel1.setText (name + ".length"); jTextField1.setText ("" + n);// convert to string String [] title = new String [n]; String [] [] data = new String [1] [n]; for (int i = 0; i < n; i++) { title [i] = name + "[" + i + "]" ; data [0][i] = "" + a[i]; // convert to string } DefaultTableModel model = new DefaultTableModel (data, title); jTable1.setModel (model); if (n == 0) jScrollPane1.setVisible (false); } } Pokud je odkaz na pole roven **null** zobrazíme červený text null. if (a == null) { jLabel1.setText ("null"); jLabel1.setForeground (new Color (255, 0, 0)); jLabel1.setFont(new java.awt.Font("Dialog", 0, 36)); jTextField1.setVisible (false); jScrollPane1.setVisible (false); } ===== Výsledný program ===== Téměř celá třída pro okno: package experiment; import java.awt.*; import javax.swing.table.*; public class Display extends javax.swing.JFrame { public Display() { initComponents(); } public Display (String name, int [] a) { this (); put (name, a); } private void initComponents() { /* ... */ } public void put (String name, int [] a ) { setTitle (name); if (a == null) { jLabel1.setText ("null"); jLabel1.setForeground (new Color (255, 0, 0)); jLabel1.setFont(new java.awt.Font("Dialog", 0, 36)); jTextField1.setVisible (false); jScrollPane1.setVisible (false); } else { int n = a.length; jLabel1.setText (name + ".length"); jTextField1.setText ("" + n);// convert to string String [] title = new String [n]; String [] [] data = new String [1] [n]; for (int i = 0; i < n; i++) { title [i] = name + "[" + i + "]" ; data [0][i] = "" + a[i]; // convert to string } DefaultTableModel model = new DefaultTableModel (data, title); jTable1.setModel (model); if (n== 0) jScrollPane1.setVisible (false); } } private static int x = 10; private static int y = 10; public static void demo (String name, int a []) { Display w = new Display (name, a); w.setVisible (true); w.setLocation(x, y); y = y + w.getHeight() + 10; } public static void main(String args[]) { int a [] = { 1, 2, 3 ,4, 5, 6, 7 }; int b [] = new int [10]; int c [] = { }; int e [] = null; demo ("a", a); demo ("b", b); demo ("c", c); demo ("e", e); } /* ... */ } ===== Okna vytvořená programem ===== Ještě jednou zobrazovaná pole z funkce main. int a [] = { 1, 2, 3 ,4, 5, 6, 7 }; int b [] = new int [10]; int c [] = { }; int e [] = null; Výsledná okna, která vzniknou při spuštění třídy Display (pravou myší, Run File) {{array_1d.png}} [[https://gitlab.fjfi.cvut.cz/culikzde/java-priklady/-/blob/master/Array/src/experiment/Display.java|zdrojový text na gitlab]]