[[oktatas:programozás:java|< Java]] ====== Java GUI Swing csomaggal ====== * **Szerző:** Sallai András * Copyright (c) 2011, Sallai András * Szerkesztve: 2011-2023 * Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC BY-SA 4.0]] * Web: https://szit.hu ===== Bevezetés ===== A fejezet feldolgozásához szükség van a Java nyelv, és a Java OOP ismeretére. A Java nyelvbe épített első GUI programozói könyvtár az AWT volt. Az AWT programozói eszközkészlet úgy működik, hogy az ablakok a komponensek megjelenítését az operációs rendszer ablakkezelőjére bízza, minden operációs rendszeren. Ennek eredménye, hogy ugyanaz a program másként néz ki Windowson, Linuxon, MacOS-en vagy más rendszeren. A Swing eszközkészletet úgy alakították ki, hogy maga határozza meg hogyan nézzen ki a program ablaka. Így egységes kinézetet kapunk minden operációs rendszeren. ===== Ablak ===== ==== Első program ==== A Java alapismeretek alapján, az első programunk, amely egy ablakot jelenít meg az alábbiak szerint nézhet ki. import javax.swing.JFrame; class Program { public static void main(String args[]) { JFrame ablak = new JFrame(); ablak.setSize(400, 300); ablak.setVisible(true); } } A fenti program egy szimpla ablakot valósít meg, amelynek a mérete 400x300-as. {{:oktatas:programozas:java:hellovilag_ablak.png|}} Alapértelmezetten, amikor a felhasználó kattint a bal felső sarokban a bezárásra, az ablak ugyan bezáródik, de a program nem. A programot a terminálablakba kattintva tudjuk leállítani, egy Ctrl+C billentyűkombinációval. ==== Az első program elemzése ==== Az ablak létrehozásához JFrame osztályt használjuk, ezért az első kódot tartalmazó sorban importáljuk ezt az osztályt: import javax.swing.JFrame; A JFrame a javax.swing csomagban található, ezért importálásnál ezt az útvonalat adtuk meg. A programban egy ablak nevű objektumot deklarálunk, aminek a típusa JFrame: JFrame ablak Rögtön helyet is foglalunk az objektum számára: new JFrame(); A JFrame() konstruktort hívjuk paraméterek nélkül. A következő utasítás beállítja az ablak méretét: ablak.setSize(400, 300); A következő utasítás megjeleníti az ablakot. Ennek az utasításnak az utolsónak kell lenni. ablak.setVisible(true); A programunk magját tulajdonképpen a main() metódusban hoztuk létre, hagyományos módon: JFrame ablak = new JFrame(); ablak.setSize(400, 300); ablak.setVisible(true); Ha futtatjuk a programot, az ablak bezárása után, ne felejtsük el a programot is leállítani Ctrl+C billentyűkombinációval a terminálablakban. ==== Második program ==== A második programunk eredménye mindenben megegyezik az előzővel, viszont másként valósítottuk meg. Kihasználjuk a Java objektum orientált lehetőségeit, és a megvalósításhoz az öröklést használjuk. import javax.swing.JFrame; class Program extends JFrame { Program() { this.setSize(400, 300); this.setVisible(true); } public static void main(String args[]) { new Program(); } } ==== A második program elemzése ==== Az első sor ugyanúgy importálja a JFrame osztályt mint az első programunk. A főosztályunkban viszont most látunk egy "extends JFrame" kiegészítést. Az "extends" arra ad utasítást, hogy a JFrame összes tulajdonságát és metódusát átörökítjük a Program osztályunk számára. Ettől kezdve a Program osztály úgy viselkedik mint egy JFrame objektum. A programosztályon futtatható az összes metódus amivel rendelkezik a JFrame osztály. Ilyen metódus a példában szereplő setSize() és setVisible() metódus is. Program() { this.setSize(400, 300); this.setVisible(true); } A Program osztályon belül létre kell hozni egy speciális metódust, a "konstruktort"! Az objektum orientált tanulmányaikból tudhatjuk, hogy ennek meg kell egyeznie az osztály nevével. A példában ennek megfelelően egy Program() nevű konstruktort hoztunk létre a main() metódus előtt. Az ablakunk beállításit ebben a konstruktorban adom meg. Lásd this.setSize(400, 300); this.setVisible(true); Ahhoz, hogy a program elinduljon a main() metódusban meg kell hívnunk a konstruktorunkat: new Program(); ==== Ablakbezárás esemény ==== A grafikus programok eseményvezéreltek. A program folyamatosan fut, és események bekövetkezését várja. Ilyen események az egérkattintás és a billentyűzetnyomás, egy komponens valamely tulajdonságának megváltozása, stb. Egy normál alkalmazás ablak címsorában van egy bezárás gomb, általában valamilyen "X" alakzat, egy minimalizálás és egy maximalizálás gomb. A bezárás gombra kattintva kiváltódik az úgynevezett "Close" esemény. Ez az ablak elrejtését jelenti, de nem a program befejezését, bár általában a főablak elrejtésével együtt a program befejezését is szeretnénk. A következő programban egy alapértelmezett kezelőt adunk az ablakhoz, amely megvalósítja a program befejezését, ha erre az ikonra kattint a felhasználó. Az ablak bezárás eseményt vezérelhetjük a setDefaultCloseOperation() metódussal. Általában azt szeretnénk, ha a bezárás eseményre az alkalmazás futtatása is fejeződjön be. Ehhez hívjuk a setDefaultCloseOperation() metódust a JFrame.EXIT_ON_CLOSE állandóval: this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Az állandó több osztályból is beállítható: * JFrame * JInternalPane * JDialog Minden osztályban négy lehetőség állítható be: * DO_NOTHING_ON_CLOSE * Nem csinál semmit ablak bezárásra kattintva. A WindowsListener segítségével más hatásokat is beállíthatsz. * HIDE_ON_CLOSE (az alapértelmezett beállítás JDialog és JFrame esetén) * Az ablak elrejtése. * DISPOSE_ON_CLOSE (az alapértelmezett JInternalFrame esetén) * Elrejti és megszünteti az ablakot. * EXIT_ON_CLOSE (A JFrame osztályban van definiálva) * Kilép az alkalmazásból, a System.exit(0) hívással. Alkalmazások esetén csak ez ajánlott. import javax.swing.JFrame; class Program extends JFrame { Program() { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setVisible(true); } public static void main(String args[]) { new Program(); } } ===== JLabel ===== ==== Felirat ==== A következő programunk ablakára egy feliratot fogunk elhelyezni, amit a JLabel osztállyal valósítunk meg. Alapértelmezett magassága: 15 import javax.swing.JFrame; import javax.swing.JLabel; class Program extends JFrame { JLabel label1; Program() { this.label1 = new JLabel("Helló Világ!"); this.add(this.label1); this.setSize(400, 300); this.setVisible(true); } public static void main(String args[]) { new Program(); } } Létrehoztunk egy felirat nevű objektumot a JLabel osztályból. Vegyük észre, hogy ezt a konstruktor előtt deklaráltuk, de az objektumnak a helyfoglalást a konstruktoron belül valósítottuk meg. Ugyanakkor a konstruktornak paraméterként megadtuk a felírat szövegét, amely persze nem kötelező. Az ablakhoz hozzáadtuk a felirat nevű objektumot: this.add(this.label1); A program elején van két import kezdetű sor. Az első a JFrame osztályt importálja: import javax.swing.JFrame; A második a JLabel osztályt: import javax.swing.JLabel {{:oktatas:programozas:java:jlabel_gui_swing.png|}} A felirat bármikor újraírható: this.label1.setText("Másik felirat"); Ha a JLabel komponens háttérszínét szeretnénk változtatni, akkor előtte szükséges a setOpaque(): this.label1.setOpaque(true); this.label1.setBackground(Color.blue); this.label1.setForeground(Color.WHITE); A Color osztály importálása import java.awt.Color; import javax.swing.SwingConstants; ... //RIGHT, LEFT, CENTER this.label1.setHorizontalAlignment(SwingConstants.CENTER); //TOP, BOTTOM, CENTER this.label1.setVerticalAlignment(SwingConstants.TOP); Szegély, font, szín: this.label1 = new JLabel("Valami"); Border border = new EmptyBorder(10, 10, 10, 10); this.label1.setBorder(border); this.label1.setFont(new Font("Sans serif", Font.BOLD, 22)); this.label1.setForeground(Color.blue); ==== Ablak automatikus méretezése ==== import javax.swing.JFrame; import javax.swing.JLabel; class Program extends JFrame { JLabel label1; Program() { this.label1 = new JLabel("Helló Világ!"); this.add(this.label1); this.pack(); this.setVisible(true); } public static void main(String args[]) { new Program(); } } Vegyük észre a pack() utasítást a konstruktorban. Ugyanakkor kivettük a setSize() metódust. A pack() metódus a komponens méretéhez igazítja az ablakméretét. ==== Komponensek elhelyezése ==== Az ablak egyes komponenseit elhelyezhetjük koordináták megadásával is. Ha így dolgozunk, be kell állítani a komponens szélességét és magasságát is. Ez megtehetjük a setBounds() metódussal. Az elrendezéskezelést azonban ki kell kapcsolni a setLayout() metódussal. import javax.swing.JFrame; import javax.swing.JLabel; class Program extends JFrame { JLabel felirat; Program() { felirat = new JLabel("Helló Világ!"); felirat.setBounds(50, 50, 100, 30); setLayout(null); add(felirat); setSize(400, 300); setVisible(true); } public static void main(String args[]) { new Program(); } } Vegyük észre a setLayout() utasítást a konstruktorban. Ugyanakkor vissza tettük a setSize() metódust. ===== Az ablak helyének megadása ===== A következő programban azt szemléltetjük, hogyan határozzuk meg az ablak helyét saját magunk. Ehhez a setLocation() metódust használhatjuk: import javax.swing.JFrame; import javax.swing.JLabel; class Program extends JFrame { JLabel felirat; Program() { felirat = new JLabel("Helló Világ!"); add(felirat); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setLocation(200, 200); setVisible(true); } public static void main(String args[]) { new Program(); } } A setLocation() metódusnak két paramétere van. A két száma az ablak helyéenk x és y koordinátája a képernyőn. ===== Ablak középre igazítása ===== Szokták ajánlani a setLocationRelativeTo() metódust, de ez az ablak bal felső sarkát teszi középre: ablak.setLocationRelativeTo(null); Ezért saját metódust írunk az ablak középre igazításához: public static void centerWindow(java.awt.Window frame) { java.awt.Dimension dimension = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2); int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2); frame.setLocation(x, y); } Komplett program: import java.awt.*; import javax.swing.*; class Program5 { JFrame ablak; JLabel cimke1; JLabel cimke2; public static void main(String args[]) { new Program5(); } Program5() { ablak = new JFrame("Címke"); cimke1 = new JLabel("Első címke"); cimke2 = new JLabel("Második címke"); cimke1.setBounds(10, 10, 100, 30); cimke2.setBounds(10, 40, 100, 30); //ablak.setBounds(10, 40, 800, 600); ablak.setSize(800, 600); centerWindow(ablak); ablak.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ablak.setLayout(null); ablak.add(cimke1); ablak.add(cimke2); ablak.setVisible(true); } public static void centerWindow(Window frame) { Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2); int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2); frame.setLocation(x, y); } } Másik módszer az ablak középre igazításához: public void setCenter(javax.swing.JFrame window) { java.awt.Point center = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint(); int x =(int) center.getX() - (this.getWidth()/2); int y =(int) center.getY() - (this.getHeight()/2); java.awt.Point windowCenter = new java.awt.Point(x, y); window.setLocation(windowCenter); } Középre igazítás teljes kód: import javax.swing.JFrame; import javax.swing.JLabel; import java.awt.FlowLayout; import java.awt.GraphicsEnvironment; import java.awt.Point; class Program extends JFrame { JLabel felirat1; JLabel felirat2; Program() { felirat1 = new JLabel("Első címke"); felirat2 = new JLabel("Második címke"); add(felirat1); add(felirat2); setLayout(new FlowLayout()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 200); setCenter(this); //Fontos, hogy a méretezés után hívjuk meg setVisible(true); } void setCenter(JFrame ablak) { Point center = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint(); int x =(int) center.getX() - (ablak.getWidth()/2); int y =(int) center.getY() - (ablak.getHeight()/2); Point ablakCenter = new Point(x, y); ablak.setLocation(ablakCenter); } public static void main(String args[]) { new Program(); } } ===== Méretezés, hely ===== A méretezés és helymeghatározásra a setBounds() metódust használhatjuk. Általánosságban a setBounds() paraméterezése: setBounds(x, y, szelesseg, magassag); Az x és y koordináta határozza meg, hogy az ablak, vagy egy komponens hova kerüljön. Az x koordináta az ablak vízszintes helyzetét határozza meg a képernyőn, annak baloldalához képest. Az y koordináta az ablak függőleges helyzetét határozza meg a képernyőn, annak tetejétől. A "szelesseg" és a "magassag" önmagáért beszél. Egy objektum helyének meghatározása: setLocation(50, 50); Egy objektum mérete: setSize(400, 300); Az objektum helye és mérete egyszerre: setBounds(50, 50, 400, 300); Az ablak átméretezésének tiltása: setResizable(false); Az ablak és a komponensek méretét el is tárolhatjuk a Dimension osztály segítségével: import java.awt.Dimension; Használata a következő módon lehetséges: Dimension meret = new Dimension(400, 300); setSize(meret); Dimension meret = new Dimension(); meret.width = 400; meret.height = 300; setSize(meret); A helyeket is eltárolhatjuk a java.awt.Point osztály segítségével: Point hely = new Point(); hely.x = 50; hely.y = 50; setLocation(hely); A hely és a méret egyszerre is eltárolható a java.awt.Rectangle osztály segítségével: Rectangle teglalap = new Rectangle(); teglalap.x = 50; teglalap.y = 50; teglalap.width = 400; teglalap.height = 300; setBounds(teglalap); setVisible(true); ===== Több komponens ===== Itt az ideje, hogy több komponenst is hozzáadjunk az ablakunkhoz. A komponens kettő darab címke. Az egyik cimke1 és a cimke2. A szokásos módon mind a kettőt létrehozzuk és helyet foglalunk számára. Ha fenti kódhoz hozzáillesztünk egy újabb címkét, azt tapasztaljuk, hogy egyik címke rálóg a másikra. Szükség van egy utasításra, amely megmondja, hogy egymás után kell azt megjeleníteni. Ehhez a java.awt.FlowLayout osztályt használhatjuk. import javax.swing.JFrame; import javax.swing.JLabel; import java.awt.FlowLayout; class Program extends JFrame { JLabel felirat1; JLabel felirat2; Program() { felirat1 = new JLabel("Első címke"); felirat2 = new JLabel("Második címke"); add(felirat1); add(felirat2); setLayout(new FlowLayout()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setLocation(200, 200); setVisible(true); } public static void main(String args[]) { new Program(); } } {{:oktatas:programozas:java:ket_label_gui_swing.png|}} A FlowLayout() konstruktorral megmondjuk, hogy a komponenseket egymás után sorba helyezzük el. Ha ezt kihagyjuk, akkor egymásra rakja a komponenseket. Ez viszont az awt csomagban van, ezért importáljuk azt: import java.awt.*; Importálhatjuk csak a FlowLayout osztályt: import java.awt.FlowLayout; ===== Abszolút pozíciónálás ===== A következő programunkban nem használunk elrendezéskezelőt (ablak.setLayout(...)). A komponensek helyét az ablakon mi magunk fogjuk meghatározni. Ehhez az elrendezéskezelő paramétereként "null" érték kerül átadásra. Így szükségtelen a java.awt.FlowLayout osztály importálása is. import javax.swing.JFrame; import javax.swing.JLabel; class Program extends JFrame { JLabel felirat1; JLabel felirat2; Program() { felirat1 = new JLabel("Első címke"); felirat2 = new JLabel("Második címke"); felirat1.setBounds(50,50, 100, 30); felirat2.setBounds(50,100, 100, 30); setLayout(null); add(felirat1); add(felirat2); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400,300); setVisible(true); } public static void main(String args[]) { new Program(); } } {{:oktatas:programozas:java:ket_label_abszolutpoz_gui_swing.png|}} Vegyük észre, hogy az ablak.setLayout() paramétere most már null: ablak.setLayout(null); A komponenseknél meghatározzuk a setBounds() metódussal a helyüket és méretüket. felirat1.setBounds(50,50, 100, 100); felirat2.setBounds(50,100, 100, 100); ===== JButton ===== Alapértelmezett magasság: 25 pont JButton button1 = new JButton("Kattints ide"); JButton button1 = new JButton("Kattints ide"); button1.setText("Más felirat"); button1.addActionListener(new Button_Click()); A java.awt.Insets osztály használható a JButton, JTextField és a JTextArea esetén is. Belső margó: nextButton.setMargin(new Insets(10, 10, 10, 10)); ==== Kép a gombon ==== button1 = new JButton(new ImageIcon("assets/kep02.png")); ===== Eseménykezelés ===== ==== Eseménykezelés Lambda kifejezéssel ==== A Lambda kifejezések a Java 8-s verziójától állnak rendelkezésre. Az eseménykezelésre egy példa: import javax.swing.JFrame; import javax.swing.JButton; class Program01 extends JFrame { JButton closeButton = new JButton("Kilépés"); public Program01() { this.closeButton.setBounds(100, 100, 100, 30); this.closeButton.addActionListener(event -> closeButtonAction()); this.add(closeButton); this.setLayout(null); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setVisible(true); } public void closeButtonAction() { System.exit(0); } public static void main(String[] args) { new Program01(); } } ==== ActionPerformed ==== Az események figyeléséhez a Java 8 előtti verziókban az egyik lehetőség az ActionListener interfész használata. Az ActionListener egy actionPerformed() nevű metódust követel meg, amiben reagálhatunk a bekövetkezett eseményekre. Az actionPerformed() metódus megkövetel egy kötelező paramétert, aminek a típusa ActionEvent. Az ActionEvent objektumból lekérdezhető, melyik komponens váltotta ki az eseményt. ==== Eseménykezelő névtelen osztállyal ==== import javax.swing.JFrame; import javax.swing.JButton; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; class Program extends JFrame { JButton kilepesgomb; Program() { kilepesgomb = new JButton("Kilépés"); kilepesgomb.setBounds(50,100, 100, 30); kilepesgomb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); setLayout(null); add(kilepesgomb); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400,300); setVisible(true); } public static void main(String args[]) { new Program(); } } A fenti példában az eseménykezelést névtelen beépített osztállyal valósítjuk meg. Ezt a megoldást is gyakran használják. ===== A WindowsAdapter ===== A WindowAdapter segítségével, az ablakbezárás eseményre, makunk írhatunk metódust. Az alább példában, csak simán kilépünk. import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class ExitListener extends WindowAdapter { public void windowClosing(WindowEvent event) { System.exit(0); } } ===== Szövegdoboz használata ===== Szövegdobozt a JTextField osztállyal hozhatunk létre. * Alapértelmezett magassága: 19 * Alapértelmezett szélessége: 5 A szöveg doboznak kezdőértéket adhatunk a konstruktorban a Text tulajdonsággal. Például: TextField1.Text = "Kezdő szöveg"; Később a doboz tartalmát a setText() metódussal állítjuk: TextField1.setText("Új szöveg"); A doboz tartalmának lekérdezése: String tartalom = TextField.getText(); A következő példában egy számot várunk, amit megduplázunk. import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.JTextField; class Program extends JFrame { JButton kilepesgomb; JButton duplazasgomb; JTextField szammezo; Program() { kilepesgomb = new JButton("Kilépés"); duplazasgomb = new JButton("Dupláz"); szammezo = new JTextField(); kilepesgomb.addActionListener(new KilepesGomb_Click()); duplazasgomb.addActionListener(new DuplazoGomb_Click()); szammezo.setColumns(7); add(kilepesgomb); add(duplazasgomb); add(szammezo); setLayout(new FlowLayout()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setVisible(true); } class KilepesGomb_Click implements ActionListener { public void actionPerformed(ActionEvent e) { System.exit(0); } } class DuplazoGomb_Click implements ActionListener { public void actionPerformed(ActionEvent e) { String szamstr = szammezo.getText(); int szam = Integer.parseInt(szamstr); int eredmeny = szam * 2; szammezo.setText(Integer.toString(eredmeny)); } } public static void main(String args[]) { new Program(); } } {{:oktatas:programozas:java:textfield_gui_swing.png|}} A JTextField alapértelmezett magassága: 19 pont. setHorizontalAlignment(JTextField.CENTER); ==== JTextField beállítások ==== textField1.setEditable(false); textField1.setHorizontalAlignment(JTextField.LEFT); * JTextField.LEFT * JTextField.CENTER * JTextField.RIGHT * JTextField.LEADING (vezetés, vagyis balra) * JTextField.TRAILING (követeés, vagyis jobbra) ===== Listadoboz ===== ==== Egyszerű listadoboz ==== Listadobozhoz két osztály szükséges: * DefaultListModel * JList Az első egy könnyen kezelhető listáról gondoskodik a másik pedig a megjelenítésről. import javax.swing.JFrame; import javax.swing.JList; import javax.swing.DefaultListModel; import javax.swing.JScrollPane; import java.awt.FlowLayout; import java.awt.Dimension; class Program01 extends JFrame { DefaultListModel listModel = new DefaultListModel(); JList jlist1 = new JList(listModel); JScrollPane scrollPane1 = new JScrollPane(jlist1); Program01() { scrollPane1.setPreferredSize(new Dimension(100, 200)); listModel.addElement("Első"); listModel.addElement("Második"); listModel.addElement("Harmadik"); listModel.addElement("Negyedik"); add(scrollPane1); setLayout(new FlowLayout()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setVisible(true); } public static void main(String args[]) { new Program01(); } } {{:oktatas:programozas:java:jlist_gui_swing.png|}} Ha kihagyjuk a ScrollPane osztályt, akkor listánk összeugrik. Elem törlése: model.remove(2); A példában a harmadik elemet töröljük. Elemek törlése: model.clear(); Adott elem cseréje: model.set(1, "gggg"); A második elem cseréje "gggg" karaktersorozatra. A kiválasztott: jlist1.getSelectedIndex() Az 50-dik elemet szeretném: String str = listModel.getElementAt(50); Egy elem átírása: void setElementAt(Object obj, int index) Van kijelölt?: isSelectionEmpty() A különbség csupán a részek a két sorban: DefaultListModel listModel = new DefaultListModel(); JList jlist1 = new JList(listModel); ==== Listadoboz másként ==== String[] lista = {"első", "második", "harmadik"}; JList listabox = new Jlist(lista); Teljes példa: import javax.swing.*; class Program extends JFrame { JList listabox; Program() { setLayout(null); String[] lista = {"első", "második", "harmadik"}; listabox = new JList(lista); listabox.setBounds(100,100, 100,100); add(listabox); setSize(800,600); setVisible(true); } public static void main(String args[]) { new Program(); } } Skrollozható kerettel: import javax.swing.*; class Program extends JFrame { JList listabox; Program() { setLayout(null); String[] lista = {"első", "második", "harmadik", "negyedik", "ötödik", "hatodik", "hetedik", "nyolcadik"}; listabox = new JList(lista); JScrollPane listaPane = new JScrollPane(listabox); listaPane.setBounds(100, 100, 100, 100); add(listaPane); setSize(800,600); setVisible(true); } public static void main(String args[]) { new Program(); } } Listamodel használata import javax.swing.*; class Program extends JFrame { JList listabox; DefaultListModel listaModel; Program() { setLayout(null); listaModel = new DefaultListModel(); listaModel.addElement("Első"); listaModel.addElement("Második"); listaModel.addElement("Harmadik"); listaModel.addElement("Negyedik"); listaModel.addElement("Ötödik"); listaModel.addElement("Hatodik"); listaModel.addElement("Hetedik"); listaModel.addElement("Nyolcadik"); listabox = new JList(listaModel); JScrollPane listaPane = new JScrollPane(listabox); listaPane.setBounds(100, 100, 100, 100); add(listaPane); setSize(800,600); setVisible(true); } public static void main(String args[]) { new Program(); } } Listamodel kezelése import javax.swing.*; import java.awt.event.*; class Program extends JFrame { JList listabox; DefaultListModel listaModel; JButton gomb; Program() { setLayout(null); listaModel = new DefaultListModel(); listaModel.addElement("Első"); listaModel.addElement("Második"); listabox = new JList(listaModel); JScrollPane listaPane = new JScrollPane(listabox); listaPane.setBounds(100, 100, 100, 100); gomb = new JButton("Hozzáad"); gomb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { listaModel.addElement("Harmadik"); } }); gomb.setBounds(20, 20, 100, 30); add(listaPane); add(gomb); setSize(800,600); setVisible(true); } public static void main(String args[]) { new Program(); } } ==== A DefaultListModel osztály metódusai ==== | void | add(int index, Object element) | Egy elem beszúrása egy adott helyre. | | void | addElement(Object obj) | A lista végéhez fűzünk egy elemet. | | int | capacity() | A lista kapacitása. | | void | clear() | A lista összes elemének törlése. | | boolean | contains(Object elem) | Az adott elem a listában van-e? | | void | copyInto(Object[] anArray) | Komponensek másolása a megadott tömbbe. | | Object | elementAt(int index) | Az elem indexével tér vissza. | | Enumeration | elements() | A lista komponenseinek felsorolt típusával (Enumeration) tér vissza. | | void | ensureCapacity(int minCapacity) | Növeljük a lista kapacitását, ha szükséges, hogy \\ tárolni tudjuk a megadott minimálist elemet. | | Object | firstElement() | A lista első elemét kapjuk vissza. | | Object | get(int index) | A lista adott pozícióban lévő elemét adja vissza. | | Object | getElementAt(int index) | Visszatér az adott indexű elemmel. | | int | getSize() | Visszaadja a komponensek számát a listában. | | int | indexOf(Object elem) | Egy elem első előfordulását keresi. | | int | indexOf(Object elem, int index) | Egy elem első előfordulását keresi, az adott indextől. | | void | insertElementAt(Object obj, int index) | Egy elem beszúrása a megadott indexhez. | | boolean | isEmpty() | Megvizsgáljuk, hogy van-e elem a listának. | | Object | lastElement() | A lista utolsó elemét adja vissza. | | int | lastIndexOf(Object elem) | Az elem utolsó előfordulásának indexét adja vissza. | | int | lastIndexOf(Object elem, int index) | Az elem utolsó előfordulásának indexét adja vissza, az adott indextől keresve. | | Object | remove(int index) | Adott elem törlése a listából, a megadott pozícióban. | | void | removeAllElements() | Az összes elem törlése, a méret lenullázása. | | boolean | removeElement(Object obj) | Törli az elemet az első előfordulásnál (legkisebb indexűt) a listából. | | void | removeElementAt(int index) | Elem törlése a megadott indexnél. | | void | removeRange(int fromIndex, int toIndex) | Elemek törlése a megadott indextartományból. | | Object | set(int index, Object element) | Adott pozícióban kicseréli egy elemet a megadott elemre. | | void | setElementAt(Object obj, int index) | Adott indexű elemet beállítja a megadott elemre. | | void | setSize(int newSize) | A lista méretének beállítása. | | int | size() | Visszaadja az elemek számát a listában. | | Object[] | toArray() | Visszatér egy tömbbel, amely tartalmazza az összes elemet, sorba rendezve. | | String | toString() | Az objektum beállításainak megjelenítése, karaktersorozatként. | | void | trimToSize() | A lista kapacitását beállítja a lista méretéhez. | Iterálás: for(Object s : dictListModel.toArray()) writer.println((String)s); Függőleges görgetés beállítása: wordScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); Ez az elem legyen látható. ScrollPane esetén is működik: wordList.ensureIndexIsVisible(index); Ha meret egy modellből jön, akkor 1-et ki kell vonni a mérteből: int meret = listaModell.getSize(); lista.ensureIndexIsVisible(meret-1); Kiválasztás figyelése. Egy esemény bekövetkezik az egér lenyomásakor és a felengedéskor is. A getValueIsAdjusting() metódussal kiválasztható az első, vagy a második esemény: topicsList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if(e.getValueIsAdjusting()) { //Amit az egérlenyomásakor csinálunk } else { //Amit az egér felengedésekor csinálunk } } }); ===== ComboBox ===== import javax.swing.*; class Program extends JFrame { JComboBox combo; Program() { combo = new JComboBox(); combo.setSize(100, 30); combo.addItem("Első"); combo.addItem("Második"); combo.addItem("Harmadik"); combo.addItem("Negyedik"); combo.addItem("Ötödik"); add(combo); setLayout(null); setSize(200, 100); setVisible(true); } public static void main(String args[]) { new Program(); } } {{:oktatas:programozas:java:javaswing_combobox.png|}} A ComboBox alapértelmezett magassága 24 pont. combo.removeAllItem(); Ha kiválasztott változott: import java.awt.event.ItemEvent; import java.awt.event.ItemListener; ... comboBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { } }); Ha kiválasztunk egy elemet, akkor az esemény kétszer váltódik ki. Az e.getStateChange() először 2, majd 1-et ad vissza. Ez alapján szétválaszthatjuk a két eseményt: groupComboBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { if(e.getStateChange()==2) ; //Csinálunk valamit } }); int a = lld.getItemCount(); int b = lld.getSelectedIndex(); Adott elem lekérése: if(lld.getItemCount()>0) String str = (String) lld.getSelectedItem(); A getSelectedItem() metódus Object típust ad vissza. ===== Model használata ===== import javax.swing.*; class Program extends JFrame { DefaultComboBoxModel comboModel; JComboBox combo; Program() { comboModel = new JComboBox(); combo = new JComboBox(comboModel); combo.setSize(100, 30); comboModel.addElement("Első"); comboModel.addElement("Második"); comboModel.addElement("Harmadik"); comboModel.addElement("Negyedik"); comboModel.addElement("Ötödik"); add(combo); setLayout(null); setSize(200, 100); setVisible(true); } public static void main(String args[]) { new Program(); } } ==== ComboBox feltöltés ==== Adott egy lista, benne beosztások: Rank[] rankArray = { new Rank(1, "takarító"), new Rank(2, "gondnok"), new Rank(3, "villanyszerelő"), }; Vector rankList = new Vector<>(Arrays.asList(rankArray)); Feltöltés: rankList.forEach(rank -> { comboModel.addElement(rank.name); }); A feltöltés egy másik módja: for(Rank rank : rankList) { comboModel.addElement(rank.name); } Teljeskód: public class Rank { int id; String name; public Rank(int id, String name) { this.id = id; this.name = name; } } import java.awt.Dimension; import java.awt.FlowLayout; import java.util.Arrays; import java.util.Vector; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JFrame; public class MainFrame extends JFrame { DefaultComboBoxModel comboModel; JComboBox combo; Rank[] rankArray = { new Rank(1, "takarító"), new Rank(2, "gondnok"), new Rank(3, "villanyszerelő"), }; Vector rankList = new Vector<>(Arrays.asList(rankArray)); public MainFrame() { setComponent(); setMainFrame(); } private void setComponent() { comboModel = new DefaultComboBoxModel<>(); combo = new JComboBox<>(comboModel); combo.setPreferredSize(new Dimension(100, 32)); rankList.forEach(rank -> { comboModel.addElement(rank.name); }); } private void setMainFrame() { this.add(combo); this.setLayout(new FlowLayout()); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setVisible(true); } } public class App { public static void main(String[] args) throws Exception { new MainFrame(); } } ==== Állapot változás eseménye ==== combo.addItemListener(e -> changedStateRankCombo(e)); A program indulásakor bekövetkezik az új elem kiválasztása. Ezt követően mindig két esemény következik be. * előző elem nincs kiválasztva * új elem kiválasztva private void changedStateRankCombo(ItemEvent event) { if (event.getStateChange() == ItemEvent.DESELECTED) System.out.println("előző nincs kiválasztva"); if (event.getStateChange() == ItemEvent.SELECTED) System.out.println("új kiválasztva"); } Kiválasztott: private void changedStateRankCombo(ItemEvent event) { if (event.getStateChange() == ItemEvent.SELECTED) { Object item = event.getItem(); System.out.println(item); } } ==== Akcióesemény ==== Használhatjuk az ActionListener-t is, de egyszerre csak egyet használjunk. combo.addActionListener(event -> actionRankCombo(event)); private void actionRankCombo(ActionEvent event) { System.out.println("új kiválasztva"); } ===== Párbeszédpanel ===== A JOptionPane osztály használatához importálni kell azt a javax.swing csomagból: import javax.swing.JOptionPane; Gyors kezdéshez: javax.swing.JOptionPane.showMessageDialog(getContentPane(), ""); {{:oktatas:programozas:java:joptionpane_gui_swing.png|}} ==== Üzenetablakok ==== Egy egyszerű párbeszédablak: JOptionPane.showMessageDialog(null, edit.getText()); Az első paraméter vagy null vagy a szülőablak. Ha null értéket írtunk be, a felugró párbeszédablak a programablaktól függetlenül a képernyő közepén jelenik meg. JOptionPane.showMessageDialog(ablak, edit.getText()); Ha megadjuk a szülőablakot, akkor a párbeszédpanel a programablakhoz igazodik. A párbeszédpanel 5 féle lehet. Az alapértelmezett az "information" * kérdő * információs * figyelmeztető * hiba * csak szöveg JOptionPane.showMessageDialog(szulo , "Üzenet", "Névjegy", JOptionPane.INFORMATION_MESSAGE ); Lehet egy ötödik paraméter is az ikon, ekkor információs párbeszédablaknak hozzuk létre. JOptionPane.showMessageDialog(szulo , "Üzenet", "Névjegy", JOptionPane.INFORMATION_MESSAGE, ikon ); ==== Információt kérő párbeszédablakok ==== int res = JOptionPane.showConfirmDialog(null, "Figyelem! Biztosan ezt akarod?", "Figyelmeztetés", JOptionPane.YES_NO_OPTION); if (res == JOptionPane.YES_OPTION) System.out.println("Igen"); else System.out.println("Nem"); ==== Nyomógomb saját szöveggel ==== Object[] options = {"Igen, kérem", "Nem, köszönöm. "}; int n = JOptionPane.showOptionDialog(ablak, "Kéred ezt a lehetőséget?", "Általános kérdés", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, //nem használunk külön ikont options, //A gombok feliratai options[0]); //Az alapértelmezett gomb felirata ==== Forrás ==== * http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html * http://docs.oracle.com/javase/6/docs/api/javax/swing/JOptionPane.html ===== Párbeszédablak átadott értékkel ===== Saját párbeszédablak készítése, átadott értékkel. import javax.swing.JFrame; import javax.swing.JDialog; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JTextField; import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; class Program extends JFrame { JButton gomb = new JButton("Bekér"); JTextField mezo = new JTextField(10); Program() { gomb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Parbeszed p = new Parbeszed(); mezo.setText(p.showDialog()); } }); setLayout(new FlowLayout()); add(gomb); add(mezo); pack(); setVisible(true); } public static void main(String args[]) { new Program(); } } class Parbeszed extends JDialog { String nev; JTextField mezo = new JTextField(5); Parbeszed() { JButton gomb = new JButton("Ok"); gomb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { nev = mezo.getText(); setVisible(false); } }); add(new JLabel("Név: ")); add(mezo); add(gomb); setLayout(new FlowLayout()); pack(); } public String showDialog() { setModal(true); setVisible(true); return nev; } } Főablak: {{:oktatas:programozas:java:parbeszedablak_main_gui_swing.png|}} Párbeszédablak: {{:oktatas:programozas:java:parbeszedablak_dialog_gui_swing.png|}} ===== JDilaog szülőablakon belül középre igazítva ===== import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import java.awt.Dimension; class OperationFrame extends JDialog { JButton button; public OperationFrame(JFrame parent) { super(parent); this.button = new JButton("Bezár"); this.add(this.button); this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); this.setSize(300, 200); // Középre igazítjuk a dialógusablakot a szülőablak közepén Dimension dim = parent.getSize(); int w = this.getSize().width; int h = this.getSize().height; int x = parent.getLocation().x + (dim.width - w) / 2; int y = parent.getLocation().y + (dim.height - h) / 2; this.setLocation(x, y); } } class MainFrame extends JFrame { JButton button; public MainFrame() { this.button = new JButton("Mehet"); this.button.addActionListener(e -> { this.startDialog(); }); this.add(this.button); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setVisible(true); } private void startDialog() { OperationFrame operationFrame = new OperationFrame(this); operationFrame.setVisible(true); } } class App { public static void main(String[] args) { new MainFrame(); } } ===== Ikon ===== import javax.swing.*; class Program extends JFrame { Program() { setIconImage(new ImageIcon("ikon.png").getImage()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 200); setVisible(true); } public static void main(String args[]) { new Program(); } } {{:oktatas:programozas:java:ikon_gui_swing.png|}} Készíthetünk külön ikon változót, amit esetleg másra is használhatunk. ImageIcon ikon = new ImageIcon("ikon.png"); ablak.setIconImage(ikon.getImage()); A megvalósításhoz egy rögtönzött ikon: * https://szit.hu/download/oktatas/java/ikon.png ==== Ikon a gombhoz ==== import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.ImageIcon; class Program extends JFrame { JButton gomb = new JButton("Klikkelj ide"); Program() { setIconImage(new ImageIcon("ikon.png").getImage()); gomb.setIcon(new ImageIcon("ikon.png")); add(gomb); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setVisible(true); } public static void main(String[] args) { new Program(); } } Méretezés: Image kep = new ImageIcon("ikon.png").getImage() .getScaledInstance(24, 24, java.awt.Image.SCALE_SMOOTH); A program ikon csak kis méretben jelenik meg. A nyomógombhoz rendelt ikon viszont az eredeti méreteben. A megjegyzésbe tett részt ha használjuk átméretezhetjük az eredeti képméretet. Ha az ikonfájlt beletesszük a jar fájlba, akkor erőforrásként kell olvasni: java.net.URL imageURL = Program.class.getResource("images/ProgramIcon_32x32.png"); setIconImage(new ImageIcon(imageURL).getImage()); Az első és második sor lehet így is: java.net.URL imageURL = getClass().getResource("images/ProgramIcon_32x32.png"); ===== Keret stílus ===== //a keretdekoráció look and feel stílusú JFrame.setDefaultLookAndFeelDecorated(true); //a keret elkészítése JFrame frame = new JFrame("A window"); //keretikon beállítása fájlból frame.setIconImage(new ImageIcon(imgURL).getImage()); ===== Komponens szegély ===== ==== A szegélyekről ==== Minden JComponentnek lehet egy vagy több szegélye. A border, azaz a szegély, megmondja, hogy nézzen ki egy Swing komponens széle, és körbefogja azt. A JComponent-ek számára szegélyt a setBorder() metódussal határozhatunk meg. Többféle szegély használható: * EmptyBorder * LinesBorder * stb. Ezek létrehozhatók az adott osztállyal vagy a BorderFactory kreátorral. A következőkben néhány példát látunk: this.panel1.setBorder(BorderFactory.createLineBorder(Color.BLUE)); this.panel2.setBorder(BorderFactory.createRaisedBevelBorder()); this.panel3.setBorder(BorderFactory.createLoweredBevelBorder()); this.panel4.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED)); this.panel5.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); this.panel6.setBorder(BorderFactory.createEmptyBorder()); {{:oktatas:programozas:java:border01.png|}} ==== Egyszerű szegély ==== Egy konkrét megvalósítás import javax.swing.*; import java.awt.*; import javax.swing.border.*; class Program { public static void main(String args[]) { JFrame ablak = new JFrame("Szegély példa"); JLabel cimke = new JLabel("Felirat"); Border a = BorderFactory.createLineBorder(Color.black); ablak.setLayout(null); cimke.setBorder(a); cimke.setBounds(10, 10, 80, 20); ablak.add(cimke); ablak.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ablak.setSize(400,300); ablak.setVisible(true); } } {{:oktatas:programozas:java:javaswing_border.png|}} ==== Szegély cím beállítása ==== import javax.swing.*; import java.awt.*; import javax.swing.border.*; class Program { public static void main(String args[]) { JFrame ablak = new JFrame("Szegély példa"); JLabel cimke = new JLabel("Felirat"); Border a = BorderFactory.createLineBorder(Color.black); a = BorderFactory.createTitledBorder( a, "cím", TitledBorder.LEFT, //CENTER TitledBorder.TOP); //BELOW_BOTTOM, ABOVE_TOP, TOP ablak.setLayout(null); cimke.setBorder(a); cimke.setBounds(10, 10, 120, 80); ablak.add(cimke); ablak.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ablak.setSize(400,300); ablak.setVisible(true); } } {{:oktatas:programozas:java:javaswing_titledborder.png|}} Létrehozható szegélyfajták * javax.swing.border.LineBorder * javax.swing.border.EtchedBorder * javax.swing.border.BevelBorder * javax.swing.border.EmptyBorder * javax.swing.border.MatteBorder * javax.swing.border.TitledBorder * javax.swing.border.CompoundBorder * javax.swing.BorderFactory Példák: jlist1.setBorder(new EtchedBorder() ); scrollpane1.setBorder(new TitledBorder("Tartalom címe")); Méretezett üres szegélyen belül, szegély és felirat kombinációja: panel1.setBorder( BorderFactory.createCompoundBorder( new EmptyBorder(10, 10, 10, 10), new TitledBorder("Behelyettesítés") ) ); Üres méretezett szegély és felirat: panel1.setBorder(new TitledBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10), "Gyakoriságelemzés")); Üres szegély méretmegadással: panel1.setBorder(BorderFactory.createEmptyBorder(0,10,10,10)); Utóbbit lehet így is: panel1.setBorder(new EmptyBorder(10, 10, 10, 10) ); ===== Szegélyek ===== ==== LineBorder ==== import java.awt.Color; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.LineBorder; public class MainWindow extends JFrame { JPanel panel1; public MainWindow() { this.panel1 = new JPanel(); this.panel1.setBounds(5, 5, 200, 100); this.panel1.setBorder(new LineBorder(Color.BLUE)); this.setLayout(null); this.add(this.panel1); this.setTitle("App"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(215, 135); this.setVisible(true); } } ==== BevelBorder ==== Border bevelBorder = BorderFactory.createBevelBorder(BevelBorder.RAISED); Több info: http://docs.oracle.com/javase/tutorial/uiswing/components/border.html ===== Rádiógombok ===== import javax.swing.JButton; import javax.swing.JFrame; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.ButtonGroup; import javax.swing.JRadioButton; class radiogomb extends JFrame { JButton GombElso; ButtonGroup csoport; JRadioButton radiogomb1; JRadioButton radiogomb2; JRadioButton radiogomb3; JRadioButton radiogomb4; radiogomb() { this.setSize(800, 600); GombElso = new JButton(); radiogomb1 = new JRadioButton(); radiogomb2 = new JRadioButton(); radiogomb3 = new JRadioButton(); radiogomb4 = new JRadioButton(); csoport = new ButtonGroup(); this.setVisible(true); this.setLayout(null); GombElso.setText("Valami"); radiogomb1.setText("Valami"); radiogomb2.setText("Valami2"); radiogomb3.setText("Valami3"); radiogomb4.setText("Valami4"); radiogomb1.setSelected(false); radiogomb2.setSelected(true); radiogomb3.setSelected(false); radiogomb4.setSelected(false); GombElso.setBounds(10,10, 100, 30); radiogomb1.setBounds(120,10,100,20); radiogomb2.setBounds(120,30,100,20); radiogomb3.setBounds(120,50,100,20); radiogomb4.setBounds(120,70,100,20); csoport.add(radiogomb1); csoport.add(radiogomb2); csoport.add(radiogomb3); csoport.add(radiogomb4); this.add(GombElso); this.add(radiogomb1); this.add(radiogomb2); this.add(radiogomb3); this.add(radiogomb4); GombElso.addActionListener(new ButtonListener1()); } public static void main(String args[]) { new radiogomb(); } class ButtonListener1 implements ActionListener { public void actionPerformed(ActionEvent e) { if(radiogomb1.isSelected()) GombElso.setText("Első"); if(radiogomb2.isSelected()) GombElso.setText("Második"); if(radiogomb3.isSelected()) GombElso.setText("Harmadik"); if(radiogomb3.isSelected()) GombElso.setText("Negyedik"); } } } ButtonGroup * http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/ButtonGroup.html {{:oktatas:programozas:java:javaswing_radiobuttons.png|}} ==== Egyszerű rádiógomb ==== import javax.swing.*; import java.awt.*; class Program extends JFrame { ButtonGroup group; JRadioButton radio1; JRadioButton radio2; JPanel panel; Program() { group = new ButtonGroup(); radio1 = new JRadioButton("Első"); radio2 = new JRadioButton("Második"); panel = new JPanel(); group.add(radio1); group.add(radio2); panel.add(radio1); panel.add(radio2); add(panel); panel.setBorder(BorderFactory.createTitledBorder("Valami")); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 200); setVisible(true); } public static void main(String args[]) { new Program(); } } A rádiógombokat, hozzá kell adni a ButtonGroup objektumhoz is, de ez csak csoportosításra szolgál! A megjelenés érdekében a JPanel objektumhoz is hozzá kell adni. Persze a csoportosításnak csak akkor van értelme, ha több csoportunk is van. {{:oktatas:programozas:java:javaswing_simpleradiobutton.png|}} ==== Csoportok ==== import javax.swing.*; import java.awt.*; class Program extends JFrame { ButtonGroup group1; ButtonGroup group2; JRadioButton[] radio1; JRadioButton[] radio2; JPanel panel1; JPanel panel2; Program() { group1 = new ButtonGroup(); group2 = new ButtonGroup(); String[] s1 = {"Első", "Második", "Harmadik", "Negyedik", "Ötödik", "Hatodik"}; String[] s2 = {"1", "2", "3", "4", "5", "6"}; radio1 = new JRadioButton[6]; radio2 = new JRadioButton[6]; panel1 = new JPanel(); panel2 = new JPanel(); for(int i=0; i<6;i++) { radio1[i] = new JRadioButton(s1[i]); group1.add(radio1[i]); panel1.add(radio1[i]); radio2[i] = new JRadioButton(s2[i]); group2.add(radio2[i]); panel2.add(radio2[i]); } panel1.setLayout(new GridLayout(3, 2)); panel2.setLayout(new GridLayout(3, 2)); add(panel1); add(panel2); panel1.setBorder(BorderFactory.createTitledBorder("Színek")); panel2.setBorder(BorderFactory.createTitledBorder("Vastagság")); setLayout(new FlowLayout()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 200); setVisible(true); } public static void main(String args[]) { new Program(); } } Az utóbbi példában már tömbként hozzuk létre a rádiógombokat. {{:oktatas:programozas:java:javaswing_group.png|}} ==== Rádiógomb panel osztállyal ==== Hosszútávon jobban járunk, ha a panelt külön osztályba rakjuk: import javax.swing.*; import java.awt.*; class SajatPanel extends JPanel { ButtonGroup group; JRadioButton[] radio; SajatPanel(String[] felirat) { group = new ButtonGroup(); radio = new JRadioButton[6]; for(int i=0; i<6;i++) { radio[i] = new JRadioButton(felirat[i]); group.add(radio[i]); add(radio[i]); } } } class Program extends JFrame { SajatPanel panel1; SajatPanel panel2; Program() { String[] s1 = {"Első", "Második", "Harmadik", "Negyedik", "Ötödik", "Hatodik"}; String[] s2 = {"1", "2", "3", "4", "5", "6"}; panel1 = new SajatPanel(s1); panel2 = new SajatPanel(s2); panel1.setLayout(new GridLayout(3, 2)); panel2.setLayout(new GridLayout(3, 2)); add(panel1); add(panel2); panel1.setBorder(BorderFactory.createTitledBorder("Színek")); panel2.setBorder(BorderFactory.createTitledBorder("Vastagság")); setLayout(new FlowLayout()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 200); setVisible(true); } public static void main(String args[]) { new Program(); } } {{:oktatas:programozas:java:javaswing_radiobutton.png|}} ===== Jelölőnégyzetek ===== import javax.swing.JCheckBox; //... JCheckBox check1 = new JCheckBox(); Teljes kód: import javax.swing.JCheckBox; import javax.swing.JFrame; class MainWindow extends JFrame { JCheckBox check1 = new JCheckBox(); public MainWindow() { this.check1.setText("alma"); this.add(check1); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(300, 200); this.setVisible(true); } public static void main(String[] args){ new MainWindow(); } } {{:oktatas:programozas:java:jcheckbox_gui_swing.png|}} ==== Lekérdezés ==== this.check1.isSelected() import java.awt.FlowLayout; import java.awt.event.ActionEvent; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; public class MainWindow extends JFrame { JCheckBox check1 = new JCheckBox(); JButton button1 = new JButton("Mehet"); public MainWindow() { this.check1.setText("alma"); this.button1.addActionListener((e)->{ button1_on_click(e); }); this.add(check1); this.add(button1); this.setLayout(new FlowLayout()); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(300, 200); this.setVisible(true); } private void button1_on_click(ActionEvent e) { if(this.check1.isSelected()) { System.out.println("kiválasztva"); } } } {{:oktatas:programozas:java:jcheckbox_ellenorzes_gui_swing.png|}} ==== Beállítás ==== check1.setSelected(true); ==== Változás ==== this.check1.addItemListener((e)->{ System.out.println("változott"); }); Teljes kód: import java.awt.FlowLayout; import java.awt.event.ItemEvent; import javax.swing.JCheckBox; import javax.swing.JFrame; public class MainWindow extends JFrame { JCheckBox check1 = new JCheckBox(); public MainWindow() { this.check1.setText("alma"); this.check1.addItemListener((e)->{ check1_on_itemchanged(e); }); this.add(check1); this.setLayout(new FlowLayout()); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(300, 200); this.setVisible(true); } private void check1_on_itemchanged(ItemEvent e) { System.out.println("változott"); } } ===== Táblázat ===== ==== Bevezetés a táblázatkészítésbe ==== Egy táblázat adatainak megjelenítéséhez a **JTable** osztály használhatjuk. A táblázatot egy **JScrollPane** nevű konténerosztályra szoktuk feltenni. Ha szeretnénk a sorok és oszlopok számát futási időben változtatnunk, akkor szükségünk lesz még a **DefaultTableModel** osztályra. Itt fontos megjegyezni, hogy egy táblázat fejléce csak JScrollPane-ra helyezve jelenik meg. ==== Egyszerű tábla ==== Az első megoldásban nem használunk DefaultTableModel és JScrollPane osztályt, csak szimpla tömböket adunk át a JTable konstruktorának. import javax.swing.*; class Program extends JFrame { JTable tabla; Program() { // A táblázat fejrésze: String[] mezoNevek = {"id", "Név", "Település", "Kor"}; // A táblázat tartalmi része: Object[][] adat = { {1, "Nagy Peter", "Szolnok", 67}, {2, "Nagy Lajos", "Szolnok", 27} }; tabla = new JTable(adat, mezoNevek); tabla.setBounds(100, 100, 300, 200); setLayout(null); add(tabla); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setVisible(true); } public static void main(String[] argv) { new Program(); } } A fejrész nem jelenik meg, mivel a JScrollPane sem használtuk. {{:oktatas:programozas:java:javaswing_simpletable.png|}} ==== Tábla fejléccel ==== A táblát egy konténerhez adjuk. Esetünkben a JScrollPane osztály egy objektumához. import javax.swing.*; class Program extends JFrame { JTable tabla; JScrollPane spanel; Program() { String[] mezoNevek = {"id", "Nev", "Telepules", "Kor"}; Object[][] adat = { {1, "Nagy Peter", "Szolnok", 67}, {2, "Nagy Lajos", "Szolnok", 27} }; tabla = new JTable(adat, mezoNevek); spanel = new JScrollPane(tabla); spanel.setBounds(50, 50, 400, 300); add(spanel); setLayout(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setVisible(true); } public static void main(String[] argv) { new Program(); } } Fordítsuk és futtassuk a programot, látható, hogy a táblázat fejrésze is megjelenik. {{:oktatas:programozas:java:javaswing_headtable.png|}} A következő példában mindhárom osztályt használjuk. Az adattartalom már külön, egy model nevű objektumban lesz. A táblához a **setModel()** metódussal adjuk. import javax.swing.JFrame; import javax.swing.JTable; import javax.swing.JScrollPane; import javax.swing.table.DefaultTableModel; class Program extends JFrame { DefaultTableModel model = new DefaultTableModel(); JTable table = new JTable(); JScrollPane spanel = new JScrollPane(table); public Program() { Object[] felirat = {"Név", "Település"}; model.setColumnIdentifiers(felirat); model.addRow(new Object[] {"Nagy János", "Szolnok"}); table.setModel(model); spanel.setBounds(20, 20, 300, 200); this.add(spanel); this.setLayout(null); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setVisible(true); } public static void main(String[] args) { Program prg01 = new Program(); } } {{:oktatas:programozas:java:javaswing_modeltable.png|}} ==== Oszlop, sor méretezés ==== Oszlop szélessége: tabla.getColumnModel().getColumn(0).setPreferredWidth(10); tabla.getColumnModel().getColumn(1).setPreferredWidth(200); A példában az első és második sor szélességét állítjuk be. Az oszlop szélessége a megadott számhoz egy közelítő érték lesz. Sorok magassága: tabla.setRowHeight(1, 80); A példában a második sor magasságát állítjuk be. ==== Szelektálás ==== Háttérszín: tabla.setSelectionBackground(Color.red); Kijelöltek indexének kinyerése: int sor = tabla.getSelectedRow(); int osz = tabla.getSelectedColumn(); Szelekciós mód: // ListSelectionModel.SINGLE_INTERVAL_SELECTION // ListSelectionModel.SINGLE_SELECTION // ListSelectionModel.MULTIPLE_INTERVAL_SELECTION tabla.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); tabla.setColumnSelectionAllowed(true); tabla.setRowSelectionAllowed(false); tabla.setCellSelectionEnabled(true); ==== Igazítás ==== DefaultTableCellRenderer rightRenderer = new DefaultTableCellRenderer(); // JLabel.RIGHT, JLabel.CENTER, JLabel.LEFT (alapértelmezés) // DefaultTableCellRenderer.RIGHT, .CENTER, .RIGHT rightRenderer.setHorizontalAlignment(DefaultTableCellRenderer.CENTER); tabla.getColumnModel().getColumn(0).setCellRenderer(rightRenderer); ==== Táblázat változásának figyelése ==== import javax.swing.event.*; ... tabla.getModel().addTableModelListener(new TableModelListener() { public void tableChanged(TableModelEvent ev) { System.out.println("változott egy cella"); } }); ==== Fejléc csere ==== A táblázat fejlécét a modellben tároljuk és ott változtatjuk. A feladatra két metódus áll rendelkezésre. Lehet így: void setColumnIdentifiers(Object[] newIdentifiers) Lehet így: void setColumnIdentifiers(Vector columnIdentifiers) Konkrét megvalósítás: Object[] obj ={"Az", "Név", "Anyja neve", "Település", "Lakcím", "Fizetés", "Születés", "Jutalom", "Beosztás Az"}; tableModel.setColumnIdentifiers(obj); ==== Tartalom cseréje ==== //Tábla tartalmának beállítása Első sor, második mező tabla.getModel().setValueAt("Feher Bela", 0, 1); A tabla.getModel() metódus egy [[http://docs.oracle.com/javase/6/docs/api/javax/swing/table/TableModel.html|TableModel]] típusú objektumot ad vissza. | void | addTableModelListener(TableModelListener l) | Egy eseményfigyelő hozzáadása | | int | getColumnCount() | A mezők számát adja vissza | | String | getColumnName(int mezoIndex) | Adott indexű mező nevét adja vissza | | int | getRowCount() | A sorok számát adja vissza | | Object | getValueAt(int sorIndex, int mezoIndex) | Egy cell értékét adja | | boolean | isCellEditable(int sorIndex, int mezoIndex) | Szerkeszthető-e? | | void | removeTableModelListener(TableModelListener l) | Az változások figyelésének kikapcsolása | | void | setValueAt(Object ertek, int sorIndex, int mezoIndex) | Egy cella értékének beállítása | ==== Oszlopok, sorok beszúrása ==== A feladathoz használnunk kell a DefaultTableModel osztályt. Ezzel létrehozzuk egy model objektumot, amelyet a JTable konstruktorban átadunk. import javax.swing.*; import javax.swing.table.*; class Program extends JFrame { JTable tabla; JScrollPane spanel; Program() { String[] mezoNevek = {"id", "Nev", "Telepules", "Kor"}; Object[][] adat = { {1, "Nagy Peter", "Szolnok", 67}, {2, "Nagy Lajos", "Szolnok", 27} }; DefaultTableModel model = new DefaultTableModel(adat, mezoNevek); tabla = new JTable(model); spanel = new JScrollPane(tabla); spanel.setBounds(50, 50, 400, 300); //Mező hozzáadása model.addColumn("Fizetes"); //Beszúrás az utolsó helyre model.insertRow(tabla.getRowCount(),new Object[] {"","","","",""}); //Hozzáfűzés az utolsó helyre model.addRow(new Object[]{3, "Akad Tibor", "Miskolc", 37}); add(spanel); setLayout(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setVisible(true); } public static void main(String[] argv) { new Program(); } } További metódusok használhatók a DefaultTableModel osztályból. ==== Cella színezése ==== import javax.swing.JFrame; import javax.swing.JTable; import javax.swing.JLabel; import java.awt.Component; import java.awt.Color; import javax.swing.table.TableCellRenderer; class Program extends JFrame { private JTable tabla; public Program() { setLayout(null); tabla = new JTable(9, 9); tabla.setBounds(20, 20, 300, 200); int columnWidht = 20; int rowHeight = 25; for(int i=0; i<9; i++) tabla.getColumnModel().getColumn(i).setPreferredWidth(columnWidht); for(int i=0; i<9; i++) tabla.setRowHeight(i, rowHeight); tabla.setDefaultRenderer(Object.class, new MyTableCellRenderer()); tabla.getModel().setValueAt(Color.red, 3, 3); tabla.getModel().setValueAt(Color.red, 3, 5); add(tabla); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public static void main(String args[]) { new Program(); } class MyTableCellRenderer extends JLabel implements TableCellRenderer { MyTableCellRenderer() { setOpaque(true); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { setBackground((Color) value); return this; } } } {{:oktatas:programozas:java:javaswing_cellcolor.png|}} Néhány metódus: setShowGrid(boolean bol) setGridColor(Color col): setShowVerticalLines(): ==== Rajzolás a táblázaton ==== Ha rajzolni szeretnék egy táblázatra, akkor helyfoglalást (példányosítás) a következő módon adjuk meg. JTable tabla = new JTable(9, 9) { protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor (Color.black); g.drawString("1", 2, 12); } }; ==== Táblázat fontméret ==== tabla.setFont(new Font("Serif", Font.BOLD, 12)); ==== Táblázat színezés ==== Egész tábla háttérszíne: tabla.setBackground(Color.blue); Szöveg színe: tabla.setForeground(Color.yellow); Rács színe: tabla.setGridColor(Color.black); Szegély színe: tabla.setBorder(new MatteBorder(1, 1, 1, 1, Color.RED)); ==== Az egész táblázat fontja ==== tabla.setFont(new Font("Serif", Font.BOLD, 16)); A táblázatra rajzoláskor is ezt használjuk, hacsak nem adunk meg rajzolásnál mást. ==== TableModel használata ==== TableModel tableModel = new AbstractTableModel(){ @Override public Object getValueAt(int row, int col) { return new Integer(row*col); }; @Override public int getColumnCount(){return 10;}; @Override public int getRowCount(){return 10;}; }; JTable table = new JTable(tableModel); JScrollPane jsp = new JScrollPane(table); ==== Fejléc rejtése ==== table.getTableHeader().setVisible(false); Ha nem vizuális szerkesztőt használunk ez is működik: table.setTableHeader(null); ==== Cellák igazítása ==== class CenterTableCellRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int col) { Component cell = super.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, col); setHorizontalAlignment(SwingConstants.CENTER); return cell; } } A táblázatra ekkor így állítom be: table.setDefaultRenderer(Object.class, new CenterTableCellRenderer()); Vagy megoldom az egészet három sorból: DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer(); centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); table.setDefaultRenderer(Object.class, centerRenderer); ==== ArrayList DefaultTableModelbe ==== public void feltolt() { //Valahonnan megjönnek a dolgozók ArrayList employeeList = mainModel.getEmployeeList(); for(Employee emp : employeeList) { Vector row = new Vector<>(); row.add(emp.id); row.add(emp.name); row.add(emp.city); row.add(emp.salary); this.mainwindow.model.addRow(row); } } Az ArrayList átalakítható másként is: for (Employee emp : employeeList) { Object[] obj = {emp.id, emp.name, emp.city, emp.salary}; model.addRow(obj); } ==== Komplett program ==== public class App { public static void main(String[] args) { new MainFrame(); } } public class Employee { Integer id; String name; String city; Double salary; public Employee(Integer id, String name, String city, Double salary) { this.id = id; this.name = name; this.city = city; this.salary = salary; } } import java.awt.BorderLayout; import java.util.ArrayList; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; public class MainFrame extends JFrame{ DefaultTableModel model = new DefaultTableModel(); JTable table = new JTable(); JScrollPane pane = new JScrollPane(); public MainFrame() { ArrayList employeeList = new ArrayList<>(); employeeList.add(new Employee(1, "Erős István", "Szeged", 395.0)); employeeList.add(new Employee(2, "Csontos Ferenc", "Szolnok", 392.3)); Object[] cols = {"#", "Név", "Település", "Fizetés"}; this.model.setColumnIdentifiers(cols); for (Employee emp : employeeList) { Vector row = new Vector<>(); row.add(emp.id); row.add(emp.name); row.add(emp.city); row.add(emp.salary); model.addRow(row); } this.table.setModel(model); this.pane.setViewportView(table); this.table.getColumnModel().getColumn(0).setPreferredWidth(5); this.setLayout(new BorderLayout()); this.add(pane, BorderLayout.CENTER); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setVisible(true); } } ==== Irodalom a táblázathoz ==== Linkek: * http://www.java2s.com/Tutorial/Java/0240__Swing/CreatingaJTable.htm (2022) * http://www.java2s.com/Code/Java/Swing-Components/SortableTableExample.htm (2022) * http://docs.oracle.com/javase/tutorial/uiswing/components/table.html * http://docs.oracle.com/javase/6/docs/api/javax/swing/JTable.html ===== Ablakméret lekérdezése ===== import java.awt.Dimension; import javax.swing.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; class prog extends JFrame { JButton gomb; JLabel cimke; prog() { setLayout(null); gomb = new JButton("Méret"); cimke = new JLabel("Adatok"); gomb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Dimension ablakMeret = getSize(); int ablakMagassag = ablakMeret.height; int ablakSzelesseg = ablakMeret.width; cimke.setText(Integer.toString(ablakMagassag) + "x" + Integer.toString(ablakSzelesseg)); } }); gomb.setBounds(20, 20, 100, 30); cimke.setBounds(100,100, 100,30); add(gomb); add(cimke); setSize(800,600); setVisible(true); } public static void main(String args[]) { new prog(); } } ===== Java GUI Füles panel ===== Füles ablakok elkészítésére a TabbedPane osztályt használjuk. Az alábbiakban ennek használatára látunk egy példát. ==== Fülespanel 001 ==== import javax.swing.*; import java.awt.BorderLayout; class Program extends JFrame { private JTabbedPane fulespanelek; private JPanel panel1; private JPanel panel2; private JPanel panel3; Program() { setTitle("Fülespanelek"); setSize(400,300); setLayout( new BorderLayout() ); panel1Keszites(); panel2Keszites(); panel3Keszites(); fulespanelek = new JTabbedPane(); fulespanelek.addTab("Első", panel1); fulespanelek.addTab("Második", panel2); fulespanelek.addTab("Harmadik", panel3); add(fulespanelek); } void panel1Keszites() { panel1 = new JPanel(); panel1.setLayout( null ); JLabel cimke1 = new JLabel( "Első panel felirata" ); cimke1.setBounds( 10, 15, 150, 20 ); panel1.add( cimke1 ); } void panel2Keszites() { panel2 = new JPanel(); panel2.setLayout( null ); JLabel cimke1 = new JLabel( "Második panel felirata" ); cimke1.setBounds( 10, 15, 150, 20 ); panel2.add( cimke1 ); } void panel3Keszites() { panel3 = new JPanel(); panel3.setLayout( null ); JLabel cimke1 = new JLabel( "Harmadik panel felirata" ); cimke1.setBounds( 10, 15, 150, 20 ); panel3.add( cimke1 ); } public static void main(String args[]) { Program ablak = new Program(); ablak.setVisible(true); } } {{:oktatas:programozas:java:javaswing_tabbedpane.png|}} import javax.swing.event.ChangeListener; import javax.swing.event.ChangeEvent; ... tabbedPane1.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { //mi történjen } }); ==== Java füles panel külső linkek ==== * http://ngweb.atw.hu/applets/tabbedpaneapplet.html (2022) * http://www.codeproject.com/KB/tabs/JTabbedPane.aspx (2022) ===== Panel használata ===== import javax.swing.*; import java.awt.*; class Program extends JFrame { JPanel panel1; Program() { panel1 = new JPanel(); panel1.setSize(200, 200); panel1.setLocation(50, 50); panel1.setBackground(Color.blue); this.setLayout(null); this.getContentPane().add(panel1); this.setSize(800, 600); this.setLocationRelativeTo(null); this.setVisible(true); } public static void main(String args[]) { new Program(); } } ===== Menü ===== ==== Egyszerű menü ==== Program, egyetlen menü, egyetlen menüpontjával. import javax.swing.*; import java.awt.event.*; class Program extends JFrame implements ActionListener { JMenuBar menusav; JMenu filemenu; JMenuItem kilepesitem; Program() { menusav = new JMenuBar(); filemenu = new JMenu("Fájl"); kilepesitem = new JMenuItem("Kilépés"); kilepesitem.addActionListener(this); setJMenuBar(menusav); menusav.add(filemenu); filemenu.add(kilepesitem); setSize(800, 600); setVisible(true); } public static void main(String args[]) { new Program(); } public void actionPerformed(ActionEvent e) { if(e.getSource() == kilepesitem) System.exit(0); } } ==== Szeparátor hozzáadása ==== import javax.swing.*; import java.awt.event.*; class Program extends JFrame implements ActionListener { JMenuBar menusav; JMenu filemenu; JMenuItem kilepesitem; JMenuItem ujitem; Program() { menusav = new JMenuBar(); filemenu = new JMenu("Fájl"); kilepesitem = new JMenuItem("Kilépés"); ujitem = new JMenuItem("Új"); kilepesitem.addActionListener(this); setJMenuBar(menusav); menusav.add(filemenu); filemenu.add(ujitem); filemenu.addSeparator(); filemenu.add(kilepesitem); setSize(800, 600); setVisible(true); } public static void main(String args[]) { new Program(); } public void actionPerformed(ActionEvent e) { if(e.getSource() == kilepesitem) System.exit(0); } } ==== Rádiógomb és jelölőnégyzet ==== import javax.swing.*; import java.awt.event.*; class Program extends JFrame implements ActionListener, ItemListener { JMenuBar menusav; JMenu filemenu; JMenuItem kilepesitem; JMenuItem ujitem; JRadioButtonMenuItem kodolasitem; JRadioButtonMenuItem kodolasitem2; JCheckBoxMenuItem mentesitem; Program() { menusav = new JMenuBar(); filemenu = new JMenu("Fájl"); kilepesitem = new JMenuItem("Kilépés"); ujitem = new JMenuItem("Új"); kodolasitem = new JRadioButtonMenuItem("Kódolás"); kodolasitem2 = new JRadioButtonMenuItem("Kódolás2"); mentesitem = new JCheckBoxMenuItem("Automatikus mentés"); kilepesitem.addActionListener(this); kilepesitem.setMnemonic(KeyEvent.VK_C); setJMenuBar(menusav); menusav.add(filemenu); filemenu.add(ujitem); filemenu.addSeparator(); filemenu.add(kodolasitem); filemenu.add(kodolasitem2); filemenu.add(mentesitem); filemenu.addSeparator(); filemenu.add(kilepesitem); setSize(800, 600); setVisible(true); } public static void main(String args[]) { new Program(); } public void actionPerformed(ActionEvent e) { if(e.getSource() == kilepesitem) System.exit(0); } public void itemStateChanged(ItemEvent e) { } } {{:oktatas:programozas:java:javaswing_menuradiocheck.png|}} ===== Szöveghely ===== import javax.swing.*; class Program extends JFrame { JTextArea hely; Program() { hely = new JTextArea(); add(hely); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setVisible(true); } public static void main(String args[]) { new Program(); } } Margó beállítása: setMargin(new Insets(10, 10, 10, 10)); Fájl tartalmának beolvasása: textarea1.read(new InputStreamReader( getClass().getResourceAsStream("adat.txt")), null); Vagy: FileReader reader = new FileReader("adat.txt"); textarea1.read(reader, "adat.txt"); ===== Színezés ===== Egy feliratot színezünk a példaprogramban: import javax.swing.*; import java.awt.*; class Program extends JFrame { JLabel cimke; Program() { cimke = new JLabel("Valamiaaaaaaaaaaa"); cimke.setForeground(Color.blue); add(cimke); pack(); setVisible(true); } public static void main(String args[]) { new Program(); } } A felirat hátterének színezése: import javax.swing.*; import java.awt.*; class Program extends JFrame { JLabel cimke; JLabel cimke2; JPanel panel; Program() { cimke = new JLabel("Valamiaaaaaaaaaaa"); cimke2 = new JLabel("rövid", JLabel.CENTER); panel = new JPanel(); cimke2.setForeground(Color.blue); cimke2.setFont(new Font("Arial", Font.BOLD, 20)); panel.add(cimke2); panel.setBackground(Color.white); setLayout(new GridLayout(0,1)); add(cimke); add(panel); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setVisible(true); } public static void main(String args[]) { new Program(); } } Tulajdonképpen egy panelra tesszük, és azt színezzük. {{:oktatas:programozas:java:javaswing_felirathattere.png|}} ===== Fontok ===== A fontok beállításához a java.awt.Font osztályt használjuk. A példában, egy JLabel objektumon alkalmazzuk a beállításokat. A Font osztályból egy névtelen példányt fogunk hívni. import javax.swing.*; import java.awt.*; class Program extends JFrame { JLabel cimke; Program() { cimke = new JLabel("Valamiaaaaaaaaaaa"); cimke.setForeground(Color.blue); cimke.setFont(new Font("Arial", Font.BOLD, 20)); add(cimke); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setVisible(true); } public static void main(String args[]) { new Program(); } } {{:oktatas:programozas:java:javaswing_font.png|}} Monospace font: cimke.setFont(new Font(Font.MONOSPACED, Font.BOLD, 20)); ===== Igazítás ===== import javax.swing.*; import java.awt.*; class Program extends JFrame { JLabel cimke; JLabel cimke2; Program() { cimke = new JLabel("Valamiaaaaaaaaaaa"); cimke2 = new JLabel("rövid", JLabel.CENTER); cimke.setForeground(Color.blue); cimke.setFont(new Font("Arial", Font.BOLD, 20)); setLayout(new GridLayout(0,1)); add(cimke); add(cimke2); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setVisible(true); } public static void main(String args[]) { new Program(); } } {{:oktatas:programozas:java:jlabel_center.png|}} ===== Másik ablak ===== Az alábbiakban egy másik ablakot indítunk, majd arra is felteszünk egy gombot, ami annyit csinál, hogy bezárja azt. import javax.swing.*; import java.awt.event.*; class Mas extends JFrame { JButton gomb; Mas() { gomb = new JButton("Nyomj"); gomb.addActionListener(new GombKezelo()); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); add(gomb); setSize(300, 200); } class GombKezelo implements ActionListener { public void actionPerformed(ActionEvent e) { dispose(); } } } class Program extends JFrame { JButton gomb; Program() { gomb = new JButton("Nyomj"); gomb.addActionListener(new GombKezelo()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); add(gomb); setSize(200, 100); setVisible(true); } class GombKezelo implements ActionListener { public void actionPerformed(ActionEvent e) { Mas m = new Mas(); m.setVisible(true); } } public static void main(String args[]) { new Program(); } } Vegyük észre! A következő metódussal megadjuk, hogy az ablak bezárás eseményre töröljük az új ablakot: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); A dispose() metódussal pedig kiváltom a bezáráseseményt: dispose(); ==== Ha másik ablak párbeszédablak ==== import javax.swing.*; import java.awt.event.*; class Program extends JFrame { JButton masikgomb; Program() { masikgomb = new JButton("Masik"); masikgomb.addActionListener(new MasikGombClick()); masikgomb.setBounds( 50, 50, 100, 25); add(masikgomb); setLayout(null); setDefaultCloseOperation(JDialog.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public static void main(String[] argv) { new Program(); } class MasikGombClick implements ActionListener { public void actionPerformed(ActionEvent e) { Parbeszed parbeszed = new Parbeszed(); parbeszed.show(); } } class Parbeszed extends JDialog { Parbeszed() { setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); setSize(400, 300); setLocationRelativeTo(this); setVisible(true); } } } | DO_NOTHING_ON_CLOSE | Nem teszünk semmit | | HIDE_ON_CLOSE | Az ablak elrejtése | | DISPOSE_ON_CLOSE | Az ablak elrejtése és törlése | ===== Fájlválasztó párbeszédablak ===== Egyszerűen parancssorból: import javax.swing.JFileChooser; class Program02 { Program02() { JFileChooser fc = new JFileChooser(); fc.showOpenDialog(null); String utvonal = fc.getSelectedFile().getPath(); System.out.println(utvonal); } public static void main(String[] args) { new Program02(); } } Filter alkalmazása: import javax.swing.*; import java.awt.event.*; import javax.swing.filechooser.*; import java.awt.image.*; import java.io.File; class ImageFilter extends FileFilter { private final String[] okFileExtensions = new String[] {"jpg", "png", "gif"}; public boolean accept(File file) { if(file.isDirectory()) { return true; } for (String extension : okFileExtensions) { if (file.getName().toLowerCase().endsWith(extension)) { return true; } } return false; } public String getDescription() { return "Képfájlok"; } } class Program extends JFrame { JFileChooser fc = new JFileChooser(); JButton gomb; Program() { //~ fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); fc.setAcceptAllFileFilterUsed(false); fc.addChoosableFileFilter(new ImageFilter()); gomb = new JButton("Nyomj"); gomb.addActionListener(new GombClick()); add(gomb); setSize(400, 300); setVisible(true); } class GombClick implements ActionListener { public void actionPerformed(ActionEvent e) { int a = fc.showOpenDialog(Program.this); setTitle(fc.getSelectedFile().getPath()); } } public static void main(String args[]) { new Program(); } } ===== Kép beillesztése ===== ==== Kép nyomógombon ==== import javax.swing.*; import java.awt.*; class Program extends JFrame { JButton gomb; Program() { ImageIcon kep = new ImageIcon("kep.png"); gomb = new JButton(kep); gomb.setBounds(10, 10, 100, 30); add(gomb); setLayout(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 200); setVisible(true); } public static void main(String args[]) { new Program(); } } // Szegély törlése: this.button1.setBorder(BorderFactory.createEmptyBorder()); //A tartalom (kép) töltse ki a gombot: this.button1.setContentAreaFilled(false); ==== Kép panelen ==== import javax.swing.*; import java.awt.*; class KepPanel extends JPanel { Image image = null; KepPanel() { image = new ImageIcon("kep.png").getImage(); } public void paintComponent(Graphics g) { g.drawImage(image, 0, 0, 200, 200, null); } } class Program extends JFrame { KepPanel keppanel; Program() { keppanel = new KepPanel(); keppanel.setBounds(10, 10, 200, 200); add(keppanel); setLayout(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public static void main(String args[]) { new Program(); } } Az alábbi rajzoló utasítást: g.drawImage(image, 0, 0, 200, 200, null); Így is írhattuk volna: g.drawImage(image, 0, 0, null); Ekkor azonban a kép nem illeszkedik a panelen elhelyezett kép nagyságához. Nagyobb képnél csak a kép bal felső sarka fog látszani. ==== Kép panelen 2 ==== import javax.swing.*; import java.awt.*; import javax.imageio.*; import java.io.*; class KepPanel extends JPanel { Image image = null; KepPanel() throws IOException { image = ImageIO.read(new File("kep.png")); } @Override public void paintComponent(Graphics g) { g.drawImage(image, 0, 0, 100, 100, null); } } class Program extends JFrame { KepPanel panel; Program() throws IOException { panel = new KepPanel(); panel.setBounds(10, 10, 150, 150); add(panel); setLayout(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public static void main(String args[]) throws IOException { new Program(); } } ===== JToggleButton ===== if(toggleButton.isSelected()) ... import javax.swing.JFrame; import javax.swing.JToggleButton; import javax.swing.JButton; import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; class Program01 extends JFrame implements ActionListener { JToggleButton toggleButton = new JToggleButton("Kapcsoló"); JButton button = new JButton("Mehet"); Program01() { button.addActionListener(this); setLayout(new FlowLayout()); add(toggleButton); add(button); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public void actionPerformed(ActionEvent event) { if(toggleButton.isSelected()) { setTitle("Kiválasztva"); }else { setTitle("Nincs kiválasztva"); } } public static void main(String[] args) { new Program01(); } } Figyeljük, hogy változott-e a gomb állapota: import javax.swing.JFrame; import javax.swing.JToggleButton; import javax.swing.JButton; import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.ItemListener; import java.awt.event.ItemEvent; class Program01 extends JFrame implements ActionListener, ItemListener { JToggleButton toggleButton = new JToggleButton("Kapcsoló"); JButton button = new JButton("Mehet"); Program01() { button.addActionListener(this); toggleButton.addItemListener(this); setLayout(new FlowLayout()); add(toggleButton); add(button); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public void actionPerformed(ActionEvent event) { if(toggleButton.isSelected()) { setTitle("Kiválasztva"); }else { setTitle("Nincs kiválasztva"); } } public void itemStateChanged(ItemEvent event) { setTitle(getTitle() + "_"); } public static void main(String[] args) { new Program01(); } } import javax.swing.JFrame; import javax.swing.JToggleButton; import javax.swing.JButton; import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.ItemListener; import java.awt.event.ItemEvent; class Program01 extends JFrame implements ActionListener, ItemListener { JToggleButton toggleButton = new JToggleButton("Kapcsoló"); JButton button = new JButton("Mehet"); Program01() { button.addActionListener(this); toggleButton.addItemListener(this); setLayout(new FlowLayout()); add(toggleButton); add(button); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public void actionPerformed(ActionEvent event) { if(toggleButton.isSelected()) { setTitle("Kiválasztva"); }else { setTitle("Nincs kiválasztva"); } } public void itemStateChanged(ItemEvent event) { if(event.getStateChange()==ItemEvent.SELECTED) { setTitle("Kiválasztva"); }else if(event.getStateChange()==ItemEvent.DESELECTED) { setTitle("Nincs kiválasztva"); } } public static void main(String[] args) { new Program01(); } } ===== JFormattedTextField ===== Az alábbi példában csak egy telefonszámot szeretnénk megengedni beírni. import javax.swing.*; import java.text.*; import javax.swing.text.*; class Program extends JFrame { JFormattedTextField mezo; Program() { MaskFormatter mf = null; try{ mf = new MaskFormatter("+36 (##) ###-####"); mf.setPlaceholderCharacter('_'); //Nem kötelező, de hasznos }catch(ParseException e){}; mezo = new JFormattedTextField(mf); mezo.setBounds(50, 50, 150, 30); add(mezo); setLayout(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public static void main(String args[]) { new Program(); } } Csak a következő három karaktert szeretnénk elfogadni: "abc". mf = new MaskFormatter("**"); mf.setPlaceholderCharacter('_'); mf.setValidCharacters("abc"); ^ Karakter ^ Leírás ^ | # | Bármilyen szám érvényes (Character.isDigit) | | ' | Escape karakter, használhatók speciális formázó escape karakterek | | U | Bármilyen karakter (Character.isLetter) A kisbetűk nagybetűssént viselkednek | | L | Bármilyen karakter (Character.isLetter) A nagybetűk kisbetűsként értelmezendők | | A | Bármilyen karakter vagy szám (Character.isLetter vagy Character.isDigit) | | ? | Bármilyen karakter (Character.isLetter) | | * | Bármi | | H | Bármilyen hexkarakter (0-9, a-f vagy A-F) | * http://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html * http://www.java2s.com/Tutorial/Java/0240__Swing/JFormattedTextField.htm ===== JSlider ===== A JSlider egy értékskála létrehozására való. A következő példaprogramban megadunk minimum és maximum értékeket, beállítjuk függőlegesre, adunk hozzá számozást. Amint változtatja felhasználó az értéket, azonnal megjelenítjük egy beviteli mezőben. import javax.swing.*; import javax.swing.event.*; import java.awt.*; class Program extends JFrame { JSlider skala; JTextField mezo; Program() { skala = new JSlider(); mezo = new JTextField(); skala.setMinimum(0); skala.setMaximum(100); skala.setValue(20); skala.setOrientation(SwingConstants.VERTICAL); skala.setLabelTable(skala.createStandardLabels(10)); skala.setPaintLabels(true); skala.addChangeListener(new skala_Change()); mezo.setSize(50, 30); mezo.setText("kezdetben"); setLayout(new FlowLayout()); add(skala); add(mezo); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(50, 300); setVisible(true); } class skala_Change implements ChangeListener { public void stateChanged(ChangeEvent e) { int a = skala.getValue(); mezo.setText(Integer.toString(a)); } } public static void main(String[] args) { new Program(); } } ===== JProgressBar ===== A következő program egy folyamatsávot jelenít meg, amely a 20-as értéknél áll. A nyomógombot használva növelhetem annak értékét. import javax.swing.JFrame; import javax.swing.JProgressBar; import javax.swing.JButton; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; class Program extends JFrame { JProgressBar folyamatsav; JButton gomb; Program() { folyamatsav = new JProgressBar(); gomb = new JButton("Növel"); folyamatsav.setMinimum(0); folyamatsav.setMaximum(100); folyamatsav.setValue(20); folyamatsav.setBounds(50, 50, 200, 30); gomb.setBounds(100, 100, 100, 30); gomb.addActionListener(new Gomb_Click()); add(folyamatsav); add(gomb); setLayout(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } class Gomb_Click implements ActionListener { public void actionPerformed(ActionEvent e) { int a = folyamatsav.getValue(); a++; folyamatsav.setValue(a); } } public static void main(String[] args) { new Program(); } } Függőleges folyamatsávhoz állítsuk be a következőket: folyamatsav.setBounds(50, 50, 30, 200); folyamatsav.setOrientation(SwingConstants.VERTICAL); A javax.swing.SwingConstans felsorolt típust használjuk paraméterként. Százalékos megjelenítés: import javax.swing.JFrame; import javax.swing.JProgressBar; import javax.swing.JButton; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import javax.swing.SwingConstants; class Program extends JFrame { JProgressBar folyamatsav; JButton gomb; Program() { folyamatsav = new JProgressBar(); gomb = new JButton("Klikk ide"); folyamatsav.setMinimum(0); folyamatsav.setMaximum(100); folyamatsav.setValue(20); folyamatsav.setBounds(50, 50, 200, 30); folyamatsav.setStringPainted(true); gomb.setBounds(100, 100, 100, 30); gomb.addActionListener(new Gomb_Click()); add(folyamatsav); add(gomb); setLayout(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } class Gomb_Click implements ActionListener { public void actionPerformed(ActionEvent e) { int a = folyamatsav.getValue(); a++; folyamatsav.setValue(a); folyamatsav.setString(a + " %"); } } public static void main(String[] argv) { new Program(); } } ===== JTree ===== Faszerkezet. import javax.swing.JFrame; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; public class JtreeProba extends JFrame { JTree tree = new JTree(); DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); DefaultMutableTreeNode egy = new DefaultMutableTreeNode("egy"); DefaultMutableTreeNode ketto = new DefaultMutableTreeNode("kettő"); DefaultTreeModel model = new DefaultTreeModel(root); public JtreeProba() { model.insertNodeInto(egy, root, 0); model.insertNodeInto(ketto, root, 0); this.tree.setModel(model); this.add(tree); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(300, 200); this.setVisible(true); } public static void main(String[] args) { new JtreeProba(); } } Az egyes csomópontokra kattintás figyelése: package jtreeproba; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; public class JtreeProba extends JFrame { JTree tree = new JTree(); DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); DefaultMutableTreeNode egy = new DefaultMutableTreeNode("egy"); DefaultMutableTreeNode ketto = new DefaultMutableTreeNode("kettő"); DefaultTreeModel model = new DefaultTreeModel(root); public JtreeProba() { this.tree.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent evt) { mouseClickedAction(evt); } @Override public void mousePressed(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } }); this.model.insertNodeInto(egy, root, 0); this.model.insertNodeInto(ketto, root, 0); this.tree.setModel(model); this.add(tree); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(300, 200); this.setVisible(true); } public void mouseClickedAction(MouseEvent evt) { TreePath tp = this.tree.getPathForLocation(evt.getX(), evt.getY()); if(tp != null) { String selected = tp.getLastPathComponent().toString(); if(selected.equals("egy")) { JOptionPane.showMessageDialog(this, "Egy"); } if(selected.equals("kettő")) { JOptionPane.showMessageDialog(this, "Kettő"); } } } public static void main(String[] args) { new JtreeProba(); } } A NetBeans vizuális fejlesztőjével aktiváljuk a JTree objektumot, majd a tulajdonságok között keressük meg a "model" nevűt. A mellette lévő gombra kattintva a Tree model szerkesztő ablaka ugrik elénk. Van egy bal és egy jobboldali része. Jobb oldalon csak az eredményt látjuk. Baloldalon szerkeszthetjük a csomópontokat. Az egyes csomópontok gyermek elemeit beljebb kell kezdeni egy szóközzel. Ha újabb alcsomópontokat szeretnénk létrehozni azokat két szóközzel kell beljebb kezdeni, stb. ===== JSpinner ===== import javax.swing.JFrame; import javax.swing.JSpinner; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; import java.awt.FlowLayout; import java.awt.Dimension; class Program01 extends JFrame { SpinnerModel spinmodel; JSpinner lepteto; Program01() { int min = 2; int max = 15; int leptek = 1; int kezdoErtek = 9; spinmodel = new SpinnerNumberModel(kezdoErtek, min, max, leptek); lepteto = new JSpinner(spinmodel); Dimension d = lepteto.getPreferredSize(); d.width = 50; lepteto.setPreferredSize(d); setLayout(new FlowLayout()); add(lepteto); setSize(400, 300); setVisible(true); } public static void main(String args[]) { new Program01(); } } Szintaxis: SpinnerNumberModel(double value, double minimum, double maximum, double stepSize) SpinnerNumberModel(int value, int minimum, int maximum, int stepSize) A változás figyelése: delaySpinner.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { int szam = (Integer)delaySpinner.getModel().getValue(); } }); ===== Ablakállapotok ===== import javax.swing.JFrame; import java.awt.Frame; class Program extends JFrame { Program() throws InterruptedException { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); // Várunk 5 másodpercet Thread.sleep (5000); setState ( JFrame.ICONIFIED ); // Várunk 5 másodpercet Thread.sleep (5000); setState ( JFrame.NORMAL ); // Várunk 5 másodpecet Thread.sleep (5000); setVisible (false); dispose(); // Kilépünk System.exit(0); } public static void main(String args[]) throws InterruptedException { new Program(); } } ===== Elrendezéskezelés ===== ==== Az elrendezéskezelésről ==== A setLayout() metódussal állítjuk. A JPanel komponens használata esetén a konstruktorban is megadható az elrendezéskezelő. Elrendezéskezelő osztályok: * java.awt.BorderLayout * javax.swing.BoxLayout * java.awt.CardLayout * java.awt.FlowLayout * java.awt.GridBagLayout * java.awt.GridLayout * java.swing.GroupLayout * javax.swing.SprintLayout ==== java.awt.FlowLayout ==== import java.awt.FlowLayout; import javax.swing.JButton; import javax.swing.JFrame; public class MainWindow extends JFrame { JButton button1 = new JButton("gomb1"); JButton button2 = new JButton("gomb2"); JButton button3 = new JButton("gomb3"); public MainWindow() { this.setLayout(new FlowLayout()); this.add(button1); this.add(button2); this.add(button3); this.setTitle("FlowLayout"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); this.setVisible(true); } } {{:oktatas:programozas:java:flowlayout.png|}} ==== javax.swing.BoxLayout ==== import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.BoxLayout; import javax.swing.JPanel; class Program01 extends JFrame { JButton gomb1 = new JButton("Első"); JButton gomb2 = new JButton("Második"); JButton gomb3 = new JButton("Harmadik"); Program01() { //PAGE_AXIS, X_AXIS, Y_AXIS, LINE_AXIS setLayout(new BoxLayout(getContentPane(), BoxLayout.LINE_AXIS) ); add(gomb1); add(gomb2); add(gomb3); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new Program01(); } } {{:oktatas:programozas:java:boxlayout01.png|}} JPanel használatával: import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.BoxLayout; import javax.swing.JPanel; class Program01 extends JFrame { JButton gomb1 = new JButton("Első"); JButton gomb2 = new JButton("Második"); JButton gomb3 = new JButton("Harmadik"); JPanel panel = new JPanel(); Program01() { //PAGE_AXIS, X_AXIS, Y_AXIS, LINE_AXIS panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS) ); panel.add(gomb1); panel.add(gomb2); panel.add(gomb3); add(panel); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new Program01(); } } {{:oktatas:programozas:java:boxlayout_panel01.png|}} Függőlegesen: import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.BoxLayout; import javax.swing.JPanel; class Program01 extends JFrame { JButton gomb1 = new JButton("Első"); JButton gomb2 = new JButton("Második"); JButton gomb3 = new JButton("Harmadik"); JPanel panel = new JPanel(); Program01() { //PAGE_AXIS, X_AXIS, Y_AXIS, LINE_AXIS panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS) ); panel.add(gomb1); panel.add(gomb2); panel.add(gomb3); add(panel); pack(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new Program01(); } } {{:oktatas:programozas:java:boxlayout02.png|}} ==== GridBagLayout ==== A GridBagLayout egy rugalmas elrendezéskezelő, ami vízszintes, függőlegesen rácsok vagy alapvonal mentén igazítja az összetevőket. A komponenseknek nem szükséges azonos méretűnek lenni. Minden komponens megjelenési területe egy cella. Minden komponens igazítását egy GridBagConstraints objektummal végezzük. Minden komponensnek van egy [[https://docs.oracle.com/javase/8/docs/api/java/awt/ComponentOrientation.html|alapértelmezett tájolása]]. import java.awt.GridBagLayout; import java.awt.GridBagConstraints; JPanel pane = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); panel1.add(aKomponens, c); Minden komponenshez adhatunk saját GridBagConstraints objektumot, de ugyanazt is beállíthatjuk. A GridBagConstraints a következő változókat tartalmazza: === gridx, gridy === Sorok és oszlopok megadása. Megmondjuk melyik cellába tesszük a komponenst. Az első mező címe: gridx=0 Az első sor címe: gridy=0 Az alapértelmezett: GridBagConstraints.RELATIVE === gridwidth, gridheight === Az oszlopok és sorok szélessége és magassága. Egy cella hány cellán nyúljon keresztül. * Az előtt lévő sorral egyezzen meg: GridBagConstraints.REMAINDER * GridBagConstraints.RELATIVE === fill === Kitölti a rendelkezésre álló helyet vízszintesen vagy függőlegesen. * GridBagConstraints.VERTICAL * GridBagConstraints.HORIZONTAL === ipadx, ipady === Belső térköz. === insets === Külső térköz === anchor === Akkor használjuk ha komponens kisebb mint a rendelkezésére álló hely. A következő konstansok használhatók: * GridBagConstraints.CENTER (alapértelmezés) * PAGE_START * PAGE_END * LINE_START * LINE_END * FIRST_LINE_START * FIRST_LINE_END * LAST_LINE_END * LAST_LINE_START === weightx, weighty === Vastagság * 0.0 (alapértelmezett) * 1.0 === Első példa === import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import javax.swing.JButton; import javax.swing.JFrame; public class MainWindow extends JFrame { JButton button1 = new JButton("gomb1"); JButton button2 = new JButton("gomb2"); JButton button3 = new JButton("gomb3"); GridBagLayout layout = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); public MainWindow() { this.setLayout(new GridBagLayout()); this.c.fill = GridBagConstraints.HORIZONTAL; this.c.gridx = 0; this.c.gridy = 0; this.add(button1, c); this.c.gridx = 1; this.c.gridy = 0; this.add(button2, c); this.c.gridx = 0; this.c.gridy = 2; this.c.gridwidth = 2; this.add(button3, c); this.setTitle("GridBagLayout"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); this.setVisible(true); } } {{:oktatas:programozas:java:gridbaglayout_01.png|}} === Példa 02 === import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import javax.swing.JButton; import javax.swing.JFrame; public class MainWindow extends JFrame { JButton button1 = new JButton("gomb1"); JButton button2 = new JButton("gomb2"); JButton button3 = new JButton("gomb3"); JButton button4 = new JButton("gomb4"); JButton button5 = new JButton("gomb5"); GridBagLayout layout = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); public MainWindow() { this.setLayout(new GridBagLayout()); this.c.fill = GridBagConstraints.HORIZONTAL; this.c.gridx = 0; this.c.gridy = 0; this.add(button1, c); this.c.gridx = 1; this.c.gridy = 0; this.add(button2, c); this.c.gridx = 2; this.c.gridy = 0; this.add(button3, c); this.c.gridx = 0; this.c.gridy = 1; this.c.gridwidth = 3; this.add(button4, c); this.c.gridx = 0; this.c.gridy = 2; this.c.gridwidth = 3; this.c.ipady = 40; this.add(button5, c); this.setTitle("GridBagLayout"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); this.setVisible(true); } } {{:oktatas:programozas:java:gridbaglayout_02.png|}} === További információk === * https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html * https://docs.oracle.com/javase/8/docs/api/java/awt/GridBagConstraints.html * https://docs.oracle.com/javase/8/docs/api/java/awt/ComponentOrientation.html * https://docs.oracle.com/javase/8/docs/api/java/awt/GridBagLayout.html ==== BorderLayout ==== import java.awt.BorderLayout; pane.add(button, BorderLayout.LINE_END); BorderLayout: button = new JButton("Button 3 (LINE_START)"); pane.setLayout(new BorderLayout()); pane.add(button, BorderLayout.LINE_START); * BorderLayout.PAGE_START, BorderLayout.NORTH * BorderLayout.PAGE_END, BorderLayout.SOUTH * BorderLayout.LINE_START, BorderLayout.WEST * BorderLayout.LINE_END, BorderLayout.EAST * BorderLayout.CENTER import java.awt.BorderLayout; import javax.swing.JButton; import javax.swing.JFrame; public class MainWindow extends JFrame { JButton button1 = new JButton("gomb1"); JButton button2 = new JButton("gomb2"); JButton button3 = new JButton("gomb3"); JButton button4 = new JButton("gomb4"); JButton button5 = new JButton("gomb5"); public MainWindow() { this.setLayout(new BorderLayout()); this.add(button1, BorderLayout.NORTH); this.add(button2, BorderLayout.EAST); this.add(button3, BorderLayout.SOUTH); this.add(button4, BorderLayout.WEST); this.add(button5, BorderLayout.CENTER); this.setTitle("BorderLayout"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); this.setVisible(true); } } {{:oktatas:programozas:java:borderlayout.png|}} * http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html (BorderLayout) ==== GridLayout ==== Importálás: import java.awt.GridLayout; Az első mindig a sor, a második paraméter mindig az oszlopok száma: panel.setLayout(new GridLayout(1,0)); panel.add(gomb1); panel.add(gomb2); import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JFrame; public class MainWindow extends JFrame { JButton button1 = new JButton("gomb1"); JButton button2 = new JButton("gomb2"); JButton button3 = new JButton("gomb3"); JButton button4 = new JButton("gomb4"); JButton button5 = new JButton("gomb5"); JButton button6 = new JButton("gomb6"); JButton button7 = new JButton("gomb7"); public MainWindow() { this.setLayout(new GridLayout(4, 2)); this.add(button1); this.add(button2); this.add(button3); this.add(button4); this.add(button5); this.add(button6); this.add(button7); this.setTitle("GridLayout"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); this.setVisible(true); } } {{:oktatas:programozas:java:gridlayout.png|}} ==== java.awt.CardLayout ==== A CardLayout esetén az elemek egymás felett helyezkednek el. Az elrendezés kezelő példányán keresztül léptethetünk a komponensek között. import java.awt.CardLayout; import javax.swing.JButton; import javax.swing.JFrame; public class MainWindow extends JFrame { JButton button1 = new JButton("gomb1"); JButton button2 = new JButton("gomb2"); JButton button3 = new JButton("gomb3"); CardLayout card = new CardLayout(50, 100); public MainWindow() { this.button1.addActionListener(e->onClickButton()); this.button2.addActionListener(e->onClickButton()); this.button3.addActionListener(e->onClickButton()); this.setLayout(card); this.add(button1); this.add(button2); this.add(button3); this.setTitle("CardLayout"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.pack(); this.setVisible(true); } private void onClickButton() { this.card.next(this.getContentPane()); } } {{:oktatas:programozas:java:cardlayout.png|}} ===== TrayIcon ===== import javax.swing.JFrame; import javax.swing.JButton; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.SystemTray; import java.awt.TrayIcon; import java.awt.AWTException; import javax.swing.ImageIcon; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JOptionPane; class Program01 extends JFrame { JButton button1 = new JButton("Kilépés"); ImageIcon img = new ImageIcon(this.getClass().getClassLoader().getResource("ikon.png")); JPopupMenu jpopup = new JPopupMenu(); Program01() { JMenuItem exampleMenuItem = new JMenuItem("Példa", new ImageIcon("ikon24x24.png")); JMenuItem exitMenuItem = new JMenuItem("Kilépés"); exitMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); exampleMenuItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(getContentPane(), "Példa"); } }); jpopup.add(exampleMenuItem); jpopup.addSeparator(); jpopup.add(exitMenuItem); TrayIcon trayIcon = new TrayIcon(img.getImage()); trayIcon.setImageAutoSize(true); trayIcon.addMouseListener(new MouseAdapter() { public void mouseReleased(MouseEvent e) { jpopup.setLocation(e.getX(), e.getY()); jpopup.setInvoker(jpopup); jpopup.setVisible(true); } }); SystemTray sysTray = SystemTray.getSystemTray(); try { sysTray.add(trayIcon); } catch(AWTException e) { e.printStackTrace(); System.err.println("Rendszer tray ikon"); } button1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); add(button1); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setVisible(true); } public static void main(String args[]) { new Program01(); } } * http://docs.oracle.com/javase/tutorial/uiswing/misc/systemtray.html ===== JToolBar ===== import javax.swing.JFrame; import javax.swing.JToolBar; import java.awt.BorderLayout; import javax.swing.JButton; class Program01 extends JFrame { JToolBar toolBar = new JToolBar(); Program01() { JButton button = new JButton("Felirat"); button.setToolTipText("Szöveg"); toolBar.add(button); add(toolBar, BorderLayout.NORTH); setSize(800, 600); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new Program01(); } } {{:oktatas:programozas:java:javaswingjtoolbar_01.png|}} Esetleg készítsünk egy saját eszköztár osztályt: import javax.swing.JToolBar; import java.awt.Color; import javax.swing.JButton; class MyToolbar extends JToolBar { public MyToolbar() { JButton button = new JButton("Felirat"); add(button); button.setToolTipText("Szövege"); setName("Eszköztár"); setBackground(new Color(245, 245, 245)); setOrientation(1); setBorderPainted(false); setFloatable(true); setOpaque(true); } } import javax.swing.JFrame; import java.awt.BorderLayout; class Program01 extends JFrame { MyToolbar toolBar = new MyToolbar(); Program01() { add(toolBar, BorderLayout.NORTH); setSize(400, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new Program01(); } } ===== Swing szállak ===== Ha elindítunk egy Swing programot, akkor az összes tevékenység az EDT-ben fut. Az EDT az Event Dispatching Thread szavak betűiből rövidítés. Ezért, ha kiteszünk egy JButton, amely egy időigényes programot futtat, a programunk várva a feladat befejezését, megmerevedik. A probléma feloldható, ha az időigényes feladatot külön szálon futtatjuk. Ha azonban a külön szál, ugyanazt a komponenst egy időben akarja elérni, az egyik végrehajtása elmaradhat. Több szál használata esetén ezért a tevékenységeket sorba rendezzük. Ezért szoktuk használni a SwingUtilities osztályt. Ebben az osztályban az invokeLater() metódusból indítjuk a programunkat. import javax.swing.SwingUtilities; ... public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new Program01(); } }); } Az invokeLater() tetszőleges szálból hívható, amely az EDT várólistájára helyezi a kívánt tevékenységet. A következő példában egyik gomb 5 másodperc várakozás után megváltoztatja a programablak címsorát, de közben a másik nyomógomb működik. import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JTextField; public class Program01 extends JFrame { JButton varGomb = new JButton("Vár"); JButton valtGomb = new JButton("Vált"); JTextField mezo = new JTextField(4); public Program01() { varGomb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { varGombActionListener(arg0); } }); valtGomb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { mezo.setText("Valami"); } }); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setLayout(new FlowLayout()); this.add(varGomb); this.add(valtGomb); this.add(mezo); this.pack(); this.setVisible(true); } private void varGombActionListener(ActionEvent e) { (new Thread() { public void run() { try { Thread.sleep(5000); setWindowTitle(); } catch (InterruptedException e) { System.err.println("Megszakítási hiba!"); } } }).start(); } private void setWindowTitle() { this.setTitle("Működik"); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { new Program01(); } }); } } ===== Időzítő ===== javax.swing.Timer A konstruktor: Timer(int varakozas, ActionListener figyelo) * varakozas - milliszekundum a kezdés és az első esemény között * figyelo - előkísztő figyelő (pl. ActionListener), de lehet null is * http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html * http://docs.oracle.com/javase/6/docs/api/javax/swing/Timer.html javax.swing.Timer timer = new javax.swing.Timer(induloVarakozas, this); timer.setInitialDelay(varakozas); timer.start(); ===== Ablakállapotok kezelése ===== Az ablak bezárása előtt mentés: import javax.swing.JFrame; import java.awt.event.WindowStateListener; import java.awt.event.WindowEvent; class Program01 extends JFrame { Program01() { addWindowStateListener(new WindowStateListener() { public void windowStateChanged(WindowEvent e) { windowStateListener(e); } }); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setVisible(true); } private void windowStateListener(WindowEvent e) { if(e.getNewState()==WindowEvent.WINDOW_CLOSED) { //ide jön a mentés } } public static void main(String[] args) { new Program01(); } } ===== JLayeredPane ===== A JLayeredPane lehetővé teszi rétegek kezelését. A rétegkezelést Z index, vagy sorrendnek is hívjuk. A következő példában nyomógombokat helyeztünk egymás felé: import javax.swing.JLayeredPane; ... class RetegesPanel extends JLayeredPane { public RetegesPanel(){ setComponentZOrder(button1, 1); setComponentZOrder(button2, 1); setComponentZOrder(button3, 0); } } Ha az egyik gomb felé viszem az egeret, akkor az a gomb felülre kerül. Ha szeretnénk mindig az adott Z sorrendben látni a gombokat, akkor használjuk a setLayer() metódust: import javax.swing.JLayeredPane; ... class RetegesPanel extends JLayeredPane { public RetegesPanel(){ setLayer(button1, 0); setLayer(button2, 0); setLayer(button3, 1); } } Így, ha az egeret egy gomb felé viszem, az adott rétegben marad. [[http://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html|Az ide vonatkozó hivatalos dokumentáció]] ===== Fókusz ===== A GUI programnak általában van egy ablaka, amelyet frame-nek is szoktunk nevezni. Az ablakon komponenseket helyezünk el, amelyek közül egy mindig fókuszban van. A fókusz alatt értjük, hogy aktívvá válik, kissé megváltozik a színezete, abba írhatunk, vagy vezérelhetjük billentyűkkel stb. Ha billentyűnyomásokat szeretnénk figyelni, azt csak a fókuszban lévő komponensen tudjuk alapesetben. Ha minden komponensnél figyelni szeretnénk egy billentyűkombinációt, akkor azt az ablakon kell figyeltetni. A fókusz átadása az egész ablaknak: this.requestFocus(); Néha szeretnénk a fókuszt tiltani, vagy éppen újra engedélyezni. A Component osztály rendelkezik egy setFocusable() metódussal. Szintaktikája: setFocusable(boolean focusable) Segítségével a Component osztály vagy azok leszármazott osztályaiból példányosított objektumoknak beállítható a fókusz engedélyezése vagy tiltása. Az ablakkeretre tehető komponensek (JButton, JTextField, stb) őse között szerepel a Component osztály, ezért mindegyiknél használható a metódus. button1.setFocusable(false); ===== jDesktopPane ===== A jDesktopPane segítségével virtuális asztal létrehozása lehetséges. A virtuális asztalra jInternalFrame ablakok helyezhetők. Az ablakoknak beállítható az átméretezhetőség, ikonállapotba helyezhetőség, maximalizálás stb. * https://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html ===== JDialog ===== Ha a JDialog ablakot szeretnék a szülőablakhoz igazítani, akkor használhatjuk a következő utasítást: super.setLocationRelativeTo(parent); public HelpDialog(java.awt.Frame parent, boolean modal) { super(parent, modal); initComponents(); super.setLocationRelativeTo(parent); } A perent objektum automatikusan rendelkezésünkre áll NetBeans esetén. De így is használható: public HelpDialog(java.awt.Frame parent, boolean modal) { super(parent, modal); initComponents(); setLocationRelativeTo(parent); } ===== TextPane ===== Mozgás a lap tetejére: setCaretPosition(0) ===== Komponensek helyzete ===== public void move() { int x = this.button1.getLocation().x; int y = this.button1.getLocation().y; this.button1.setLocation(x+100, y); } ===== Függelék ===== ==== Füles ablak példa ==== Négypaneles példa, státuszbárral: import javax.swing.JFrame; import javax.swing.JTabbedPane; import javax.swing.JPanel; import javax.swing.JLabel; import java.awt.BorderLayout; import javax.swing.JMenuBar; import javax.swing.JMenu; import javax.swing.JMenuItem; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.Dimension; class Program01 extends JFrame implements ActionListener { private JTabbedPane tabbedPane; private JPanel firstPanel; private JPanel secondPanel; private JPanel thirdPanel; private JPanel fourthPanel; private JMenuBar menuBar; private JMenuItem exitMenuItem; private StatusBar statusBar; public Program01() { setLayout( new BorderLayout() ); menuBar = new JMenuBar(); menuCreate(); statusBar = new StatusBar(); getContentPane().add(statusBar, java.awt.BorderLayout.SOUTH); firstPanelCreate(); secondPanelCreate(); thirdPanelCreate(); fourthPanelCreate(); tabbedPane = new JTabbedPane(); tabbedPane.addTab("Első", firstPanel); tabbedPane.addTab("Második", secondPanel); tabbedPane.addTab("Harmadik", thirdPanel); tabbedPane.addTab("Negyedik", fourthPanel); add(tabbedPane); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setVisible(true); } void firstPanelCreate() { firstPanel = new JPanel(); firstPanel.setLayout( null ); JLabel cimke1 = new JLabel( "Első panel felirata" ); cimke1.setBounds( 10, 15, 150, 20 ); firstPanel.add( cimke1 ); } void secondPanelCreate() { secondPanel = new JPanel(); secondPanel.setLayout( null ); JLabel cimke1 = new JLabel( "Második panel felirata" ); cimke1.setBounds( 10, 15, 150, 20 ); secondPanel.add( cimke1 ); } void thirdPanelCreate() { thirdPanel = new JPanel(); thirdPanel.setLayout( null ); JLabel cimke1 = new JLabel( "Harmadik panel felirata" ); cimke1.setBounds( 10, 15, 150, 20 ); thirdPanel.add( cimke1 ); } void fourthPanelCreate() { fourthPanel = new JPanel(); fourthPanel.setLayout( null ); JLabel cimke1 = new JLabel( "Harmadik panel felirata" ); cimke1.setBounds( 10, 15, 150, 20 ); fourthPanel.add( cimke1 ); } void menuCreate() { JMenu filemenu; filemenu = new JMenu("Fájl"); exitMenuItem = new JMenuItem("Kilépés"); exitMenuItem.addActionListener(this); setJMenuBar(menuBar); menuBar.add(filemenu); filemenu.add(exitMenuItem); } public void actionPerformed(ActionEvent e) { if(e.getSource() == exitMenuItem) System.exit(0); } public static void main(String args[]) { new Program01(); } public class StatusBar extends JLabel { public StatusBar() { super(); super.setPreferredSize(new Dimension(100, 16)); setMessage("Készen van"); } public void setMessage(String message) { setText(" "+message); } } } ==== Szeparátor ==== System.getProperty("line.separator") ==== Ablak stílus ==== Az eseménykezelőt az ActionListener névtelen példányosításával oldjuk meg. Létrehozunk egy actionPerformed() metódust. Az esemény hatására végrehajtandó kód külön metódusban van, a példában ez a GombActionPerformed(). import javax.swing.JFrame; import javax.swing.JButton; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; class Program01 extends JFrame { private JButton gomb; Program01() { gomb = new JButton(); gomb.setText("Klikkelj ide"); gomb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { GombActionPerformed(e); } }); add(gomb); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); } private void GombActionPerformed(ActionEvent e) { } public static void main(String[] args) { try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(Program01.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(Program01.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(Program01.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(Program01.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } new Program01().setVisible(true); } } Beállítható: * CDE/Motif * GTK+ * Nimbus * Metal ==== Óra részlet ==== Ha szeretnénk órát készíteni, szükségünk van egy időzítőre, és valahogy le kell kérdeznünk az időt, esetleg még a dátumot is. A programrészt a program konstruktorába tesszük vagy onnan hívjuk. A program része két feliratot is feltételez a GUI felületen. Az egyik **timeLabel**, a masik **dateLabel**. javax.swing.Timer timer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String timeStr, dateStr; Calendar c = Calendar.getInstance(); SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date = c.getTime(); timeStr = timeFormat.format(date); dateStr = dateFormat.format(date); timeLabel.setText(timeStr); dateLabel.setText(dateStr); } } ); timer.start(); ===== Külső link ===== * https://docs.oracle.com/javase/tutorial/uiswing/ (2019) * https://docs.oracle.com/javase/tutorial/uiswing/components/ (2021) * http://mindprod.com/jgloss/image.html (Minden ami kép; 2019) * http://download.oracle.com/javase/tutorial/uiswing/components/list.html (JList; 2019) * http://download.oracle.com/javase/tutorial/uiswing/components/toplevel.html (2019) * http://zetcode.com/gfx/java2d/ * https://www.logicbig.com/tutorials/java-swing.html (2019) * https://www.javacodex.com/More-Examples/2/11 (2019) * https://www3.ntu.edu.sg/home/ehchua/programming/java/J4a_GUI_2.html (2023)