750 likes | 902 Views
II. Grafikus felhasználói interfész. 5. A felhasználói interfész felépítése 6. Elrendezésmenedzserek 7. Eseményvezérelt programozás 8. Swing-komponensek 9. Grafika, képek 10. Alacsony szintű események Belső eseménykezelés, komponensgyártás Applet. II. Grafikus felhasználói interfész.
E N D
II. Grafikus felhasználói interfész 5. A felhasználói interfész felépítése 6. Elrendezésmenedzserek 7. Eseményvezérelt programozás 8. Swing-komponensek 9. Grafika, képek 10. Alacsony szintű események • Belső eseménykezelés, komponensgyártás • Applet
II. Grafikus felhasználói interfész 5. A felhasználói interfész felépítése 1. Komponensek és azok tulajdonosi hierarchiája 2. AWT és Swing osztályhierarchia 3. Swing mintaprogram 4 Jellemzők 5. Pont, méret, téglalap 6. Koordinátarendszer 7. Szín, betű 8. Az absztrakt JComponent osztály 9. Container osztály 10. java.awt.Window osztály 11. JFrame osztály
:JFrame :JDialog :JWindow :JMenuBar contentPane :JPanel :JPanel contentPane :JLabel :JTextField :JButton :JButton :JLabel :JButton :JTextField :JTextArea :JComboBox :JList :JCheckBox :JScrollbar :JRadioButton :JRadioButton :ButtonGroup Komponensek tulajdonosi hierarchiája Konténerkomponens Vezérlőkomponens
Tulajdonosi viszony • Konténer és komponense: A konténer komponensei fizikailag sosem kerülhetnek a konténeren kívülre • Ablak és ablaka: A gyerek ablakok elhelyezkedése és mérete független a szülő ablaktól Tulajdonosi hierarchia • Felépítése a programozó feladata! • Az a komponens, amely nincs rajta a tulajdonosi hierarchián, nem látható és nem képes eseményekre reagálni! • Szülő megszűnése gyerek megszűnése
java.lang.Object +--Component | +--Container | | +--JComponent | | | +--JLabel | | | +--AbstractButton | | | | +--JButton | | | | +--JToggleButton | | | | | +--JCheckBox | | | | | +--JRadioButton | | | | +--JMenuItem | | | | | +--JCheckBoxMenuItem | | | | | +--JRadioButtonMenuItem | | | | | +--JMenu | | | +--JMenuBar | | | +--JComboBox | | | +--JTextComponent | | | | +--JTextField | | | | +--JTextArea | | | +--JList | | | +--JScrollBar | | | +--JScrollPane | | | +--JPanel | | | +--JColorChooser | | | +--JOptionPane +--ButtonGroup +--ImageIcon +--Timer AWT és Swing java.awt javax.swing java.lang.Object +--FlowLayout +--GridLayout +--BorderLayout +--java.util.EventObject | +--AWTEvent | + ... +--Point +--Dimension +--Rectangle +--Polygon +--Font +--Color +--Graphics +--Image +--Component | +--Label | +--Button | +--... | +--Container | | +--Panel | | | +--Applet | | | | +--javax.swing.JApplet | | +--java.awt.Window | | | +-- javax.swing.JWindow | | | +--java.awt.Frame | | | | +-- javax.swing.JFrame | | | +-- java.awt.Dialog | | | | +--javax.swing.JDialog
java.lang.Object +--Component | +--Label | +--Button | +--... | +--Container | | +--Panel | | | +--Applet | | +--Window | | | +--Frame | | | +--Dialog java.awt java.lang.Object +--FlowLayout +--GridLayout +--BorderLayout +--java.util.EventObject | +--AWTEvent | + ... +--Point +--Dimension +--Rectangle +--Polygon +--Font +--Color +--Graphics +--Image
JComponent +--JLabel +--AbstractButton | +--JButton | +--JToggleButton | | +--JCheckBox | | +--JRadioButton | +--JMenuItem | | +--JCheckBoxMenuItem | | +--JRadioButtonMenuItem | | +--JMenu +--JMenuBar +--JComboBox +--JTextComponent | +--JTextField | +--JTextArea +--JList +--JScrollBar +--JScrollPane +--JPanel +--JColorChooser +--JOptionPane javax.swing Object +--Component | +--Container | | +--Panel | | | +--Applet | | | | +--JApplet | | +--Window | | | +--JWindow | | | +--Frame | | | | +--JFrame | | | +--Dialog | | | | +--JDialog | | +--JComponent | | | + ... +--ButtonGroup +--ImageIcon +--Timer
fr lbInfo btOk btNemOk Swing mintaprogram • Feladat – Frame teszt • Készítsük el az itt látható keretet! A keret bal felső sarka a képernyő (100,50) pozícióján legyen, mérete 300*100, címe: Frame teszt. A kereten legyen egy címke a Döntsd el: szöveggel, továbbá legyen két nyomógomb, OK és Nem OK felirattal! A programnak egyelőre nem kell reagálnia semmilyen eseményre.
JFrame() setTitle("Frame teszt") setBounds(100,50,300,100) setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) cp = getContentPane() setVisible(true) main FrameTest1 fr:JFrame setLayout(new FlowLayout()) add(lbInfo) add(btOk) add(btNemOk) :FlowLayout cp:JPanel lbInfo:JLabel btOk:JButton btNemOk:JButton 1. megoldás – Keret összerakása kívülről Együttműködési diagram
import java.awt.*; import javax.swing.*; public class FrameTest1 { public static void main (String args[]) { JFrame fr; JLabel lbInfo; JButton btOk, btNemOk; fr = new JFrame(); fr.setTitle("Frame teszt"); fr.setBounds(100,50,300,100); fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = fr.getContentPane(); cp.setLayout(new FlowLayout()); lbInfo = new JLabel("Döntsd el:"); btOk = new JButton("OK"); btNemOk = new JButton("Nem OK"); cp.add(lbInfo); cp.add(btOk); cp.add(btNemOk); fr.setVisible(true); } // main } // FrameTest1
setTitle("Frame teszt") setBounds(100,50,300,100) cp = getContentPane() setVisible(true), setD.CloseOp.(...) main SpecFrame() FrameTest2 :SpecFrame setLayout(new FlowLayout()) add(lbInfo) add(btOk) add(btNemOk) cp:JPanel :FlowLayout lbInfo:JLabel btOk:JButton btNemOk:JButton 2. megoldás – Keret összerakása belülről Együttműködési diagram
import java.awt.*; import javax.swing.*; class SpecFrame extends JFrame { JLabel lbInfo; JButton btOk, btNemOk; public SpecFrame() { setTitle("Frame teszt"); setBounds(100,50,300,100); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); lbInfo = new JLabel("Döntsd el:"); btOk = new JButton("OK"); btNemOk = new JButton("Nem OK");
cp.add(lbInfo); cp.add(btOk); cp.add(btNemOk); setVisible(true); } // konstruktor } // SpecFrame public class FrameTest2 { public static void main (String args[]) { new SpecFrame(); } // main } // FrameTest2
3. megoldás – A konténer komponenseit nem deklaráljuk, pakolunk class SpecFrame extends JFrame { public SpecFrame() { … cp.add(new JLabel("Döntsd el:")); cp.add(new JButton("OK")); cp.add(new JButton("Nem OK")); pack(); show(); } // konstruktor } // SpecFrame
Példák: Jellemző Beállító metódus Lekérdező metódus int columns void setColumns(int columns) int getColumns() boolean visible void setVisible(boolean visible) boolean isVisible() Jellemzők • Property: Beállítható és lekérdezhető tulajdonság • Deklaráció: PropType propName; • beállító metódus (set):void setPropName(PropType propName) • lekérdező metódus (get / is):PropTypegetPropName()boolean isPropName()
Pont, méret, téglalap Osztályok a látható komponensek paraméterezéséhez • Point osztály: megjegyzi egy pont x és y koordinátáit • Dimension osztály: megjegyzi egy téglalap méretét (szélességét és magasságát) • Rectangle osztály: megjegyzi egy téglalap • helyzetét (location): bal felső sarkának x és y koordinátáit, és • méretét (dimension): szélességét (width) és magasságát (height)
Feladat – Pontok és téglalapok • Adva van két téglalap: az egyik téglalap bal felső sarka a (100,100) pont, mérete 50*30; a másik téglalap bal felső sarka a (120,80) pont, mérete 20*60. • Határozzuk meg a téglalapok közös részét! • Vizsgáljuk meg, hogy a (130,110) pont benne van-e a közös részben! • Határozzuk meg azt a legkisebb téglalapot, amely tartalmazza a téglalapokat és egy megadott pontsoro-zat összes pontját!
nagy p r2 r1 kozos import java.awt.*; public class PontTegla { public static void main (String args[]) { Rectangle r1 = new Rectangle(100,100,50,30); Rectangle r2 = new Rectangle(); r2.setLocation(120,80); r2.setSize(20,60); Rectangle kozos = r1.intersection(r2); System.out.println("Közös: "+kozos); Point p = new Point(130,110);
if (kozos.contains(p)) System.out.println(p+" benne van"); else System.out.println(p+" nincs benne"); Point[] pontok = {new Point(50,80),new Point(15,70), new Point(30,95),new Point(120,200)}; Rectangle nagy = r1.union(r2); for (int i=0; i<pontok.length; i++) nagy.add(pontok[i]); System.out.println("Nagy: "+nagy); System.out.println("Nagy mérete: "+nagy.getSize()); } }
(0,0) screenSize.width=1024 x y screenSize.height=768 A képernyő bal alsó sarka: (1023,767) Koordinátarendszer Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
Betű, szín Font osztály • Adott tulajdonságú fontot (betűfajtát) tárol • Tulajdonságok • String fontName (név, pl.: Arial, Monospaced) • int style (stílus, pl.: PLAIN, BOLD, ITALIC) • int size (betűméret pontokban) • Példánya változtathatatlan • Minden komponensnek van fontja • Logikai fontnevek: SansSerif, Serif, Monospaced, Dialog, DialogInput
Color osztály • RGB színt tárol • Minden szín a 3 alapszín (piros,zöld,kék) keveréke • Tulajdonságok • int red (piros összetevő, 0..255) • int green (zöld összetevő, 0..255) • int blue (kék összetevő, 0..255) • Példánya változtathatatlan • Minden komponensnek van egy háttérszíne és egy előtérszíne (betűszíne) • Konstans szín objektumokat definiál: Color.black, Color.blue, Color.white, ...
SystemColor osztály • Rendszer által használt színeket definiál: SystemColor.info, SystemColor.infoText, SystemColor.desktop, ... Színek, betűk használata lb = new JLabel("Szöveg:"); lb.setFont(new Font(”Arial",Font.BOLD,24)); lb.setBackground(SystemColor.control); lb.setForeground(Color.red);
Az absztrakt JComponent osztály • Absztrakt osztály • A képernyőn megjelenő Swing komponensek közös őse • Mezők • static final float CENTER_ALIGNMENT, ... • Jellemzők • Color backgroundColor foreground • boolean opaque
Jellemzők (folyt.) • Font font • Cursor cursor • Border border • Dimension maximumSizeDimension minimumSizeDimension preferredSize • float alignmentXfloat alignmentY • String toolTipText • boolean visible • boolean enabled • boolean requestFocusEnabled
Helyzet, méret • int getX()int getY() • int getWidth()int getHeight() • Rectangle getBounds() • Point getLocation()Point getLocationOnScreen() • void setBounds(int x, int y, int width, int height)void setLocation(int x, int y)void setSize(int width, int height) • boolean contains(int x, int y)boolean contains(Point p)
Láthatóság, érvényesség • boolean isDisplayable() • void validate() • Fókusz, eseményfogadás • boolean hasFocus() • void requestFocus() • void transferFocus() • Szülő, állapot • Container getParent() • String toString() • void list()
java.awt.Container osztály Konténer-komponensek közös őse • Jellemzők • LayoutManager layoutMgr • Komponens hozzáadása, kivétele • Component add(Component comp)Component add(Component comp, int index) • void remove(Component comp)void remove(int index)void removeAll()
Gyerekkomponensek • int getComponentCount() • Component[] getComponents() • Component getComponent(int n) • Component getComponentAt(int x, int y)Component getComponentAt(Point p) • boolean isAncestorOf(Component comp) • Elrendezés • Dimension getMaximumSize() • Dimension getMinimumSize() • Dimension getPreferredSize()
java.awt.Window osztály • Összes AWT és Swing ablak komponens közös őse • Utódai: Frame, JFrame, Dialog, JDialog, JWindow • Metódusok • void pack() • void show()boolean isShowing()void hide() • void setLocationRelativeTo(Component c) • void toBack()void toFront() • void dispose()
Metódusok (folyt.) • void addWindowListener(WindowListener l) • void removeWindowListener(WindowListener l) • Component getFocusOwner() • Window getOwner() • Window[] getOwnedWindows() • Aktív ablak Az operációs rendszerben pontosan egy alkalmazás aktív, egy alkalmazásban pedig pontosan egy ablak aktív.
JFrame osztály • Közvetlen ős: java.awt.Frame • A Swing egyetlen natív komponense • Keret: legfelső szintű ablak, nincs tulajdonosa • Van szegélye, ikonja, címe és menüsora • Komponenseit a tartalompanelbe (content pane) kell tenni
Jellemzők • String title • Image iconImage • MenuBar menuBar • boolean resizable • int state • Metódusok • Container getContentPane() • setDefaultCloseOperation(int operation) • static Frame[] getFrames()
6. Elrendezésmenedzserek 1. Az elrendezésmenedzserek tulajdonságai 2. FlowLayout – sorfolytonos elrendezés 3. GridLayout – rácsos elrendezés 4. BorderLayout – határmenti elrendezés 5. JPanel, az összefogó konténer II. Grafikus felhasználói interfész
konténer komponens1 komponens2 konténer :Container layoutManager :LayoutManager komponens3 komponens2 komponens1 komponens3 Elrendezésmenedzserek • Minden konténernek van elrendezésmenedzsere • Az ablak pack utasítására automatikusan elrendezi a konténer komponenseit, azok helyzetét és méretét • Előredefiniált elrendezésmenedzserek: FlowLayout, GridLayout, BorderLayout, CardLayout, GridBagLayout
LayoutManager interfész Minden elrendezésmenedzsernek implementálnia kell aLayoutManager interfészt. Container osztály idetartozó metódusai • Component add(Component comp)Component add(Component comp, int index) • void add(Component comp, Object constraints)void add(Component comp, Object constraints, int index) • LayoutManager getLayout()void setLayout(LayoutManager mgr) • void validate()
FlowLayout – sorfolytonos elrendezés • Sorfolytonos elhelyezés balról jobbra • Elemek mérete: előnyös méret (preferredSize) alapján, az ablak átméretezésekor nem változik • Sorok igazítása(align): balra, jobbra, középre • Komponensek közötti konstans távolság vízszintesen(hgap) és függőlegesen(vgap) • JPanel és Applet alapértelmezett elrendezés-menedzsere
vgap=5 hgap=5 • Feladat – FlowLayoutTest • Tegyünk az alkalmazás 700*100-as méretű keretébe 10 szövegmező (JTextField) és nyomógomb (JButton) párost, a sorokat középre igazítva! A szövegmezők 5 oszlopnyi helyet foglaljanak; a gombokon a ”Gomb” felirat és a gomb sorszáma szerepeljen! • A futó programban interaktív módon méretezzük át a keretet, és közben figyeljük meg, hogyan változik az elemek elrendezése!
public class FlowLayoutTest extends JFrame { private Container cp = getContentPane(); public FlowLayoutTest() { setDefaultCloseOperation(EXIT_ON_CLOSE); setTitle("FlowLayout"); LayoutManager lm = new FlowLayout(); cp.setLayout(lm); for (int i=1; i<=10; i++) { cp.add(new JTextField(5)); cp.add(new JButton("Gomb "+i)); } setSize(700,150); show(); } ... }
GridLayout – rácsos elrendezés • Megadott sor és oszlopszámú rácson való elhelyezés • Rács cellái: egyenlő méretű téglalapok, minden komponens egy téglalapot foglal el (nincs lyuk!) • Elemek mérete: cellaméret, az ablak átméretezése-kor változik • Komponensek közötti konstans távolság vízszintesen(hgap) és függőlegesen(vgap)
vgap=10 hgap=20 • Feladat – GridLayoutTest • Tegyünk az alkalmazás keretére képzeletben egy 6*2-es rácsot, és tegyünk az első 10 rácshelyre egy-egy sorszámozott nyomógombot! A komponensek közötti vízszintes távolság legyen 20 pont, a függőleges távolság pedig legyen 10 pont! A futó programban interaktív módon méretezzük át a keretet!
public class GridLayoutTest extends JFrame { public GridLayoutTest() { setDefaultCloseOperation(EXIT_ON_CLOSE); setTitle("GridLayout"); getContentPane().setLayout(new GridLayout(6,2,20,10)); for (int i=1; i<=10; i++) { getContentPane().add(new JButton("Gomb "+i)); } pack(); show(); } public static void main (String args[]) { new GridLayoutTest(); } }
BorderLayout – határ menti elrendezés • 4+1 égtájon való elhelyezés: North (Észak), South (Dél), West (Nyugat), East (Kelet), Center (Közép) • Azonos égtájon levő elemek takarják egymást • Elemek mérete az ablak átméretezésekor változik • Komponensek közötti konstans távolság vízszintesen(hgap) és függőlegesen(vgap) • Window és leszármazottainak (JFrame, JDialog), JFrame tartalompaneljének elrendezésmenedzsere
Feladat – BorderLayoutTest • Tegyünk a 400*200-as méretű keretbe 5 darab nyomó-gombot a képen látható módon! A vízszintes köz 2, függőleges köz 1 legyen! A futó programban interaktív módon méretezzük át a keretet!
class BorderLayoutTest extends JFrame { Container cp = getContentPane(); public BorderLayoutTest() { setDefaultCloseOperation(EXIT_ON_CLOSE); setTitle("BorderLayout"); cp.setLayout(new BorderLayout(2,1)); cp.add(new JButton("North - Észak - Felső"),"North"); cp.add(new JButton("South - Dél"),"South"); cp.add(new JButton("West - Nyugat - Bal"),"West"); cp.add(new JButton("East - Kelet - Jobb"),"East"); cp.add(new JButton("Center - Középső"),"Center"); setSize(400,200); show(); } … }
JPanel, az összefogó konténer • Konténer, mely összefogja a benne levő elemeket • Láthatatlan, vagy látható (szín, keret) • Alapértelmezésben dupla pufferelésű • Saját elrendezésmenedzsere van, alapértelmezésben FlowLayout
szemelyPanel (kitölti a keretet) pnNev pnSzulev pnGomb • Feladat – Személy bevitel • Készítsük el az ábrán látható keretet! A Név beviteli mező 20 oszlopos, a Születési év mező 6 oszlopos legyen! A két címkézett beviteli mező, és a gombok egy-egy sort alkossanak; a sorok egymás alatt jelenjenek meg!
:SzemelyBevitel contentPane:JPanel :SzemelyPanel :GridLayout pnNev: JPanel pnGomb: JPanel pnSzulev: JPanel :FlowLayout :FlowLayout :FlowLayout :JLabel tfSzulev :JTextField btOk :JButton btCancel :JButton tfNev :JTextField :JLabel Tulajdonosi hierarchia
7. Eseményvezérelt programozás 1. Mintaprogram 2. Eseményosztályok 3. Alacsony és magas szintű események 4. Eseménydelegációs modell 5. A felhasználói felület tervezése 6. Eseményadapterek II. Grafikus felhasználói interfész