950 likes | 1.1k Views
Fejlett Programoz ási Technikák 2. 15 / 6. Közhírré tétetik. Március 10.-én 14.00-tól TIK I. Előadó MS RoadShow ASP.NET XML Web Szolgáltatások … Ingyenes részvétel Regisztrálni célszerű a: http://www.microsoft.com/hun/msdneloadas/reg.aspx. Az előző előadás tartalma:. CVS
E N D
Közhírré tétetik • Március 10.-én • 14.00-tól TIK I. Előadó • MS RoadShow • ASP.NET • XML Web Szolgáltatások • … • Ingyenes részvétel • Regisztrálni célszerű a: • http://www.microsoft.com/hun/msdneloadas/reg.aspx
Az előző előadás tartalma: • CVS • Miért van rá szükségünk? • Használata • Címkézés • Ágak kezelése • JUnit • Tesztelés • TestCase • TestSuit • Log4J • Miért nem println()? • Log • Log4J • Ant
Források • Core Java 2 • http://www.mindview.net/Books/TIJ/
A mai előadás tartalma: • JFC és Swing • Múlt • Felépítés • Java Bean • Felső szintű konténerek • Középső szintű konténerek • Elemek • Eseménykezelés • Rajzolás
JFC (Java Foundation Classes) • olyan alkalmazások csoportja melyek segítségével GUI-t készíthetünk. • 1997-ben a JavaOne konferencián mutatták be • A következő csoportokra osztható: • Swing komponenesek (nyomógomb, …) • Beépíthető látvány támogatás (Java, Windows, …) • Hozzáférést támogató API-k vakok részére • Java 2D API (jó minőségű 2D képek készítése) • Drag and Drop támogatás
Java Swing • Nem tartalmaz natív kódot (az AWT tartalmaz) ezért teljesen platform független • A Swing komponensek megjelenítését megadhatjuk (az AWT az aktuális platform megjelenítését használja) • Az objektumok nevei J betűvel kezdődnek • javax.swing.*; java.awt.*; java.awt.event.*;
Java Beans • Visual Programming • VB • Delphi • Java • Az elemeket testre szeretnénk szabni: • szín • események … • Reflexió segítségével deríti ki tulajdnoságokat
Bean • Egyszerű osztály bizonyos elnevezési konvenciókkal • xxx tulajdonság • getXxx • setXxx • isXxx • addListener() • removeListener()
public boolean isJumper() { return jmpr; } public void setJumper(boolean j) { jmpr = j; } public void addActionListener(ActionListener l) { //... } public void removeActionListener(ActionListener l) { // ... } public void addKeyListener(KeyListener l) { // ... } public void removeKeyListener(KeyListener l) { // ... } // An "ordinary" public method: public void croak() { System.out.println("Ribbet!"); } } ///:~ package frogbean; import java.awt.*; import java.awt.event.*; class Spots {} public class Frog { private int jumps; private Color color; private Spots spots; private boolean jmpr; public int getJumps() { return jumps; } public void setJumps(int newJumps) { jumps = newJumps; } public Color getColor() { return color; } public void setColor(Color newColor) { color = newColor; } public Spots getSpots() { return spots; } public void setSpots(Spots newSpots) { spots = newSpots; }
Java Bean • A forráskód nélkül kell a fejlesztő környezetnek megtudnia a használható metódusokat • Használhatnánk a Reflexió-t is • Inspector osztály • BeanInfo static getBeanInfo( )
print("Public methods:"); MethodDescriptor[] methods = bi.getMethodDescriptors(); for(int i = 0; i < methods.length; i++) print(methods[i].getMethod().toString()); print("======================"); print("Event support:"); EventSetDescriptor[] events = bi.getEventSetDescriptors(); for(int i = 0; i < events.length; i++) { print("Listener type:\n " + events[i].getListenerType().getName()); Method[] lm = events[i].getListenerMethods(); for(int j = 0; j < lm.length; j++) print("Listener method:\n " + lm[j].getName()); MethodDescriptor[] lmd = events[i].getListenerMethodDescriptors(); for(int j = 0; j < lmd.length; j++) print("Method descriptor:\n " + lmd[j].getMethod()); Method addListener= events[i].getAddListenerMethod(); print("Add Listener Method:\n " + addListener); Method removeListener = events[i].getRemoveListenerMethod(); print("Remove Listener Method:\n "+ removeListener); print("===================="); } } public void dump(Class bean) { results.setText(""); BeanInfo bi = null; try { bi = Introspector.getBeanInfo(bean, Object.class); } catch(IntrospectionException e) { print("Couldn't introspect " + bean.getName()); return; } PropertyDescriptor[] properties = bi.getPropertyDescriptors(); for(int i = 0; i < properties.length; i++) { Class p = properties[i].getPropertyType(); if(p == null) continue; print("Property type:\n " + p.getName() + "Property name:\n " + properties[i].getName()); Method readMethod = properties[i].getReadMethod(); if(readMethod != null) print("Read method:\n " + readMethod); Method writeMethod = properties[i].getWriteMethod(); if(writeMethod != null) print("Write method:\n " + writeMethod); print("===================="); }
Csomagolás • Manifest fájl: Manifest-Version: 1.0 Name: bangbean/BangBean.class Java-Bean: True • jar cfm BangBean.jar BangBean.mf bangbean
A GUI felépítése • Felső szintű konténerek • helyet biztosítanak a többi komponens számára (JFrame, JDialog, JApplet) • tartalmaznak egy content_pane nevű konténert mely közvetlenül vagy közvetve tartalmaz minden elemet a menüt kivéve • közvetlenül tartalmazhatja a menü elemet • Középső szintű általános, speciális konténerek • egyszerűbbé teszik az egyes elemek pozicionálását • minden elem a menüt kivéve itt helyezkedik el • az add() metódust használhatjuk az egyes elemek felhelyezésére • Elemi komponensek
Megjelenítés(Layout management ) I. • megállapítja az egyes komponensek helyét és méretét • öt különböző menedzsert használhatunk: • BorderLayout • BoxLayout • FlowLayout • GridBagLayout • GridLayout • amikor az add() metódust használjuk figyelembe kell vennünk az egyes megjelenítések igényeit is (relatív pozíció) • bármikor megválltoztatható JPanel pane = new JPanel(); pane.setLayout(new BorderLayout()); • nem kötelező használni (pane.setLayout(NULL)), ekkor minden komponensnek meg kell adnunk a méretét és a helyét, hátránya, hogy nem alkalmazkodik a felső szintű konténre átméretezésekor, nem alkalmazkodik a különböző rendszerekhez, fontméretkehez
Megjelenítés(Layout management ) II. • megadhatjuk a komponens minimum, alapértelmezett, maximális méretét (setMinimumSize, setPreferredSize, setMaximumSize ) • megadhatjuk a rendezést is (setAlignmentX , setAlignmentY ) • a komponensek közötti hely az alábbiaktól függ: • Layout manager • Láthatatlan komponensek • Üres keretek
A méret megállapítása • JFrame esetén: • miután a GUI össze lett rakva a JFrame pack() metódusát meghívjuk, mely megpróbálja kideríteni a keret méretét • a keret megjelenítés menedzselője hozzáadja a keret méretéhez a keret által közvetlenül tartalmazott elemek méretét (content pane, menu bar) • a content pane mérete a megjelenítés menedzserétől függ GridLayout esetén például megpróbál minden elemet egyforma méretűre venni (a legnagyobb méretet veszi fel) • megkérdezi az általa tartalmazott elemek az alapértelmezett méreteit
Esemény kezelés • event source • event listener • minden eseménytípusra külön osztály használandó: • ActionListener • WindowListener • MouseListener • MouseMotionListener • ComponentListener • FocusListener • ListSelectionListener • az események objektumként jelennek meg, melyek sok hasznos tulajdonsággal rendelkeznek (esemény forrása, információ az eseményről …) • egy esemény forráshoz több esemény kezelő csatlakozhat • az esemény kezelésért egy szál a felelős (event-dispatching thread ). Az események kezelése egymás után történik !
Esemény kezelés megvalósítása • a megfelelő interfészt meg kell valósítanipublic class MyClass implements ActionListener { • regisztrálni kell a megfelelő esemény forrásnál esemény kezelőnketsomeComponent.addActionListener(instanceOfMyClass); • meg kell valósítani az interfésztpublic void actionPerformed(ActionEvent e) { ...//code that reacts to the action... } • általában névtelen belső osztályt használunk erre a célrabutton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { numClicks++; label.setText(labelPrefix + numClicks);} } ); • célszerű gyors kezelőket írni, vagy ha ez nem oldható meg akkor új szálat indítani !
Rajzolás • szintén az event-dispatching szálban van • amikor a Swing GUI-t újra kell rajzolni akkor a legfelső komponenst rajzolja újra és halad lefelé a hierarchiában • az egyes komponensek automatikusan újrarajzolják, méretezik magukat revalidate(), repaint() • a gördülékeny működés érdekében a Swing az ún. double-buffered technológiát alkalmazza. Előbb a bufferbe összerakja a GUI-t és utána innen másolja ki a képernyőre • gyorsíthatjuk a rajzolást ha az egyes elemekre beállítjuk az opaque tulajdonságot (setOpaque(true) ). Ilyenkor az alatta lévő objektumokat nem rajzolja ki.
Rajzolási sorrend: Gyermek objektum Speciális grafika Keret Háttér
Swing áttekintés Felirat import javax.swing.*; import java.awt.*; import java.awt.event.*; public class SwingApplication { private static String labelPrefix = ”Kattintások száma: "; private int numClicks = 0; public Component createComponents() { final JLabel label = new JLabel(labelPrefix + "0 "); JButton button = new JButton("I'm a Swing button!"); button.setMnemonic(KeyEvent.VK_I); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { numClicks++; label.setText(labelPrefix + numClicks);}}); label.setLabelFor(button); JPanel pane = new JPanel(); pane.setBorder(BorderFactory.createEmptyBorder(30,30,10,30)); pane.setLayout(new GridLayout(0, 1)); pane.add(button); pane.add(label); return pane; } public static void main(String[] args) { try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { } JFrame frame = new JFrame("SwingApplication"); SwingApplication app = new SwingApplication(); Component contents = app.createComponents(); frame.getContentPane().add(contents, BorderLayout.CENTER); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);}}); frame.pack(); frame.setVisible(true); } } Gomb Eseménykezelő Alsó Konténer Megjelenés Felső Konténer Eseménykezelő
Eseménykezelők I. • EventObject • Object getSource() • Események: • alacsony szintű (ablak, alacsony szintű bevitel) • egér • ablak • billentyű . . . • szemantikus (elemenként különböző lehet pl szöveg mező, gomb) • akció (action) • elem (item) • lista kiválasztás (list selection) • Ajánlatos szemantikus eseményeket használni
Esemény kezelők II. • Interfész megvalósítás vs. öröklés • érdemesebb az öröklést választani anonym osztályként (mivel ilyenkor nem kell a sok üres metódust megvalósítani) • Általános eseménykezelők: • component listener • focus listener • key listener • mouse events • mouse-motion events
component listener • Az egyes komponensek megváltozásakor hívódik meg • Az interfész: • void componentHidden(ComponentEvent) • void componentMoved(ComponentEvent) • void componentResized(ComponentEvent) • void componentShown(ComponentEvent) • Component getComponent() • addComponentListener(this)
focus listener • A FocusListener interfész: • void focusGained(FocusEvent) • void focusLost(FocusEvent) • FocusEvent objektum • boolean isTemporary()
key listener I. • két esemény: • unicode karakter (key-typed) • egy billentyű lenyomása (key-pressed) • KeyListener interfész: • void keyTyped(KeyEvent) • void keyPressed(KeyEvent) • void keyReleased(KeyEvent)
key listener II. • KeyEvent objektum: • int getKeyCode() • void setKeyCode(int) • void setModifiers(int) • String getKeyText() • String getKeyModifiersText() • Component getComponent() • boolean isAltDown() • boolean isControlDown() • boolean isMetaDown() • boolean isShiftDown() • int getModifiers()
mouse events • MouseListener interfész: • void mouseClicked(MouseEvent) • void mouseEntered(MouseEvent) • void mouseExited(MouseEvent) • void mousePressed(MouseEvent) • void mouseReleased(MouseEvent) • MouseEvent objektum: • int getClickCount() • int getX() • int getY() • Point getPoint() • boolean isPopupTrigger()
mouse-motion events • MouseMotionListener interfész: • void mouseDragged(MouseEvent) • void mouseMoved(MouseEvent)
Swing komponensek I. • Felső szintű tárolók • Applet • Dialog • Frame • Általános célú tárolók • Panel • Scroll pane • Split pane • Tabbed pane • Tool bar
Swing komponensek II. • Speciális célú tárolók: • Belső keret (Internal Frame) • Réteges tábla (Layered pane) • Gyökér tábla (Root pane)
Swing komponensek III. • Egyszerű vezérlők: • Gombok • Legördülő lista • Lista • Menü • Csúszka (Slider) • Szöveg mező
Swing komponensek IV. • információ közlő elemek (nem írható): • Felirat (Label) • Progress bar • Tool tip
Swing komponenesek V. • információ közlő elemek (írható): • Szín választó • Fájl választó • Táblázat • Szöveg • Fa
Felső szintű tárolók használata I. • három általánosan használható felső szintű tároló van. • a képernyőn való megjelenéshez szükség van egy konténer hierarchiára melynek gyökere egy felső szintű konténer • egy alkalmazásban több konténer szerkezete is lehet (egy főablak két dialógus ablakkal) • minden felső szintű vezérlő tartalmaz egy content pane-t • tartalmazhatnak menüt is • getContentPane() - Container objektumot ad vissza nem JComponent objektumot. • ha ki akarjuk használni a JComponent osztály lehetőségeit akkor át kell alakítanunk (cast) vagy egy saját objektumot kell létrehoznunk • minden felső szintű tároló rendelkezik egy gyökér lappal is melyet csak speciális esetekben kell használnunk • JInternal Frame ugyan hasnoló de nem felső szintű
Felső szintű tárolók használata II. • új objektummal: JPanel contentPane = new JPanel(); contentPane.setLayout(new BorderLayout()); contentPane.setBorder(someBorder); contentPane.add(someComponent, BorderLayout.CENTER); contentPane.add(anotherComponent, BorderLayout.SOUTH); topLevelContainer.setContentPane(contentPane); • átakalkítva: JComponent x = (JComponent) frame.getContentPane(); x.setLayout(new BorderLayout()); x.setBorder(someBorder); x.add(someComponent, BorderLayout.CENTER); x.add(anotherComponent, BorderLayout.SOUTH);
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TopLevelDemo { public static void main(String s[]) { JFrame frame = new JFrame("TopLevelDemo"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); JLabel yellowLabel = new JLabel(""); yellowLabel.setOpaque(true); yellowLabel.setBackground(Color.yellow); yellowLabel.setPreferredSize(new Dimension(200, 180)); JMenuBar cyanMenuBar = new JMenuBar(); cyanMenuBar.setOpaque(true); cyanMenuBar.setBackground(Color.cyan); cyanMenuBar.setPreferredSize(new Dimension(200, 20)); frame.setJMenuBar(cyanMenuBar); frame.getContentPane().add(yellowLabel, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } }
Keretek (frames) • a JFrame osztály példányaként valósítható meg • megjelenítése platformfüggő • JFrame(”név") • getContentPane() • pack() • setVisible()
Dialógus ablakok I. • korlátozottabb képességekkel bírnak mint a keretek • minden dialógus egy keretből származik • amikor a keretet bezárjuk bezáródnak a hozzá tartozó dialógus ablakok is • lehet modális (ekkor csak ő fogadja az inputot) • saját dialógus ablakot a JDialog osztály segítségével tudunk létrehozni • létrehoz egy gyökér hátlapot • támogatja az ablak bezárást • hasonló funkciói vannak mint a JFrame-nak
Dialógus ablakok II. • egyszerű dialógusablakot a JOptionPane osztályból célszerű példányosítaniJOptionPane.showMessageDialog(frame, "Egy minta dialógus ablak"); • az alábbi típusokat használhatjuk: • alapértelmezett • figyelmeztetés (JOptionPane.WARNING_MESSAGE ) • kérdés (JOptionPane.QUESTION_MESSAGE ) • hiba (JOptionPane.ERROR_MESSAGE ) • ikon nélküli (JOptionPane.PLAIN_MESSAGE ) • saját ikon (JOptionPane.INFORMATION_MESSAGE, icon ) • a kérdés beállítása: • DEFAULT_OPTION • YES_NO_OPTION, • YES_NO_CANCEL_OPTION • OK_CANCEL_OPTION.
Dialógus ablak III. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class teszt { public static void main(String s[]) { JFrame frame = new JFrame("TopLevelDemo"); Object[] options = {”Igen", "Nem", "Nem ha mondom!"}; int n = JOptionPane.showOptionDialog(frame, ”Szerinted ez működni fog" + ”minden további nélkül?", ”Jó kérdés", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]); System.exit(0); };}
Appletek • JApplet • a java.applet.Applet osztályból származik • hasonlóan kezelhető mint a keret
JComponent osztály • őse az AWT csomag Container osztálya • a felső szintű tárolókat kivéve minden objektum belőle származik • szolgáltatásai: • eszköz tippek (Tool Tips) • keretek (borders) • billentyűzet események kezelése • alkalmazásfüggő megjelenítés • tulajdonságok kezelése (név érték párként , putClientProperty ) • megjelenítés definiálása (setMaximumSize, …) • speciális hozzáférés támogatása (brail) • dupla tároló (double buffer)
Közbülső tárolók • arra szolgálnak, hogy más elemeket tartalmazzanak • a következő típusai vannak: • Panel – A legflexibilisebb. Gyakran használják közbülső tárolóként, a JPanel osztály írja le. Az elemek csoportosítására is gyakran használatos. • Scroll Pane – görgetősávokat biztosít • Split Pane – két részre osztja a területet • Tabbed Pane – több komponenst is tartalmazhat de csak egy látható • Tool Bar – egy elemcsoportot tartalmaz oszlopba, vagy sorba rendezve melyet a felhasználó áthelyezhet
Hátrészek (Panel) I. • általános célú tároló az egyszerű komponensek számára • alapértelmezésként csak a saját hátterét rajzolja meg • egy speciális függvény felülírásával rajzolhatunk is (paintComponent()) public void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(image, 0, 0, this); g.drawImage(image, 90, 0, 300, 62, this); }
Hátrészek (Panel) II. • beállíthatjuk az elrendezést JPanel aPanel = new JPanel(); aPanel.setLayout(new BorderLayout()); JPanel aPanel = new JPanel(new BorderLayout()); • komponenseket adhatunk hozzá: aFlowPanel.add(aComponent); aFlowPanel.add(anotherComponent); • amikor BorderLayout elrendezést használunk akkor specifikálni kell az elem helyét aBorderPanel.add(aComponent, BorderLayout.CENTER); aBorderPanel.add(anotherComponent, BorderLayout.SOUTH);